Merge "Add a flag to enable/disable SupervisionService based on whether the device is being managed by the supervision role holder." into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 26fbd27..497619a 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -348,6 +348,7 @@
aconfig_declarations {
name: "android.security.flags-aconfig",
package: "android.security",
+ exportable: true,
container: "system",
srcs: ["core/java/android/security/*.aconfig"],
}
@@ -365,6 +366,13 @@
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+java_aconfig_library {
+ name: "android.security.flags-aconfig-java-export",
+ aconfig_declarations: "android.security.flags-aconfig",
+ mode: "exported",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
cc_aconfig_library {
name: "android_security_flags_aconfig_c_lib",
aconfig_declarations: "android.security.flags-aconfig",
diff --git a/apex/jobscheduler/framework/aconfig/job.aconfig b/apex/jobscheduler/framework/aconfig/job.aconfig
index 79aef1e..47a85498f 100644
--- a/apex/jobscheduler/framework/aconfig/job.aconfig
+++ b/apex/jobscheduler/framework/aconfig/job.aconfig
@@ -45,3 +45,11 @@
description: "Introduce a new getPendingJobReasons() API which returns reasons why a job may not have executed. Also deprecate the existing getPendingJobReason() API."
bug: "372031023"
}
+
+flag {
+ name: "get_pending_job_reasons_history_api"
+ is_exported: true
+ namespace: "backstage_power"
+ description: "Introduce a new getPendingJobReasonsHistory() API which returns a limited historical view of getPendingJobReasons()."
+ bug: "372031023"
+}
diff --git a/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java b/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java
index 3cfddc6..fb5ef87 100644
--- a/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java
+++ b/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java
@@ -173,6 +173,16 @@
}
@Override
+ @NonNull
+ public int[] getPendingJobReasons(int jobId) {
+ try {
+ return mBinder.getPendingJobReasons(mNamespace, jobId);
+ } catch (RemoteException e) {
+ return new int[] { PENDING_JOB_REASON_UNDEFINED };
+ }
+ }
+
+ @Override
public boolean canRunUserInitiatedJobs() {
try {
return mBinder.canRunUserInitiatedJobs(mContext.getOpPackageName());
diff --git a/apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl b/apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl
index 416a2d8..21051b5 100644
--- a/apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl
+++ b/apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl
@@ -39,6 +39,7 @@
ParceledListSlice<JobInfo> getAllPendingJobsInNamespace(String namespace);
JobInfo getPendingJob(String namespace, int jobId);
int getPendingJobReason(String namespace, int jobId);
+ int[] getPendingJobReasons(String namespace, int jobId);
boolean canRunUserInitiatedJobs(String packageName);
boolean hasRunUserInitiatedJobsPermission(String packageName, int userId);
List<JobInfo> getStartedJobs();
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
index ad54cd39..bfdd15e 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
@@ -16,6 +16,7 @@
package android.app.job;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -238,6 +239,13 @@
* to defer this job.
*/
public static final int PENDING_JOB_REASON_USER = 15;
+ /**
+ * The override deadline has not transpired.
+ *
+ * @see JobInfo.Builder#setOverrideDeadline(long)
+ */
+ @FlaggedApi(Flags.FLAG_GET_PENDING_JOB_REASONS_API)
+ public static final int PENDING_JOB_REASON_CONSTRAINT_DEADLINE = 16;
/** @hide */
@IntDef(prefix = {"PENDING_JOB_REASON_"}, value = {
@@ -259,6 +267,7 @@
PENDING_JOB_REASON_JOB_SCHEDULER_OPTIMIZATION,
PENDING_JOB_REASON_QUOTA,
PENDING_JOB_REASON_USER,
+ PENDING_JOB_REASON_CONSTRAINT_DEADLINE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface PendingJobReason {
@@ -458,6 +467,10 @@
/**
* Returns a reason why the job is pending and not currently executing. If there are multiple
* reasons why a job may be pending, this will only return one of them.
+ *
+ * @apiNote
+ * To know all the potential reasons why the job may be pending,
+ * use {@link #getPendingJobReasons(int)} instead.
*/
@PendingJobReason
public int getPendingJobReason(int jobId) {
@@ -465,6 +478,21 @@
}
/**
+ * Returns potential reasons why the job with the given {@code jobId} may be pending
+ * and not currently executing.
+ *
+ * The returned array will include {@link PendingJobReason reasons} composed of both
+ * explicitly set constraints on the job and implicit constraints imposed by the system.
+ * The results can be used to debug why a given job may not be currently executing.
+ */
+ @FlaggedApi(Flags.FLAG_GET_PENDING_JOB_REASONS_API)
+ @NonNull
+ @PendingJobReason
+ public int[] getPendingJobReasons(int jobId) {
+ return new int[] { PENDING_JOB_REASON_UNDEFINED };
+ }
+
+ /**
* Returns {@code true} if the calling app currently holds the
* {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS} permission, allowing it to run
* user-initiated jobs.
diff --git a/apex/jobscheduler/service/aconfig/device_idle.aconfig b/apex/jobscheduler/service/aconfig/device_idle.aconfig
index c4d0d18..426031f 100644
--- a/apex/jobscheduler/service/aconfig/device_idle.aconfig
+++ b/apex/jobscheduler/service/aconfig/device_idle.aconfig
@@ -17,3 +17,13 @@
description: "Disable wakelocks for background apps while Light Device Idle is active"
bug: "326607666"
}
+
+flag {
+ name: "use_cpu_time_for_temp_allowlist"
+ namespace: "backstage_power"
+ description: "Use CPU time for temporary allowlists"
+ bug: "376561328"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 3e650da..41fd4a2 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -620,8 +620,8 @@
* the network and acquire wakelocks. Times are in milliseconds.
*/
@GuardedBy("this")
- private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
- = new SparseArray<>();
+ @VisibleForTesting
+ final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes = new SparseArray<>();
private NetworkPolicyManagerInternal mNetworkPolicyManagerInternal;
@@ -1941,7 +1941,8 @@
private static final int MSG_REPORT_IDLE_ON_LIGHT = 3;
private static final int MSG_REPORT_IDLE_OFF = 4;
private static final int MSG_REPORT_ACTIVE = 5;
- private static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
+ @VisibleForTesting
+ static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
@VisibleForTesting
static final int MSG_REPORT_STATIONARY_STATUS = 7;
private static final int MSG_FINISH_IDLE_OP = 8;
@@ -2511,6 +2512,11 @@
return SystemClock.elapsedRealtime();
}
+ /** Returns the current elapsed realtime in milliseconds. */
+ long getUptimeMillis() {
+ return SystemClock.uptimeMillis();
+ }
+
LocationManager getLocationManager() {
if (mLocationManager == null) {
mLocationManager = mContext.getSystemService(LocationManager.class);
@@ -3264,7 +3270,8 @@
void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int uid,
long duration, @TempAllowListType int tempAllowListType, boolean sync,
@ReasonCode int reasonCode, @Nullable String reason) {
- final long timeNow = SystemClock.elapsedRealtime();
+ final long timeNow = Flags.useCpuTimeForTempAllowlist() ? mInjector.getUptimeMillis()
+ : mInjector.getElapsedRealtime();
boolean informWhitelistChanged = false;
int appId = UserHandle.getAppId(uid);
synchronized (this) {
@@ -3350,7 +3357,8 @@
}
void checkTempAppWhitelistTimeout(int uid) {
- final long timeNow = SystemClock.elapsedRealtime();
+ final long timeNow = Flags.useCpuTimeForTempAllowlist() ? mInjector.getUptimeMillis()
+ : mInjector.getElapsedRealtime();
final int appId = UserHandle.getAppId(uid);
if (DEBUG) {
Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow);
@@ -5219,6 +5227,17 @@
}
}
+ pw.println(" Flags:");
+ pw.print(" ");
+ pw.print(Flags.FLAG_USE_CPU_TIME_FOR_TEMP_ALLOWLIST);
+ pw.print("=");
+ pw.println(Flags.useCpuTimeForTempAllowlist());
+ pw.print(" ");
+ pw.print(Flags.FLAG_REMOVE_IDLE_LOCATION);
+ pw.print("=");
+ pw.println(Flags.removeIdleLocation());
+ pw.println();
+
synchronized (this) {
mConstants.dump(pw);
@@ -5449,7 +5468,8 @@
pw.println(" Temp whitelist schedule:");
prefix = " ";
}
- final long timeNow = SystemClock.elapsedRealtime();
+ final long timeNow = Flags.useCpuTimeForTempAllowlist() ? mInjector.getUptimeMillis()
+ : mInjector.getElapsedRealtime();
for (int i = 0; i < size; i++) {
pw.print(prefix);
pw.print("UID=");
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 ba8e3e8..8f44698 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -1550,7 +1550,7 @@
mActivePkgStats.add(
jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(),
packageStats);
- mService.resetPendingJobReasonCache(jobStatus);
+ mService.resetPendingJobReasonsCache(jobStatus);
}
if (mService.getPendingJobQueue().remove(jobStatus)) {
mService.mJobPackageTracker.noteNonpending(jobStatus);
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 4c1951a..f569388 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -460,10 +460,10 @@
private final ArraySet<JobStatus> mChangedJobList = new ArraySet<>();
/**
- * Cached pending job reasons. Mapping from UID -> namespace -> job ID -> reason.
+ * Cached pending job reasons. Mapping from UID -> namespace -> job ID -> reasons.
*/
- @GuardedBy("mPendingJobReasonCache") // Use its own lock to avoid blocking JS processing
- private final SparseArrayMap<String, SparseIntArray> mPendingJobReasonCache =
+ @GuardedBy("mPendingJobReasonsCache") // Use its own lock to avoid blocking JS processing
+ private final SparseArrayMap<String, SparseArray<int[]>> mPendingJobReasonsCache =
new SparseArrayMap<>();
/**
@@ -2021,139 +2021,123 @@
}
}
- @JobScheduler.PendingJobReason
- private int getPendingJobReason(int uid, String namespace, int jobId) {
- int reason;
+ @NonNull
+ private int[] getPendingJobReasons(int uid, String namespace, int jobId) {
+ int[] reasons;
// Some apps may attempt to query this frequently, so cache the reason under a separate lock
// so that the rest of JS processing isn't negatively impacted.
- synchronized (mPendingJobReasonCache) {
- SparseIntArray jobIdToReason = mPendingJobReasonCache.get(uid, namespace);
- if (jobIdToReason != null) {
- reason = jobIdToReason.get(jobId, JobScheduler.PENDING_JOB_REASON_UNDEFINED);
- if (reason != JobScheduler.PENDING_JOB_REASON_UNDEFINED) {
- return reason;
+ synchronized (mPendingJobReasonsCache) {
+ SparseArray<int[]> jobIdToReasons = mPendingJobReasonsCache.get(uid, namespace);
+ if (jobIdToReasons != null) {
+ reasons = jobIdToReasons.get(jobId);
+ if (reasons != null) {
+ return reasons;
}
}
}
synchronized (mLock) {
- reason = getPendingJobReasonLocked(uid, namespace, jobId);
+ reasons = getPendingJobReasonsLocked(uid, namespace, jobId);
if (DEBUG) {
- Slog.v(TAG, "getPendingJobReason("
- + uid + "," + namespace + "," + jobId + ")=" + reason);
+ Slog.v(TAG, "getPendingJobReasons("
+ + uid + "," + namespace + "," + jobId + ")=" + Arrays.toString(reasons));
}
}
- synchronized (mPendingJobReasonCache) {
- SparseIntArray jobIdToReason = mPendingJobReasonCache.get(uid, namespace);
- if (jobIdToReason == null) {
- jobIdToReason = new SparseIntArray();
- mPendingJobReasonCache.add(uid, namespace, jobIdToReason);
+ synchronized (mPendingJobReasonsCache) {
+ SparseArray<int[]> jobIdToReasons = mPendingJobReasonsCache.get(uid, namespace);
+ if (jobIdToReasons == null) {
+ jobIdToReasons = new SparseArray<>();
+ mPendingJobReasonsCache.add(uid, namespace, jobIdToReasons);
}
- jobIdToReason.put(jobId, reason);
+ jobIdToReasons.put(jobId, reasons);
}
- return reason;
+ return reasons;
}
@VisibleForTesting
@JobScheduler.PendingJobReason
int getPendingJobReason(JobStatus job) {
- return getPendingJobReason(job.getUid(), job.getNamespace(), job.getJobId());
+ // keep original method to enable unit testing with flags
+ return getPendingJobReasons(job.getUid(), job.getNamespace(), job.getJobId())[0];
}
- @JobScheduler.PendingJobReason
- @GuardedBy("mLock")
- private int getPendingJobReasonLocked(int uid, String namespace, int jobId) {
- // Very similar code to isReadyToBeExecutedLocked.
+ @VisibleForTesting
+ @NonNull
+ int[] getPendingJobReasons(JobStatus job) {
+ return getPendingJobReasons(job.getUid(), job.getNamespace(), job.getJobId());
+ }
- JobStatus job = mJobs.getJobByUidAndJobId(uid, namespace, jobId);
+ @GuardedBy("mLock")
+ @NonNull
+ private int[] getPendingJobReasonsLocked(int uid, String namespace, int jobId) {
+ // Very similar code to isReadyToBeExecutedLocked.
+ final JobStatus job = mJobs.getJobByUidAndJobId(uid, namespace, jobId);
if (job == null) {
// Job doesn't exist.
- return JobScheduler.PENDING_JOB_REASON_INVALID_JOB_ID;
+ return new int[] { JobScheduler.PENDING_JOB_REASON_INVALID_JOB_ID };
}
-
if (isCurrentlyRunningLocked(job)) {
- return JobScheduler.PENDING_JOB_REASON_EXECUTING;
+ return new int[] { JobScheduler.PENDING_JOB_REASON_EXECUTING };
}
+ final String debugPrefix = "getPendingJobReasonsLocked: " + job.toShortString();
final boolean jobReady = job.isReady();
-
if (DEBUG) {
- Slog.v(TAG, "getPendingJobReasonLocked: " + job.toShortString()
- + " ready=" + jobReady);
+ Slog.v(TAG, debugPrefix + " ready=" + jobReady);
}
-
if (!jobReady) {
- return job.getPendingJobReason();
+ return job.getPendingJobReasons();
}
final boolean userStarted = areUsersStartedLocked(job);
-
if (DEBUG) {
- Slog.v(TAG, "getPendingJobReasonLocked: " + job.toShortString()
- + " userStarted=" + userStarted);
+ Slog.v(TAG, debugPrefix + " userStarted=" + userStarted);
}
if (!userStarted) {
- return JobScheduler.PENDING_JOB_REASON_USER;
+ return new int[] { JobScheduler.PENDING_JOB_REASON_USER };
}
final boolean backingUp = mBackingUpUids.get(job.getSourceUid());
if (DEBUG) {
- Slog.v(TAG, "getPendingJobReasonLocked: " + job.toShortString()
- + " backingUp=" + backingUp);
+ Slog.v(TAG, debugPrefix + " backingUp=" + backingUp);
}
-
if (backingUp) {
// TODO: Should we make a special reason for this?
- return JobScheduler.PENDING_JOB_REASON_APP;
+ return new int[] { JobScheduler.PENDING_JOB_REASON_APP };
}
- JobRestriction restriction = checkIfRestricted(job);
+ final JobRestriction restriction = checkIfRestricted(job);
if (DEBUG) {
- Slog.v(TAG, "getPendingJobReasonLocked: " + job.toShortString()
- + " restriction=" + restriction);
+ Slog.v(TAG, debugPrefix + " restriction=" + restriction);
}
if (restriction != null) {
- return restriction.getPendingReason();
+ // Currently this will return _DEVICE_STATE because of thermal reasons.
+ // TODO (b/372031023): does it make sense to move this along with the
+ // pendingJobReasons() call above and also get the pending reasons from
+ // all of the restriction controllers?
+ return new int[] { restriction.getPendingReason() };
}
- // The following can be a little more expensive (especially jobActive, since we need to
- // go through the array of all potentially active jobs), so we are doing them
- // later... but still before checking with the package manager!
+ // The following can be a little more expensive, so we are doing it later,
+ // but still before checking with the package manager!
final boolean jobPending = mPendingJobQueue.contains(job);
-
-
if (DEBUG) {
- Slog.v(TAG, "getPendingJobReasonLocked: " + job.toShortString()
- + " pending=" + jobPending);
+ Slog.v(TAG, debugPrefix + " pending=" + jobPending);
}
-
if (jobPending) {
- // We haven't started the job for some reason. Presumably, there are too many jobs
- // running.
- return JobScheduler.PENDING_JOB_REASON_DEVICE_STATE;
- }
-
- final boolean jobActive = mConcurrencyManager.isJobRunningLocked(job);
-
- if (DEBUG) {
- Slog.v(TAG, "getPendingJobReasonLocked: " + job.toShortString()
- + " active=" + jobActive);
- }
- if (jobActive) {
- return JobScheduler.PENDING_JOB_REASON_UNDEFINED;
+ // We haven't started the job - presumably, there are too many jobs running.
+ return new int[] { JobScheduler.PENDING_JOB_REASON_DEVICE_STATE };
}
// Validate that the defined package+service is still present & viable.
final boolean componentUsable = isComponentUsable(job);
-
if (DEBUG) {
- Slog.v(TAG, "getPendingJobReasonLocked: " + job.toShortString()
- + " componentUsable=" + componentUsable);
+ Slog.v(TAG, debugPrefix + " componentUsable=" + componentUsable);
}
if (!componentUsable) {
- return JobScheduler.PENDING_JOB_REASON_APP;
+ return new int[] { JobScheduler.PENDING_JOB_REASON_APP };
}
- return JobScheduler.PENDING_JOB_REASON_UNDEFINED;
+ return new int[] { JobScheduler.PENDING_JOB_REASON_UNDEFINED };
}
private JobInfo getPendingJob(int uid, @Nullable String namespace, int jobId) {
@@ -2195,15 +2179,16 @@
// The app process will be killed soon. There's no point keeping its jobs in
// the pending queue to try and start them.
if (mPendingJobQueue.remove(job)) {
- synchronized (mPendingJobReasonCache) {
- SparseIntArray jobIdToReason = mPendingJobReasonCache.get(
+ synchronized (mPendingJobReasonsCache) {
+ SparseArray<int[]> jobIdToReason = mPendingJobReasonsCache.get(
job.getUid(), job.getNamespace());
if (jobIdToReason == null) {
- jobIdToReason = new SparseIntArray();
- mPendingJobReasonCache.add(job.getUid(), job.getNamespace(),
+ jobIdToReason = new SparseArray<>();
+ mPendingJobReasonsCache.add(job.getUid(), job.getNamespace(),
jobIdToReason);
}
- jobIdToReason.put(job.getJobId(), JobScheduler.PENDING_JOB_REASON_USER);
+ jobIdToReason.put(job.getJobId(),
+ new int[] { JobScheduler.PENDING_JOB_REASON_USER });
}
}
}
@@ -2229,8 +2214,8 @@
synchronized (mLock) {
mJobs.removeJobsOfUnlistedUsers(umi.getUserIds());
}
- synchronized (mPendingJobReasonCache) {
- mPendingJobReasonCache.clear();
+ synchronized (mPendingJobReasonsCache) {
+ mPendingJobReasonsCache.clear();
}
}
@@ -2875,7 +2860,7 @@
final boolean update = lastJob != null;
mJobs.add(jobStatus);
// Clear potentially cached INVALID_JOB_ID reason.
- resetPendingJobReasonCache(jobStatus);
+ resetPendingJobReasonsCache(jobStatus);
if (mReadyToRock) {
for (int i = 0; i < mControllers.size(); i++) {
StateController controller = mControllers.get(i);
@@ -2897,9 +2882,9 @@
// Deal with any remaining work items in the old job.
jobStatus.stopTrackingJobLocked(incomingJob);
- synchronized (mPendingJobReasonCache) {
- SparseIntArray reasonCache =
- mPendingJobReasonCache.get(jobStatus.getUid(), jobStatus.getNamespace());
+ synchronized (mPendingJobReasonsCache) {
+ SparseArray<int[]> reasonCache =
+ mPendingJobReasonsCache.get(jobStatus.getUid(), jobStatus.getNamespace());
if (reasonCache != null) {
reasonCache.delete(jobStatus.getJobId());
}
@@ -2927,11 +2912,11 @@
return removed;
}
- /** Remove the pending job reason for this job from the cache. */
- void resetPendingJobReasonCache(@NonNull JobStatus jobStatus) {
- synchronized (mPendingJobReasonCache) {
- final SparseIntArray reasons =
- mPendingJobReasonCache.get(jobStatus.getUid(), jobStatus.getNamespace());
+ /** Remove the pending job reasons for this job from the cache. */
+ void resetPendingJobReasonsCache(@NonNull JobStatus jobStatus) {
+ synchronized (mPendingJobReasonsCache) {
+ final SparseArray<int[]> reasons =
+ mPendingJobReasonsCache.get(jobStatus.getUid(), jobStatus.getNamespace());
if (reasons != null) {
reasons.delete(jobStatus.getJobId());
}
@@ -3313,18 +3298,18 @@
public void onControllerStateChanged(@Nullable ArraySet<JobStatus> changedJobs) {
if (changedJobs == null) {
mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
- synchronized (mPendingJobReasonCache) {
- mPendingJobReasonCache.clear();
+ synchronized (mPendingJobReasonsCache) {
+ mPendingJobReasonsCache.clear();
}
} else if (changedJobs.size() > 0) {
synchronized (mLock) {
mChangedJobList.addAll(changedJobs);
}
mHandler.obtainMessage(MSG_CHECK_CHANGED_JOB_LIST).sendToTarget();
- synchronized (mPendingJobReasonCache) {
+ synchronized (mPendingJobReasonsCache) {
for (int i = changedJobs.size() - 1; i >= 0; --i) {
final JobStatus job = changedJobs.valueAt(i);
- resetPendingJobReasonCache(job);
+ resetPendingJobReasonsCache(job);
}
}
}
@@ -3893,23 +3878,21 @@
// Update the pending reason for any jobs that aren't going to be run.
final int numRunnableJobs = runnableJobs.size();
if (numRunnableJobs > 0 && numRunnableJobs != jobsToRun.size()) {
- synchronized (mPendingJobReasonCache) {
+ synchronized (mPendingJobReasonsCache) {
for (int i = 0; i < numRunnableJobs; ++i) {
final JobStatus job = runnableJobs.get(i);
if (jobsToRun.contains(job)) {
- // We're running this job. Skip updating the pending reason.
- continue;
+ continue; // we're running this job - skip updating the pending reason.
}
- SparseIntArray reasons =
- mPendingJobReasonCache.get(job.getUid(), job.getNamespace());
+ SparseArray<int[]> reasons =
+ mPendingJobReasonsCache.get(job.getUid(), job.getNamespace());
if (reasons == null) {
- reasons = new SparseIntArray();
- mPendingJobReasonCache.add(job.getUid(), job.getNamespace(), reasons);
+ reasons = new SparseArray<>();
+ mPendingJobReasonsCache.add(job.getUid(), job.getNamespace(), reasons);
}
- // We're force batching these jobs, so consider it an optimization
- // policy reason.
- reasons.put(job.getJobId(),
- JobScheduler.PENDING_JOB_REASON_JOB_SCHEDULER_OPTIMIZATION);
+ // we're force batching these jobs - note it as optimization.
+ reasons.put(job.getJobId(), new int[]
+ { JobScheduler.PENDING_JOB_REASON_JOB_SCHEDULER_OPTIMIZATION });
}
}
}
@@ -5123,12 +5106,16 @@
@Override
public int getPendingJobReason(String namespace, int jobId) throws RemoteException {
- final int uid = Binder.getCallingUid();
+ return getPendingJobReasons(validateNamespace(namespace), jobId)[0];
+ }
+ @Override
+ public int[] getPendingJobReasons(String namespace, int jobId) throws RemoteException {
+ final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- return JobSchedulerService.this.getPendingJobReason(
- uid, validateNamespace(namespace), jobId);
+ return JobSchedulerService.this.getPendingJobReasons(
+ uid, validateNamespace(namespace), jobId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -5867,6 +5854,9 @@
pw.print(android.app.job.Flags.FLAG_IGNORE_IMPORTANT_WHILE_FOREGROUND,
android.app.job.Flags.ignoreImportantWhileForeground());
pw.println();
+ pw.print(android.app.job.Flags.FLAG_GET_PENDING_JOB_REASONS_API,
+ android.app.job.Flags.getPendingJobReasonsApi());
+ pw.println();
pw.decreaseIndent();
pw.println();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
index 68303e8..a4a3024 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
@@ -439,6 +439,9 @@
case android.app.job.Flags.FLAG_IGNORE_IMPORTANT_WHILE_FOREGROUND:
pw.println(android.app.job.Flags.ignoreImportantWhileForeground());
break;
+ case android.app.job.Flags.FLAG_GET_PENDING_JOB_REASONS_API:
+ pw.println(android.app.job.Flags.getPendingJobReasonsApi());
+ break;
default:
pw.println("Unknown flag: " + flagName);
break;
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 1dc5a71..58579eb 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
@@ -2067,12 +2067,11 @@
}
/**
- * If {@link #isReady()} returns false, this will return a single reason why the job isn't
- * ready. If {@link #isReady()} returns true, this will return
- * {@link JobScheduler#PENDING_JOB_REASON_UNDEFINED}.
+ * This will return all potential reasons why the job is pending.
*/
- @JobScheduler.PendingJobReason
- public int getPendingJobReason() {
+ @NonNull
+ public int[] getPendingJobReasons() {
+ final ArrayList<Integer> reasons = new ArrayList<>();
final int unsatisfiedConstraints = ~satisfiedConstraints
& (requiredConstraints | mDynamicConstraints | IMPLICIT_CONSTRAINTS);
if ((CONSTRAINT_BACKGROUND_NOT_RESTRICTED & unsatisfiedConstraints) != 0) {
@@ -2084,78 +2083,99 @@
// (they'll always get BACKGROUND_RESTRICTION) as the reason, regardless of
// battery saver state.
if (mIsUserBgRestricted) {
- return JobScheduler.PENDING_JOB_REASON_BACKGROUND_RESTRICTION;
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_BACKGROUND_RESTRICTION);
+ } else {
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_DEVICE_STATE);
}
- return JobScheduler.PENDING_JOB_REASON_DEVICE_STATE;
}
+ if ((CONSTRAINT_DEVICE_NOT_DOZING & unsatisfiedConstraints) != 0) {
+ if (!reasons.contains(JobScheduler.PENDING_JOB_REASON_DEVICE_STATE)) {
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_DEVICE_STATE);
+ }
+ }
+
if ((CONSTRAINT_BATTERY_NOT_LOW & unsatisfiedConstraints) != 0) {
if ((CONSTRAINT_BATTERY_NOT_LOW & requiredConstraints) != 0) {
// The developer requested this constraint, so it makes sense to return the
// explicit constraint reason.
- return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_BATTERY_NOT_LOW;
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_CONSTRAINT_BATTERY_NOT_LOW);
+ } else {
+ // Hard-coding right now since the current dynamic constraint sets don't overlap
+ // TODO: return based on active dynamic constraint sets when they start overlapping
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_APP_STANDBY);
}
- // Hard-coding right now since the current dynamic constraint sets don't overlap
- // TODO: return based on active dynamic constraint sets when they start overlapping
- return JobScheduler.PENDING_JOB_REASON_APP_STANDBY;
}
if ((CONSTRAINT_CHARGING & unsatisfiedConstraints) != 0) {
if ((CONSTRAINT_CHARGING & requiredConstraints) != 0) {
// The developer requested this constraint, so it makes sense to return the
// explicit constraint reason.
- return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_CHARGING;
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_CONSTRAINT_CHARGING);
+ } else {
+ // Hard-coding right now since the current dynamic constraint sets don't overlap
+ // TODO: return based on active dynamic constraint sets when they start overlapping
+ if (!reasons.contains(JobScheduler.PENDING_JOB_REASON_APP_STANDBY)) {
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_APP_STANDBY);
+ }
}
- // Hard-coding right now since the current dynamic constraint sets don't overlap
- // TODO: return based on active dynamic constraint sets when they start overlapping
- return JobScheduler.PENDING_JOB_REASON_APP_STANDBY;
- }
- if ((CONSTRAINT_CONNECTIVITY & unsatisfiedConstraints) != 0) {
- return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_CONNECTIVITY;
- }
- if ((CONSTRAINT_CONTENT_TRIGGER & unsatisfiedConstraints) != 0) {
- return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_CONTENT_TRIGGER;
- }
- if ((CONSTRAINT_DEVICE_NOT_DOZING & unsatisfiedConstraints) != 0) {
- return JobScheduler.PENDING_JOB_REASON_DEVICE_STATE;
- }
- if ((CONSTRAINT_FLEXIBLE & unsatisfiedConstraints) != 0) {
- return JobScheduler.PENDING_JOB_REASON_JOB_SCHEDULER_OPTIMIZATION;
}
if ((CONSTRAINT_IDLE & unsatisfiedConstraints) != 0) {
if ((CONSTRAINT_IDLE & requiredConstraints) != 0) {
// The developer requested this constraint, so it makes sense to return the
// explicit constraint reason.
- return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_DEVICE_IDLE;
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_CONSTRAINT_DEVICE_IDLE);
+ } else {
+ // Hard-coding right now since the current dynamic constraint sets don't overlap
+ // TODO: return based on active dynamic constraint sets when they start overlapping
+ if (!reasons.contains(JobScheduler.PENDING_JOB_REASON_APP_STANDBY)) {
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_APP_STANDBY);
+ }
}
- // Hard-coding right now since the current dynamic constraint sets don't overlap
- // TODO: return based on active dynamic constraint sets when they start overlapping
- return JobScheduler.PENDING_JOB_REASON_APP_STANDBY;
+ }
+
+ if ((CONSTRAINT_CONNECTIVITY & unsatisfiedConstraints) != 0) {
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_CONSTRAINT_CONNECTIVITY);
+ }
+ if ((CONSTRAINT_CONTENT_TRIGGER & unsatisfiedConstraints) != 0) {
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_CONSTRAINT_CONTENT_TRIGGER);
+ }
+ if ((CONSTRAINT_FLEXIBLE & unsatisfiedConstraints) != 0) {
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_JOB_SCHEDULER_OPTIMIZATION);
}
if ((CONSTRAINT_PREFETCH & unsatisfiedConstraints) != 0) {
- return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_PREFETCH;
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_CONSTRAINT_PREFETCH);
}
if ((CONSTRAINT_STORAGE_NOT_LOW & unsatisfiedConstraints) != 0) {
- return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_STORAGE_NOT_LOW;
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_CONSTRAINT_STORAGE_NOT_LOW);
}
if ((CONSTRAINT_TIMING_DELAY & unsatisfiedConstraints) != 0) {
- return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_MINIMUM_LATENCY;
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_CONSTRAINT_MINIMUM_LATENCY);
}
if ((CONSTRAINT_WITHIN_QUOTA & unsatisfiedConstraints) != 0) {
- return JobScheduler.PENDING_JOB_REASON_QUOTA;
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_QUOTA);
+ }
+ if (android.app.job.Flags.getPendingJobReasonsApi()) {
+ if ((CONSTRAINT_DEADLINE & unsatisfiedConstraints) != 0) {
+ reasons.addLast(JobScheduler.PENDING_JOB_REASON_CONSTRAINT_DEADLINE);
+ }
}
- if (getEffectiveStandbyBucket() == NEVER_INDEX) {
- Slog.wtf(TAG, "App in NEVER bucket querying pending job reason");
- // The user hasn't officially launched this app.
- return JobScheduler.PENDING_JOB_REASON_USER;
- }
- if (serviceProcessName != null) {
- return JobScheduler.PENDING_JOB_REASON_APP;
+ if (reasons.isEmpty()) {
+ if (getEffectiveStandbyBucket() == NEVER_INDEX) {
+ Slog.wtf(TAG, "App in NEVER bucket querying pending job reason");
+ // The user hasn't officially launched this app.
+ reasons.add(JobScheduler.PENDING_JOB_REASON_USER);
+ } else if (serviceProcessName != null) {
+ reasons.add(JobScheduler.PENDING_JOB_REASON_APP);
+ } else {
+ reasons.add(JobScheduler.PENDING_JOB_REASON_UNDEFINED);
+ }
}
- if (!isReady()) {
- Slog.wtf(TAG, "Unknown reason job isn't ready");
+ final int[] reasonsArr = new int[reasons.size()];
+ for (int i = 0; i < reasonsArr.length; i++) {
+ reasonsArr[i] = reasons.get(i);
}
- return JobScheduler.PENDING_JOB_REASON_UNDEFINED;
+ return reasonsArr;
}
/** @return whether or not the @param constraint is satisfied */
diff --git a/api/Android.bp b/api/Android.bp
index ff674c7..0ac85e2 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -73,6 +73,7 @@
"framework-bluetooth",
"framework-configinfrastructure",
"framework-connectivity",
+ "framework-connectivity-b",
"framework-connectivity-t",
"framework-devicelock",
"framework-graphics",
diff --git a/config/preloaded-classes-denylist b/config/preloaded-classes-denylist
index a413bbd..16f0693 100644
--- a/config/preloaded-classes-denylist
+++ b/config/preloaded-classes-denylist
@@ -1,13 +1,16 @@
android.content.AsyncTaskLoader$LoadTask
+android.media.MediaCodecInfo$CodecCapabilities$FeatureList
android.net.ConnectivityThread$Singleton
android.os.FileObserver
android.os.NullVibrator
+android.permission.PermissionManager
+android.provider.MediaStore
android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
+android.view.HdrRenderState
android.widget.Magnifier
+com.android.internal.jank.InteractionJankMonitor$InstanceHolder
+com.android.internal.util.LatencyTracker$SLatencyTrackerHolder
gov.nist.core.net.DefaultNetworkLayer
-android.net.rtp.AudioGroup
-android.net.rtp.AudioStream
-android.net.rtp.RtpStream
java.util.concurrent.ThreadLocalRandom
java.util.ImmutableCollections
-com.android.internal.jank.InteractionJankMonitor$InstanceHolder
+sun.nio.fs.UnixChannelFactory
diff --git a/core/api/current.txt b/core/api/current.txt
index d9ab273..ead6554 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -241,6 +241,7 @@
field public static final String PROVIDE_REMOTE_CREDENTIALS = "android.permission.PROVIDE_REMOTE_CREDENTIALS";
field @FlaggedApi("android.security.aapm_api") public static final String QUERY_ADVANCED_PROTECTION_MODE = "android.permission.QUERY_ADVANCED_PROTECTION_MODE";
field public static final String QUERY_ALL_PACKAGES = "android.permission.QUERY_ALL_PACKAGES";
+ field @FlaggedApi("android.permission.flags.ranging_permission_enabled") public static final String RANGING = "android.permission.RANGING";
field public static final String READ_ASSISTANT_APP_SEARCH_DATA = "android.permission.READ_ASSISTANT_APP_SEARCH_DATA";
field public static final String READ_BASIC_PHONE_STATE = "android.permission.READ_BASIC_PHONE_STATE";
field public static final String READ_CALENDAR = "android.permission.READ_CALENDAR";
@@ -1074,6 +1075,7 @@
field public static final int layout = 16842994; // 0x10100f2
field public static final int layoutAnimation = 16842988; // 0x10100ec
field public static final int layoutDirection = 16843698; // 0x10103b2
+ field @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") public static final int layoutLabel;
field public static final int layoutMode = 16843738; // 0x10103da
field public static final int layout_above = 16843140; // 0x1010184
field public static final int layout_alignBaseline = 16843142; // 0x1010186
@@ -8023,6 +8025,7 @@
field @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") public static final String CONTENT_PROTECTION_POLICY = "contentProtection";
field public static final String KEYGUARD_DISABLED_FEATURES_POLICY = "keyguardDisabledFeatures";
field public static final String LOCK_TASK_POLICY = "lockTask";
+ field @FlaggedApi("android.app.admin.flags.set_mte_policy_coexistence") public static final String MEMORY_TAGGING_POLICY = "memoryTagging";
field public static final String PACKAGES_SUSPENDED_POLICY = "packagesSuspended";
field public static final String PACKAGE_UNINSTALL_BLOCKED_POLICY = "packageUninstallBlocked";
field public static final String PASSWORD_COMPLEXITY_POLICY = "passwordComplexity";
@@ -9245,6 +9248,7 @@
method @Nullable public String getNamespace();
method @Nullable public abstract android.app.job.JobInfo getPendingJob(int);
method public int getPendingJobReason(int);
+ method @FlaggedApi("android.app.job.get_pending_job_reasons_api") @NonNull public int[] getPendingJobReasons(int);
method @NonNull public java.util.Map<java.lang.String,java.util.List<android.app.job.JobInfo>> getPendingJobsInAllNamespaces();
method public abstract int schedule(@NonNull android.app.job.JobInfo);
field public static final int PENDING_JOB_REASON_APP = 1; // 0x1
@@ -9254,6 +9258,7 @@
field public static final int PENDING_JOB_REASON_CONSTRAINT_CHARGING = 5; // 0x5
field public static final int PENDING_JOB_REASON_CONSTRAINT_CONNECTIVITY = 6; // 0x6
field public static final int PENDING_JOB_REASON_CONSTRAINT_CONTENT_TRIGGER = 7; // 0x7
+ field @FlaggedApi("android.app.job.get_pending_job_reasons_api") public static final int PENDING_JOB_REASON_CONSTRAINT_DEADLINE = 16; // 0x10
field public static final int PENDING_JOB_REASON_CONSTRAINT_DEVICE_IDLE = 8; // 0x8
field public static final int PENDING_JOB_REASON_CONSTRAINT_MINIMUM_LATENCY = 9; // 0x9
field public static final int PENDING_JOB_REASON_CONSTRAINT_PREFETCH = 10; // 0xa
@@ -9687,10 +9692,8 @@
method @Nullable public String getId();
method @Nullable public android.net.Uri getThumbnail();
method @Nullable public CharSequence getTitle();
- method @NonNull public static android.app.wallpaper.WallpaperDescription readFromStream(@NonNull java.io.InputStream) throws java.io.IOException;
method @NonNull public android.app.wallpaper.WallpaperDescription.Builder toBuilder();
method public void writeToParcel(@NonNull android.os.Parcel, int);
- method public void writeToStream(@NonNull java.io.OutputStream) throws java.io.IOException;
field @NonNull public static final android.os.Parcelable.Creator<android.app.wallpaper.WallpaperDescription> CREATOR;
}
@@ -12732,6 +12735,7 @@
method public abstract void onPackagesUnavailable(String[], android.os.UserHandle, boolean);
method public void onPackagesUnsuspended(String[], android.os.UserHandle);
method public void onShortcutsChanged(@NonNull String, @NonNull java.util.List<android.content.pm.ShortcutInfo>, @NonNull android.os.UserHandle);
+ method @FlaggedApi("android.multiuser.add_launcher_user_config") public void onUserConfigChanged(@NonNull android.content.pm.LauncherUserInfo);
}
public static final class LauncherApps.PinItemRequest implements android.os.Parcelable {
@@ -12767,10 +12771,12 @@
@FlaggedApi("android.os.allow_private_profile") public final class LauncherUserInfo implements android.os.Parcelable {
method @FlaggedApi("android.os.allow_private_profile") public int describeContents();
+ method @FlaggedApi("android.multiuser.add_launcher_user_config") @NonNull public android.os.Bundle getUserConfig();
method @FlaggedApi("android.os.allow_private_profile") public int getUserSerialNumber();
method @FlaggedApi("android.os.allow_private_profile") @NonNull public String getUserType();
method @FlaggedApi("android.os.allow_private_profile") public void writeToParcel(@NonNull android.os.Parcel, int);
field @FlaggedApi("android.os.allow_private_profile") @NonNull public static final android.os.Parcelable.Creator<android.content.pm.LauncherUserInfo> CREATOR;
+ field @FlaggedApi("android.multiuser.add_launcher_user_config") public static final String PRIVATE_SPACE_ENTRYPOINT_HIDDEN = "private_space_entrypoint_hidden";
}
public final class ModuleInfo implements android.os.Parcelable {
@@ -13701,7 +13707,7 @@
field public static final int FLAG_STOP_WITH_TASK = 1; // 0x1
field public static final int FLAG_USE_APP_ZYGOTE = 8; // 0x8
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CAMERA}, anyOf={android.Manifest.permission.CAMERA}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CAMERA = 64; // 0x40
- field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE}, anyOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.CHANGE_NETWORK_STATE, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, android.Manifest.permission.NFC, android.Manifest.permission.TRANSMIT_IR, android.Manifest.permission.UWB_RANGING}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 16; // 0x10
+ field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE}, anyOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.CHANGE_NETWORK_STATE, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, android.Manifest.permission.NFC, android.Manifest.permission.TRANSMIT_IR, android.Manifest.permission.UWB_RANGING, android.Manifest.permission.RANGING}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 16; // 0x10
field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_DATA_SYNC, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1; // 0x1
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_HEALTH}, anyOf={android.Manifest.permission.ACTIVITY_RECOGNITION, android.Manifest.permission.BODY_SENSORS, android.Manifest.permission.HIGH_SAMPLING_RATE_SENSORS}) public static final int FOREGROUND_SERVICE_TYPE_HEALTH = 256; // 0x100
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_LOCATION}, anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_LOCATION = 8; // 0x8
@@ -16418,6 +16424,7 @@
field public static final int FLEX_RGBA_8888 = 42; // 0x2a
field public static final int FLEX_RGB_888 = 41; // 0x29
field public static final int HEIC = 1212500294; // 0x48454946
+ field @FlaggedApi("com.android.internal.camera.flags.camera_heif_gainmap") public static final int HEIC_ULTRAHDR = 4102; // 0x1006
field public static final int JPEG = 256; // 0x100
field public static final int JPEG_R = 4101; // 0x1005
field public static final int NV16 = 16; // 0x10
@@ -16844,6 +16851,7 @@
field @FlaggedApi("com.android.text.flags.letter_spacing_justification") public static final int TEXT_RUN_FLAG_LEFT_EDGE = 8192; // 0x2000
field @FlaggedApi("com.android.text.flags.letter_spacing_justification") public static final int TEXT_RUN_FLAG_RIGHT_EDGE = 16384; // 0x4000
field public static final int UNDERLINE_TEXT_FLAG = 8; // 0x8
+ field @FlaggedApi("com.android.text.flags.vertical_text_layout") public static final int VERTICAL_TEXT_FLAG = 4096; // 0x1000
}
public enum Paint.Align {
@@ -18708,6 +18716,7 @@
field public static final int DATASPACE_DISPLAY_P3 = 143261696; // 0x88a0000
field public static final int DATASPACE_DYNAMIC_DEPTH = 4098; // 0x1002
field public static final int DATASPACE_HEIF = 4100; // 0x1004
+ field @FlaggedApi("com.android.internal.camera.flags.camera_heif_gainmap") public static final int DATASPACE_HEIF_ULTRAHDR = 4102; // 0x1006
field public static final int DATASPACE_JFIF = 146931712; // 0x8c20000
field public static final int DATASPACE_JPEG_R = 4101; // 0x1005
field public static final int DATASPACE_SCRGB = 411107328; // 0x18810000
@@ -24660,6 +24669,7 @@
field @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") public static final int SUITABILITY_STATUS_NOT_SUITABLE_FOR_TRANSFER = 2; // 0x2
field @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") public static final int SUITABILITY_STATUS_SUITABLE_FOR_DEFAULT_TRANSFER = 0; // 0x0
field @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") public static final int SUITABILITY_STATUS_SUITABLE_FOR_MANUAL_TRANSFER = 1; // 0x1
+ field @FlaggedApi("com.android.media.flags.enable_new_wired_media_route_2_info_types") public static final int TYPE_AUX_LINE = 19; // 0x13
field public static final int TYPE_BLE_HEADSET = 26; // 0x1a
field public static final int TYPE_BLUETOOTH_A2DP = 8; // 0x8
field public static final int TYPE_BUILTIN_SPEAKER = 2; // 0x2
@@ -24669,6 +24679,8 @@
field @FlaggedApi("com.android.media.flags.enable_audio_policies_device_and_bluetooth_controller") public static final int TYPE_HDMI_ARC = 10; // 0xa
field @FlaggedApi("com.android.media.flags.enable_audio_policies_device_and_bluetooth_controller") public static final int TYPE_HDMI_EARC = 29; // 0x1d
field public static final int TYPE_HEARING_AID = 23; // 0x17
+ field @FlaggedApi("com.android.media.flags.enable_new_wired_media_route_2_info_types") public static final int TYPE_LINE_ANALOG = 5; // 0x5
+ field @FlaggedApi("com.android.media.flags.enable_new_wired_media_route_2_info_types") public static final int TYPE_LINE_DIGITAL = 6; // 0x6
field @FlaggedApi("android.media.audio.enable_multichannel_group_device") public static final int TYPE_MULTICHANNEL_SPEAKER_GROUP = 32; // 0x20
field public static final int TYPE_REMOTE_AUDIO_VIDEO_RECEIVER = 1003; // 0x3eb
field @FlaggedApi("com.android.media.flags.enable_new_media_route_2_info_types") public static final int TYPE_REMOTE_CAR = 1008; // 0x3f0
@@ -32944,11 +32956,16 @@
public class Build {
ctor public Build();
+ method @FlaggedApi("android.os.api_for_backported_fixes") public static int getBackportedFixStatus(long);
method @NonNull public static java.util.List<android.os.Build.Partition> getFingerprintedPartitions();
method @FlaggedApi("android.sdk.major_minor_versioning_scheme") public static int getMajorSdkVersion(int);
method @FlaggedApi("android.sdk.major_minor_versioning_scheme") public static int getMinorSdkVersion(int);
method public static String getRadioVersion();
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public static String getSerial();
+ field @FlaggedApi("android.os.api_for_backported_fixes") public static final int BACKPORTED_FIX_STATUS_FIXED = 1; // 0x1
+ field @FlaggedApi("android.os.api_for_backported_fixes") public static final int BACKPORTED_FIX_STATUS_NOT_APPLICABLE = 2; // 0x2
+ field @FlaggedApi("android.os.api_for_backported_fixes") public static final int BACKPORTED_FIX_STATUS_NOT_FIXED = 3; // 0x3
+ field @FlaggedApi("android.os.api_for_backported_fixes") public static final int BACKPORTED_FIX_STATUS_UNKNOWN = 0; // 0x0
field public static final String BOARD;
field public static final String BOOTLOADER;
field public static final String BRAND;
@@ -33965,12 +33982,14 @@
}
public final class PowerManager {
+ method @FlaggedApi("android.os.allow_thermal_thresholds_callback") public void addThermalHeadroomListener(@NonNull android.os.PowerManager.OnThermalHeadroomChangedListener);
+ method @FlaggedApi("android.os.allow_thermal_thresholds_callback") public void addThermalHeadroomListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.PowerManager.OnThermalHeadroomChangedListener);
method public void addThermalStatusListener(@NonNull android.os.PowerManager.OnThermalStatusChangedListener);
method public void addThermalStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.PowerManager.OnThermalStatusChangedListener);
method @Nullable public java.time.Duration getBatteryDischargePrediction();
method public int getCurrentThermalStatus();
method public int getLocationPowerSaveMode();
- method public float getThermalHeadroom(@IntRange(from=0, to=60) int);
+ method @FloatRange(from=0.0f) public float getThermalHeadroom(@IntRange(from=0, to=60) int);
method @FlaggedApi("android.os.allow_thermal_headroom_thresholds") @NonNull public java.util.Map<java.lang.Integer,java.lang.Float> getThermalHeadroomThresholds();
method public boolean isAllowedInLowPowerStandby(int);
method public boolean isAllowedInLowPowerStandby(@NonNull String);
@@ -33988,6 +34007,7 @@
method public boolean isWakeLockLevelSupported(int);
method public android.os.PowerManager.WakeLock newWakeLock(int, String);
method @RequiresPermission(android.Manifest.permission.REBOOT) public void reboot(@Nullable String);
+ method @FlaggedApi("android.os.allow_thermal_thresholds_callback") public void removeThermalHeadroomListener(@NonNull android.os.PowerManager.OnThermalHeadroomChangedListener);
method public void removeThermalStatusListener(@NonNull android.os.PowerManager.OnThermalStatusChangedListener);
field @Deprecated @RequiresPermission(value=android.Manifest.permission.TURN_SCREEN_ON, conditional=true) public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
field public static final String ACTION_DEVICE_IDLE_MODE_CHANGED = "android.os.action.DEVICE_IDLE_MODE_CHANGED";
@@ -34020,6 +34040,10 @@
field public static final int THERMAL_STATUS_SHUTDOWN = 6; // 0x6
}
+ @FlaggedApi("android.os.allow_thermal_thresholds_callback") public static interface PowerManager.OnThermalHeadroomChangedListener {
+ method public void onThermalHeadroomChanged(@FloatRange(from=0.0f) float, @FloatRange(from=0.0f) float, @IntRange(from=0) int, @NonNull java.util.Map<java.lang.Integer,java.lang.Float>);
+ }
+
public static interface PowerManager.OnThermalStatusChangedListener {
method public void onThermalStatusChanged(int);
}
@@ -55387,7 +55411,7 @@
method public CharSequence getHintText();
method public int getInputType();
method public android.view.accessibility.AccessibilityNodeInfo getLabelFor();
- method public android.view.accessibility.AccessibilityNodeInfo getLabeledBy();
+ method @Deprecated @FlaggedApi("android.view.accessibility.support_multiple_labeledby") public android.view.accessibility.AccessibilityNodeInfo getLabeledBy();
method @FlaggedApi("android.view.accessibility.support_multiple_labeledby") @NonNull public java.util.List<android.view.accessibility.AccessibilityNodeInfo> getLabeledByList();
method public int getLiveRegion();
method public int getMaxTextLength();
@@ -55487,8 +55511,8 @@
method public void setInputType(int);
method public void setLabelFor(android.view.View);
method public void setLabelFor(android.view.View, int);
- method public void setLabeledBy(android.view.View);
- method public void setLabeledBy(android.view.View, int);
+ method @Deprecated @FlaggedApi("android.view.accessibility.support_multiple_labeledby") public void setLabeledBy(android.view.View);
+ method @Deprecated @FlaggedApi("android.view.accessibility.support_multiple_labeledby") public void setLabeledBy(android.view.View, int);
method public void setLiveRegion(int);
method public void setLongClickable(boolean);
method public void setMaxTextLength(int);
@@ -55573,6 +55597,7 @@
field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH = "android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH";
field public static final int EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_MAX_LENGTH = 20000; // 0x4e20
field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX = "android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX";
+ field @FlaggedApi("android.view.accessibility.a11y_character_in_window_api") public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_IN_WINDOW_KEY = "android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_IN_WINDOW_KEY";
field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY = "android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_KEY";
field public static final int FLAG_PREFETCH_ANCESTORS = 1; // 0x1
field public static final int FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST = 16; // 0x10
@@ -56975,6 +57000,9 @@
method public String getExtraValueOf(String);
method public int getIconResId();
method @NonNull public String getLanguageTag();
+ method @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") @NonNull public CharSequence getLayoutDisplayName(@NonNull android.content.Context, @NonNull android.content.pm.ApplicationInfo);
+ method @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") @NonNull public CharSequence getLayoutLabelNonLocalized();
+ method @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") @StringRes public int getLayoutLabelResource();
method @Deprecated @NonNull public String getLocale();
method public String getMode();
method @NonNull public CharSequence getNameOverride();
@@ -56994,6 +57022,8 @@
method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAsciiCapable(boolean);
method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAuxiliary(boolean);
method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setLanguageTag(String);
+ method @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") @NonNull public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setLayoutLabelNonLocalized(@NonNull CharSequence);
+ method @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") @NonNull public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setLayoutLabelResource(@StringRes int);
method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setOverridesImplicitlyEnabledSubtype(boolean);
method @NonNull public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setPhysicalKeyboardHint(@Nullable android.icu.util.ULocale, @NonNull String);
method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeExtraValue(String);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 3fde749..a9b181d 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -389,6 +389,7 @@
field public static final String START_CROSS_PROFILE_ACTIVITIES = "android.permission.START_CROSS_PROFILE_ACTIVITIES";
field public static final String START_REVIEW_PERMISSION_DECISIONS = "android.permission.START_REVIEW_PERMISSION_DECISIONS";
field public static final String START_TASKS_FROM_RECENTS = "android.permission.START_TASKS_FROM_RECENTS";
+ field @FlaggedApi("android.os.vibrator.vendor_vibration_effects") public static final String START_VIBRATION_SESSIONS = "android.permission.START_VIBRATION_SESSIONS";
field public static final String STATUS_BAR_SERVICE = "android.permission.STATUS_BAR_SERVICE";
field public static final String STOP_APP_SWITCHES = "android.permission.STOP_APP_SWITCHES";
field public static final String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME";
@@ -696,6 +697,7 @@
field public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
field public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
field public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
+ field @FlaggedApi("android.permission.flags.ranging_permission_enabled") public static final String OPSTR_RANGING = "android:ranging";
field @FlaggedApi("android.view.contentprotection.flags.rapid_clear_notifications_by_listener_app_op_enabled") public static final String OPSTR_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER = "android:rapid_clear_notifications_by_listener";
field public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
field @FlaggedApi("android.permission.flags.replace_body_sensor_permission_enabled") public static final String OPSTR_READ_HEART_RATE = "android:read_heart_rate";
@@ -5293,13 +5295,19 @@
field public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1024; // 0x400
}
+ public abstract static class VirtualDisplay.Callback {
+ method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") public void onRequestedBrightnessChanged(@FloatRange(from=0.0f, to=1.0f) float);
+ }
+
public final class VirtualDisplayConfig implements android.os.Parcelable {
+ method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @FloatRange(from=0.0f, to=1.0f) public float getDefaultBrightness();
method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @Nullable public android.view.DisplayCutout getDisplayCutout();
method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") public boolean isHomeSupported();
method @FlaggedApi("com.android.window.flags.vdm_force_app_universal_resizable_api") public boolean isIgnoreActivitySizeRestrictions();
}
public static final class VirtualDisplayConfig.Builder {
+ method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDefaultBrightness(@FloatRange(from=0.0f, to=1.0f) float);
method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDisplayCutout(@Nullable android.view.DisplayCutout);
method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setHomeSupported(boolean);
method @FlaggedApi("com.android.window.flags.vdm_force_app_universal_resizable_api") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setIgnoreActivitySizeRestrictions(boolean);
@@ -7027,7 +7035,7 @@
method @NonNull public android.hardware.soundtrigger.SoundTrigger.RecognitionConfig.Builder setAllowMultipleTriggers(boolean);
method @NonNull public android.hardware.soundtrigger.SoundTrigger.RecognitionConfig.Builder setAudioCapabilities(int);
method @NonNull public android.hardware.soundtrigger.SoundTrigger.RecognitionConfig.Builder setCaptureRequested(boolean);
- method @NonNull public android.hardware.soundtrigger.SoundTrigger.RecognitionConfig.Builder setData(@Nullable byte[]);
+ method @NonNull public android.hardware.soundtrigger.SoundTrigger.RecognitionConfig.Builder setData(@NonNull byte[]);
method @NonNull public android.hardware.soundtrigger.SoundTrigger.RecognitionConfig.Builder setKeyphrases(@NonNull java.util.Collection<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra>);
}
@@ -11653,8 +11661,11 @@
public abstract class Vibrator {
method @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) public void addVibratorStateListener(@NonNull android.os.Vibrator.OnVibratorStateChangedListener);
method @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) public void addVibratorStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.Vibrator.OnVibratorStateChangedListener);
+ method @FlaggedApi("android.os.vibrator.vendor_vibration_effects") public boolean areVendorEffectsSupported();
+ method @FlaggedApi("android.os.vibrator.vendor_vibration_effects") public boolean areVendorSessionsSupported();
method @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) public boolean isVibrating();
method @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) public void removeVibratorStateListener(@NonNull android.os.Vibrator.OnVibratorStateChangedListener);
+ method @FlaggedApi("android.os.vibrator.vendor_vibration_effects") @RequiresPermission(allOf={android.Manifest.permission.VIBRATE, android.Manifest.permission.VIBRATE_VENDOR_EFFECTS, android.Manifest.permission.START_VIBRATION_SESSIONS}) public void startVendorSession(@NonNull android.os.VibrationAttributes, @Nullable String, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.vibrator.VendorVibrationSession.Callback);
}
public static interface Vibrator.OnVibratorStateChangedListener {
@@ -11806,6 +11817,28 @@
}
+package android.os.vibrator {
+
+ @FlaggedApi("android.os.vibrator.vendor_vibration_effects") public final class VendorVibrationSession implements java.lang.AutoCloseable {
+ method public void cancel();
+ method public void close();
+ method @RequiresPermission(android.Manifest.permission.VIBRATE) public void vibrate(@NonNull android.os.VibrationEffect, @Nullable String);
+ field public static final int STATUS_CANCELED = 4; // 0x4
+ field public static final int STATUS_IGNORED = 2; // 0x2
+ field public static final int STATUS_SUCCESS = 1; // 0x1
+ field public static final int STATUS_UNKNOWN = 0; // 0x0
+ field public static final int STATUS_UNKNOWN_ERROR = 5; // 0x5
+ field public static final int STATUS_UNSUPPORTED = 3; // 0x3
+ }
+
+ public static interface VendorVibrationSession.Callback {
+ method public void onFinished(int);
+ method public void onFinishing();
+ method public void onStarted(@NonNull android.os.vibrator.VendorVibrationSession);
+ }
+
+}
+
package android.os.vibrator.persistence {
@FlaggedApi("android.os.vibrator.vibration_xml_apis") public final class ParsedVibration {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 98d6f58..1173519 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -402,6 +402,7 @@
method @FlaggedApi("android.service.notification.notification_classification") @NonNull public java.util.Set<java.lang.String> getUnsupportedAdjustmentTypes();
method public boolean isNotificationPolicyAccessGrantedForPackage(@NonNull String);
method @FlaggedApi("android.app.modes_api") public boolean removeAutomaticZenRule(@NonNull String, boolean);
+ method @FlaggedApi("android.service.notification.notification_classification") public void setAssistantAdjustmentKeyTypeState(int, boolean);
method @FlaggedApi("android.app.api_rich_ongoing") public void setCanPostPromotedNotifications(@NonNull String, int, boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) public void setNotificationListenerAccessGranted(@NonNull android.content.ComponentName, boolean, boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING) public void setToastRateLimitingEnabled(boolean);
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 9875efe..71623c5 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -206,6 +206,7 @@
"android/os/Temperature.aidl",
"android/os/CoolingDevice.aidl",
"android/os/IThermalEventListener.aidl",
+ "android/os/IThermalHeadroomListener.aidl",
"android/os/IThermalStatusListener.aidl",
"android/os/IThermalService.aidl",
"android/os/IPowerManager.aidl",
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 36fc65a..b447897 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2764,14 +2764,19 @@
/**
* Information of organized child tasks.
*
+ * @deprecated No longer used
* @hide
*/
+ @Deprecated
public ArrayList<RecentTaskInfo> childrenTaskInfos = new ArrayList<>();
/**
* Information about the last snapshot taken for this task.
+ *
+ * @deprecated No longer used
* @hide
*/
+ @Deprecated
public PersistedTaskSnapshotData lastSnapshotData = new PersistedTaskSnapshotData();
public RecentTaskInfo() {
@@ -2793,7 +2798,7 @@
lastSnapshotData.taskSize = source.readTypedObject(Point.CREATOR);
lastSnapshotData.contentInsets = source.readTypedObject(Rect.CREATOR);
lastSnapshotData.bufferSize = source.readTypedObject(Point.CREATOR);
- super.readFromParcel(source);
+ super.readTaskFromParcel(source);
}
@Override
@@ -2804,7 +2809,7 @@
dest.writeTypedObject(lastSnapshotData.taskSize, flags);
dest.writeTypedObject(lastSnapshotData.contentInsets, flags);
dest.writeTypedObject(lastSnapshotData.bufferSize, flags);
- super.writeToParcel(dest, flags);
+ super.writeTaskToParcel(dest, flags);
}
public static final @android.annotation.NonNull Creator<RecentTaskInfo> CREATOR
@@ -2988,13 +2993,13 @@
public void readFromParcel(Parcel source) {
id = source.readInt();
- super.readFromParcel(source);
+ super.readTaskFromParcel(source);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
- super.writeToParcel(dest, flags);
+ super.writeTaskToParcel(dest, flags);
}
public static final @android.annotation.NonNull Creator<RunningTaskInfo> CREATOR = new Creator<RunningTaskInfo>() {
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index 799df1f..16dcf2a 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -534,10 +534,9 @@
dest.writeIntArray(childTaskUserIds);
dest.writeInt(visible ? 1 : 0);
dest.writeInt(position);
- super.writeToParcel(dest, flags);
+ super.writeTaskToParcel(dest, flags);
}
- @Override
void readFromParcel(Parcel source) {
bounds = source.readTypedObject(Rect.CREATOR);
childTaskIds = source.createIntArray();
@@ -546,7 +545,7 @@
childTaskUserIds = source.createIntArray();
visible = source.readInt() > 0;
position = source.readInt();
- super.readFromParcel(source);
+ super.readTaskFromParcel(source);
}
public static final @NonNull Creator<RootTaskInfo> CREATOR = new Creator<>() {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ca98da7..60b8f80 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3100,6 +3100,19 @@
mResourcesManager = ResourcesManager.getInstance();
}
+ /**
+ * Creates and initialize a new system activity thread, to be used for testing. This does not
+ * call {@link #attach}, so it does not modify static state.
+ */
+ @VisibleForTesting
+ @NonNull
+ public static ActivityThread createSystemActivityThreadForTesting() {
+ final var thread = new ActivityThread();
+ thread.mSystemThread = true;
+ initializeSystemThread(thread);
+ return thread;
+ }
+
@UnsupportedAppUsage
public ApplicationThread getApplicationThread()
{
@@ -6806,6 +6819,16 @@
LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths);
resApk.updateApplicationInfo(ai, oldPaths);
}
+ if (android.content.res.Flags.systemContextHandleAppInfoChanged() && mSystemThread) {
+ final var systemContext = getSystemContext();
+ if (systemContext.getPackageName().equals(ai.packageName)) {
+ // The system package is not tracked directly, but still needs to receive updates to
+ // its application info.
+ final ArrayList<String> oldPaths = new ArrayList<>();
+ LoadedApk.makePaths(this, systemContext.getApplicationInfo(), oldPaths);
+ systemContext.mPackageInfo.updateApplicationInfo(ai, oldPaths);
+ }
+ }
ResourcesImpl beforeImpl = getApplication().getResources().getImpl();
@@ -8560,17 +8583,7 @@
// we can't display an alert, we just want to die die die.
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
- try {
- mInstrumentation = new Instrumentation();
- mInstrumentation.basicInit(this);
- ContextImpl context = ContextImpl.createAppContext(
- this, getSystemContext().mPackageInfo);
- mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
- mInitialApplication.onCreate();
- } catch (Exception e) {
- throw new RuntimeException(
- "Unable to instantiate Application():" + e.toString(), e);
- }
+ initializeSystemThread(this);
}
ViewRootImpl.ConfigChangedCallback configChangedCallback = (Configuration globalConfig) -> {
@@ -8595,6 +8608,28 @@
ViewRootImpl.addConfigCallback(configChangedCallback);
}
+ /**
+ * Initializes the given system activity thread, setting up its instrumentation and initial
+ * application. This only has an effect if the given thread is a {@link #mSystemThread}.
+ *
+ * @param thread the given system activity thread to initialize.
+ */
+ private static void initializeSystemThread(@NonNull ActivityThread thread) {
+ if (!thread.mSystemThread) {
+ return;
+ }
+ try {
+ thread.mInstrumentation = new Instrumentation();
+ thread.mInstrumentation.basicInit(thread);
+ ContextImpl context = ContextImpl.createAppContext(
+ thread, thread.getSystemContext().mPackageInfo);
+ thread.mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
+ thread.mInitialApplication.onCreate();
+ } catch (Exception e) {
+ throw new RuntimeException("Unable to instantiate Application():" + e, e);
+ }
+ }
+
@UnsupportedAppUsage
public static ActivityThread systemMain() {
ThreadedRenderer.initForSystemProcess();
diff --git a/core/java/android/app/AppCompatCallbacks.java b/core/java/android/app/AppCompatCallbacks.java
index 4bfa3b3..cf01f50 100644
--- a/core/java/android/app/AppCompatCallbacks.java
+++ b/core/java/android/app/AppCompatCallbacks.java
@@ -28,6 +28,7 @@
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class AppCompatCallbacks implements Compatibility.BehaviorChangeDelegate {
private final long[] mDisabledChanges;
private final long[] mLoggableChanges;
diff --git a/core/java/android/app/AppCompatTaskInfo.java b/core/java/android/app/AppCompatTaskInfo.java
index 8370c2e..009cd72 100644
--- a/core/java/android/app/AppCompatTaskInfo.java
+++ b/core/java/android/app/AppCompatTaskInfo.java
@@ -101,7 +101,6 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {
FLAG_UNDEFINED,
- FLAG_BASE,
FLAG_LETTERBOX_EDU_ENABLED,
FLAG_ELIGIBLE_FOR_LETTERBOX_EDU,
FLAG_LETTERBOXED,
@@ -115,6 +114,10 @@
})
public @interface TopActivityFlag {}
+ /**
+ * A combination of {@link TopActivityFlag}s that have been enabled through
+ * {@link #setTopActivityFlag}.
+ */
@TopActivityFlag
private int mTopActivityFlags;
@@ -167,10 +170,11 @@
}
/**
- * @return {@code true} if top activity is pillarboxed.
+ * @return {@code true} if the top activity bounds are letterboxed with width <= height.
*/
- public boolean isTopActivityPillarboxed() {
- return topActivityLetterboxWidth < topActivityLetterboxHeight;
+ public boolean isTopActivityPillarboxShaped() {
+ return isTopActivityLetterboxed()
+ && topActivityLetterboxWidth <= topActivityLetterboxHeight;
}
/**
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 0629b8a..38c8583 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -63,6 +63,7 @@
import android.os.HandlerExecutor;
import android.os.HandlerThread;
import android.os.IBinder;
+import android.os.IpcDataCache;
import android.os.Looper;
import android.os.PackageTagsList;
import android.os.Parcel;
@@ -78,12 +79,14 @@
import android.permission.PermissionUsageHelper;
import android.permission.flags.Flags;
import android.provider.DeviceConfig;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LongSparseArray;
import android.util.LongSparseLongArray;
import android.util.Pools;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.Immutable;
@@ -1611,9 +1614,16 @@
/** @hide Access to read skin temperature. */
public static final int OP_READ_SKIN_TEMPERATURE = AppOpEnums.APP_OP_READ_SKIN_TEMPERATURE;
+ /**
+ * Allows an app to range with nearby devices using any ranging technology available.
+ *
+ * @hide
+ */
+ public static final int OP_RANGING = AppOpEnums.APP_OP_RANGING;
+
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int _NUM_OP = 151;
+ public static final int _NUM_OP = 152;
/**
* All app ops represented as strings.
@@ -1768,6 +1778,7 @@
OPSTR_RECEIVE_SENSITIVE_NOTIFICATIONS,
OPSTR_READ_HEART_RATE,
OPSTR_READ_SKIN_TEMPERATURE,
+ OPSTR_RANGING,
})
public @interface AppOpString {}
@@ -2515,6 +2526,11 @@
@FlaggedApi(Flags.FLAG_PLATFORM_SKIN_TEMPERATURE_ENABLED)
public static final String OPSTR_READ_SKIN_TEMPERATURE = "android:read_skin_temperature";
+ /** @hide Access to ranging */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_RANGING_PERMISSION_ENABLED)
+ public static final String OPSTR_RANGING = "android:ranging";
+
/** {@link #sAppOpsToNote} not initialized yet for this op */
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -2586,6 +2602,7 @@
OP_BLUETOOTH_ADVERTISE,
OP_UWB_RANGING,
OP_NEARBY_WIFI_DEVICES,
+ Flags.rangingPermissionEnabled() ? OP_RANGING : OP_NONE,
// Notifications
OP_POST_NOTIFICATION,
// Health
@@ -3108,6 +3125,10 @@
Flags.platformSkinTemperatureEnabled()
? HealthPermissions.READ_SKIN_TEMPERATURE : null)
.setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
+ new AppOpInfo.Builder(OP_RANGING, OPSTR_RANGING, "RANGING")
+ .setPermission(Flags.rangingPermissionEnabled()?
+ Manifest.permission.RANGING : null)
+ .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
};
// The number of longs needed to form a full bitmask of app ops
@@ -7797,6 +7818,116 @@
}
}
+ private static final String APP_OP_MODE_CACHING_API = "getAppOpMode";
+ private static final String APP_OP_MODE_CACHING_NAME = "appOpModeCache";
+ private static final int APP_OP_MODE_CACHING_SIZE = 2048;
+
+ private static final IpcDataCache.QueryHandler<AppOpModeQuery, Integer> sGetAppOpModeQuery =
+ new IpcDataCache.QueryHandler<>() {
+ @Override
+ public Integer apply(AppOpModeQuery query) {
+ IAppOpsService service = getService();
+ try {
+ return service.checkOperationRawForDevice(query.op, query.uid,
+ query.packageName, query.attributionTag, query.virtualDeviceId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ @Override
+ public boolean shouldBypassCache(@NonNull AppOpModeQuery query) {
+ // If the flag to enable the new caching behavior is off, bypass the cache.
+ return !Flags.appopModeCachingEnabled();
+ }
+ };
+
+ // A LRU cache on binder clients that caches AppOp mode by uid, packageName, virtualDeviceId
+ // and attributionTag.
+ private static final IpcDataCache<AppOpModeQuery, Integer> sAppOpModeCache =
+ new IpcDataCache<>(APP_OP_MODE_CACHING_SIZE, IpcDataCache.MODULE_SYSTEM,
+ APP_OP_MODE_CACHING_API, APP_OP_MODE_CACHING_NAME, sGetAppOpModeQuery);
+
+ // Ops that we don't want to cache due to:
+ // 1) Discrepancy of attributionTag support in checkOp and noteOp that determines if a package
+ // can bypass user restriction of an op: b/240617242. COARSE_LOCATION and FINE_LOCATION are
+ // the only two ops that are impacted.
+ private static final SparseBooleanArray OPS_WITHOUT_CACHING = new SparseBooleanArray();
+ static {
+ OPS_WITHOUT_CACHING.put(OP_COARSE_LOCATION, true);
+ OPS_WITHOUT_CACHING.put(OP_FINE_LOCATION, true);
+ }
+
+ private static boolean isAppOpModeCachingEnabled(int opCode) {
+ if (!Flags.appopModeCachingEnabled()) {
+ return false;
+ }
+ return !OPS_WITHOUT_CACHING.get(opCode, false);
+ }
+
+ /**
+ * @hide
+ */
+ public static void invalidateAppOpModeCache() {
+ if (Flags.appopModeCachingEnabled()) {
+ IpcDataCache.invalidateCache(IpcDataCache.MODULE_SYSTEM, APP_OP_MODE_CACHING_API);
+ }
+ }
+
+ /**
+ * Bypass AppOpModeCache in the local process
+ *
+ * @hide
+ */
+ public static void disableAppOpModeCache() {
+ if (Flags.appopModeCachingEnabled()) {
+ sAppOpModeCache.disableLocal();
+ }
+ }
+
+ private static final class AppOpModeQuery {
+ final int op;
+ final int uid;
+ final String packageName;
+ final int virtualDeviceId;
+ final String attributionTag;
+ final String methodName;
+
+ AppOpModeQuery(int op, int uid, @Nullable String packageName, int virtualDeviceId,
+ @Nullable String attributionTag, @Nullable String methodName) {
+ this.op = op;
+ this.uid = uid;
+ this.packageName = packageName;
+ this.virtualDeviceId = virtualDeviceId;
+ this.attributionTag = attributionTag;
+ this.methodName = methodName;
+ }
+
+ @Override
+ public String toString() {
+ return TextUtils.formatSimple("AppOpModeQuery(op=%d, uid=%d, packageName=%s, "
+ + "virtualDeviceId=%d, attributionTag=%s, methodName=%s", op, uid,
+ packageName, virtualDeviceId, attributionTag, methodName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(op, uid, packageName, virtualDeviceId, attributionTag);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null) return false;
+ if (this.getClass() != o.getClass()) return false;
+
+ AppOpModeQuery other = (AppOpModeQuery) o;
+ return op == other.op && uid == other.uid && Objects.equals(packageName,
+ other.packageName) && virtualDeviceId == other.virtualDeviceId
+ && Objects.equals(attributionTag, other.attributionTag);
+ }
+ }
+
AppOpsManager(Context context, IAppOpsService service) {
mContext = context;
mService = service;
@@ -8851,12 +8982,16 @@
private int unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName,
int virtualDeviceId) {
try {
- if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
- return mService.checkOperationRaw(op, uid, packageName, null);
+ int mode;
+ if (isAppOpModeCachingEnabled(op)) {
+ mode = sAppOpModeCache.query(
+ new AppOpModeQuery(op, uid, packageName, virtualDeviceId, null,
+ "unsafeCheckOpRawNoThrow"));
} else {
- return mService.checkOperationRawForDevice(
+ mode = mService.checkOperationRawForDevice(
op, uid, packageName, null, virtualDeviceId);
}
+ return mode;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -9041,7 +9176,7 @@
SyncNotedAppOp syncOp;
if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
syncOp = mService.noteOperation(op, uid, packageName, attributionTag,
- collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
+ collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
} else {
syncOp = mService.noteOperationForDevice(op, uid, packageName, attributionTag,
virtualDeviceId, collectionMode == COLLECT_ASYNC, message,
@@ -9284,8 +9419,21 @@
@UnsupportedAppUsage
public int checkOp(int op, int uid, String packageName) {
try {
- int mode = mService.checkOperationForDevice(op, uid, packageName,
- Context.DEVICE_ID_DEFAULT);
+ int mode;
+ if (isAppOpModeCachingEnabled(op)) {
+ mode = sAppOpModeCache.query(
+ new AppOpModeQuery(op, uid, packageName, Context.DEVICE_ID_DEFAULT, null,
+ "checkOp"));
+ if (mode == MODE_FOREGROUND) {
+ // We only cache raw mode. If the mode is FOREGROUND, we need another binder
+ // call to fetch translated value based on the process state.
+ mode = mService.checkOperationForDevice(op, uid, packageName,
+ Context.DEVICE_ID_DEFAULT);
+ }
+ } else {
+ mode = mService.checkOperationForDevice(op, uid, packageName,
+ Context.DEVICE_ID_DEFAULT);
+ }
if (mode == MODE_ERRORED) {
throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
}
@@ -9324,13 +9472,19 @@
private int checkOpNoThrow(int op, int uid, String packageName, int virtualDeviceId) {
try {
int mode;
- if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
- mode = mService.checkOperation(op, uid, packageName);
+ if (isAppOpModeCachingEnabled(op)) {
+ mode = sAppOpModeCache.query(
+ new AppOpModeQuery(op, uid, packageName, virtualDeviceId, null,
+ "checkOpNoThrow"));
+ if (mode == MODE_FOREGROUND) {
+ // We only cache raw mode. If the mode is FOREGROUND, we need another binder
+ // call to fetch translated value based on the process state.
+ mode = mService.checkOperationForDevice(op, uid, packageName, virtualDeviceId);
+ }
} else {
mode = mService.checkOperationForDevice(op, uid, packageName, virtualDeviceId);
}
-
- return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
+ return mode;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 2cf718e..3ae60d71 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1167,6 +1167,7 @@
@Override
public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
try {
+ intent.collectExtraIntentKeys();
ActivityTaskManager.getService().startActivityAsUser(
mMainThread.getApplicationThread(), getOpPackageName(), getAttributionTag(),
intent, intent.resolveTypeIfNeeded(getContentResolver()),
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index d1e517b..16444dc 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -398,6 +398,7 @@
new RegularPermission(Manifest.permission.NFC),
new RegularPermission(Manifest.permission.TRANSMIT_IR),
new RegularPermission(Manifest.permission.UWB_RANGING),
+ new RegularPermission(Manifest.permission.RANGING),
new UsbDevicePermission(),
new UsbAccessoryPermission(),
}, false),
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index a97fa18..0654ac2 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -267,4 +267,7 @@
void setAdjustmentTypeSupportedState(in INotificationListener token, String key, boolean supported);
List<String> getUnsupportedAdjustmentTypes();
+
+ int[] getAllowedAdjustmentKeyTypes();
+ void setAssistantAdjustmentKeyTypeState(int type, boolean enabled);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c6c0395..0381ee0 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -155,7 +155,7 @@
FOREGROUND_SERVICE_IMMEDIATE,
FOREGROUND_SERVICE_DEFERRED
})
- public @interface ServiceNotificationPolicy {};
+ public @interface ServiceNotificationPolicy {}
/**
* If the Notification associated with starting a foreground service has been
@@ -1754,10 +1754,6 @@
private Icon mSmallIcon;
@UnsupportedAppUsage
private Icon mLargeIcon;
- private Icon mAppIcon;
-
- /** Cache for whether the notification was posted by a headless system app. */
- private Boolean mBelongsToHeadlessSystemApp = null;
@UnsupportedAppUsage
private String mChannelId;
@@ -3247,86 +3243,6 @@
}
/**
- * Whether this notification was posted by a headless system app.
- *
- * If we don't have enough information to figure this out, this will return false. Therefore,
- * false negatives are possible, but false positives should not be.
- *
- * @hide
- */
- public boolean belongsToHeadlessSystemApp(Context context) {
- Trace.beginSection("Notification#belongsToHeadlessSystemApp");
-
- try {
- if (mBelongsToHeadlessSystemApp != null) {
- return mBelongsToHeadlessSystemApp;
- }
-
- if (context == null) {
- // Without a valid context, we don't know exactly. Let's assume it doesn't belong to
- // a system app, but not cache the value.
- return false;
- }
-
- ApplicationInfo info = getApplicationInfo(context);
- if (info != null) {
- if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
- // It's not a system app at all.
- mBelongsToHeadlessSystemApp = false;
- } else {
- // If there's no launch intent, it's probably a headless app.
- final PackageManager pm = context.getPackageManager();
- mBelongsToHeadlessSystemApp = pm.getLaunchIntentForPackage(info.packageName)
- == null;
- }
- } else {
- // If for some reason we don't have the app info, we don't know; best assume it's
- // not a system app.
- return false;
- }
- return mBelongsToHeadlessSystemApp;
- } finally {
- Trace.endSection();
- }
- }
-
- /**
- * Get the resource ID of the app icon from application info.
- * @hide
- */
- public int getHeaderAppIconRes(Context context) {
- ApplicationInfo info = getApplicationInfo(context);
- if (info != null) {
- return info.icon;
- }
- return 0;
- }
-
- /**
- * Load the app icon drawable from the package manager. This could result in a binder call.
- * @hide
- */
- public Drawable loadHeaderAppIcon(Context context) {
- Trace.beginSection("Notification#loadHeaderAppIcon");
-
- try {
- if (context == null) {
- Log.e(TAG, "Cannot load the app icon drawable with a null context");
- return null;
- }
- final PackageManager pm = context.getPackageManager();
- ApplicationInfo info = getApplicationInfo(context);
- if (info == null) {
- Log.e(TAG, "Cannot load the app icon drawable: no application info");
- return null;
- }
- return pm.getApplicationIcon(info);
- } finally {
- Trace.endSection();
- }
- }
-
- /**
* Fetch the application info from the notification, or the context if that isn't available.
*/
private ApplicationInfo getApplicationInfo(Context context) {
@@ -4361,55 +4277,6 @@
}
/**
- * The colored app icon that can replace the small icon in the notification starting in V.
- *
- * Before using this value, you should first check whether it's actually being used by the
- * notification by calling {@link Notification#shouldUseAppIcon()}.
- *
- * @hide
- */
- public Icon getAppIcon() {
- if (mAppIcon != null) {
- return mAppIcon;
- }
- // If the app icon hasn't been loaded yet, check if we can load it without a context.
- if (extras.containsKey(EXTRA_BUILDER_APPLICATION_INFO)) {
- final ApplicationInfo info = extras.getParcelable(
- EXTRA_BUILDER_APPLICATION_INFO,
- ApplicationInfo.class);
- if (info != null) {
- int appIconRes = info.icon;
- if (appIconRes == 0) {
- Log.w(TAG, "Failed to get the app icon: no icon in application info");
- return null;
- }
- mAppIcon = Icon.createWithResource(info.packageName, appIconRes);
- return mAppIcon;
- } else {
- Log.e(TAG, "Failed to get the app icon: "
- + "there's an EXTRA_BUILDER_APPLICATION_INFO in extras but it's null");
- }
- } else {
- Log.w(TAG, "Failed to get the app icon: no application info in extras");
- }
- return null;
- }
-
- /**
- * Whether the notification is using the app icon instead of the small icon.
- * @hide
- */
- public boolean shouldUseAppIcon() {
- if (Flags.notificationsUseAppIconInRow()) {
- if (belongsToHeadlessSystemApp(/* context = */ null)) {
- return false;
- }
- return getAppIcon() != null;
- }
- return false;
- }
-
- /**
* The large icon shown in this notification's content view.
* @see Builder#getLargeIcon()
* @see Builder#setLargeIcon(Icon)
@@ -4566,19 +4433,6 @@
private static final boolean USE_ONLY_TITLE_IN_LOW_PRIORITY_SUMMARY =
SystemProperties.getBoolean("notifications.only_title", true);
- /**
- * The lightness difference that has to be added to the primary text color to obtain the
- * secondary text color when the background is light.
- */
- private static final int LIGHTNESS_TEXT_DIFFERENCE_LIGHT = 20;
-
- /**
- * The lightness difference that has to be added to the primary text color to obtain the
- * secondary text color when the background is dark.
- * A bit less then the above value, since it looks better on dark backgrounds.
- */
- private static final int LIGHTNESS_TEXT_DIFFERENCE_DARK = -10;
-
private Context mContext;
private Notification mN;
private Bundle mUserExtras = new Bundle();
@@ -6451,36 +6305,12 @@
}
private void bindSmallIcon(RemoteViews contentView, StandardTemplateParams p) {
- if (Flags.notificationsUseAppIcon()) {
- // Override small icon with app icon
- mN.mSmallIcon = Icon.createWithResource(mContext,
- mN.getHeaderAppIconRes(mContext));
- } else if (mN.mSmallIcon == null && mN.icon != 0) {
+ if (mN.mSmallIcon == null && mN.icon != 0) {
mN.mSmallIcon = Icon.createWithResource(mContext, mN.icon);
}
-
- boolean usingAppIcon = false;
- if (Flags.notificationsUseAppIconInRow() && !mN.belongsToHeadlessSystemApp(mContext)) {
- // Use the app icon in the view
- int appIconRes = mN.getHeaderAppIconRes(mContext);
- if (appIconRes != 0) {
- mN.mAppIcon = Icon.createWithResource(mContext, appIconRes);
- contentView.setImageViewIcon(R.id.icon, mN.mAppIcon);
- contentView.setBoolean(R.id.icon, "setShouldShowAppIcon", true);
- usingAppIcon = true;
- } else {
- Log.w(TAG, "bindSmallIcon: could not get the app icon");
- }
- }
- if (!usingAppIcon) {
- contentView.setImageViewIcon(R.id.icon, mN.mSmallIcon);
- }
+ contentView.setImageViewIcon(R.id.icon, mN.mSmallIcon);
contentView.setInt(R.id.icon, "setImageLevel", mN.iconLevel);
-
- // Don't change color if we're using the app icon.
- if (!Flags.notificationsUseAppIcon() && !usingAppIcon) {
- processSmallIconColor(mN.mSmallIcon, contentView, p);
- }
+ processSmallIconColor(mN.mSmallIcon, contentView, p);
}
/**
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 768b70c..c49b022 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1848,6 +1848,20 @@
/**
* @hide
*/
+ @TestApi
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+ public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type, boolean enabled) {
+ INotificationManager service = getService();
+ try {
+ service.setAssistantAdjustmentKeyTypeState(type, enabled);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ */
public List<String> getEnabledNotificationListenerPackages() {
INotificationManager service = getService();
try {
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 038dcdb..f432a22 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -717,12 +717,10 @@
// The shared memory.
private volatile NonceStore mStore;
- // The index of the nonce in shared memory.
+ // The index of the nonce in shared memory. This changes from INVALID only when the local
+ // object is completely initialized.
private volatile int mHandle = NonceStore.INVALID_NONCE_INDEX;
- // True if the string has been stored, ever.
- private volatile boolean mRecorded = false;
-
// A short name that is saved in shared memory. This is the portion of the property name
// that follows the prefix.
private final String mShortName;
@@ -736,48 +734,63 @@
}
}
+ // Initialize the mStore and mHandle variables. This function does nothing if the
+ // variables are already initialized. Synchronization ensures that initialization happens
+ // no more than once. The function returns the new value of mHandle.
+ //
+ // If the "update" boolean is true, then the property is registered with the nonce store
+ // before the associated handle is fetched.
+ private int initialize(boolean update) {
+ synchronized (mLock) {
+ int handle = mHandle;
+ if (handle == NonceStore.INVALID_NONCE_INDEX) {
+ if (mStore == null) {
+ mStore = NonceStore.getInstance();
+ if (mStore == null) {
+ return NonceStore.INVALID_NONCE_INDEX;
+ }
+ }
+ if (update) {
+ mStore.storeName(mShortName);
+ }
+ handle = mStore.getHandleForName(mShortName);
+ if (handle == NonceStore.INVALID_NONCE_INDEX) {
+ return NonceStore.INVALID_NONCE_INDEX;
+ }
+ // The handle must be valid.
+ mHandle = handle;
+ }
+ return handle;
+ }
+ }
+
// Fetch the nonce from shared memory. If the shared memory is not available, return
// UNSET. If the shared memory is available but the nonce name is not known (it may not
// have been invalidated by the server yet), return UNSET.
@Override
long getNonceInternal() {
- if (mHandle == NonceStore.INVALID_NONCE_INDEX) {
- if (mStore == null) {
- mStore = NonceStore.getInstance();
- if (mStore == null) {
- return NONCE_UNSET;
- }
- }
- mHandle = mStore.getHandleForName(mShortName);
- if (mHandle == NonceStore.INVALID_NONCE_INDEX) {
+ int handle = mHandle;
+ if (handle == NonceStore.INVALID_NONCE_INDEX) {
+ handle = initialize(false);
+ if (handle == NonceStore.INVALID_NONCE_INDEX) {
return NONCE_UNSET;
}
}
- return mStore.getNonce(mHandle);
+ return mStore.getNonce(handle);
}
- // Set the nonce in shared mmory. If the shared memory is not available, throw an
- // exception. Otherwise, if the nonce name has never been recorded, record it now and
- // fetch the handle for the name. If the handle cannot be created, throw an exception.
+ // Set the nonce in shared memory. If the shared memory is not available or if the nonce
+ // cannot be registered in shared memory, throw an exception.
@Override
void setNonceInternal(long value) {
- if (mHandle == NonceStore.INVALID_NONCE_INDEX || !mRecorded) {
- if (mStore == null) {
- mStore = NonceStore.getInstance();
- if (mStore == null) {
- throw new IllegalStateException("setNonce: shared memory not ready");
- }
- }
- // Always store the name before fetching the handle. storeName() is idempotent
- // but does take a little time, so this code calls it just once.
- mStore.storeName(mShortName);
- mRecorded = true;
- mHandle = mStore.getHandleForName(mShortName);
- if (mHandle == NonceStore.INVALID_NONCE_INDEX) {
- throw new IllegalStateException("setNonce: shared memory store failed");
+ int handle = mHandle;
+ if (handle == NonceStore.INVALID_NONCE_INDEX) {
+ handle = initialize(true);
+ if (handle == NonceStore.INVALID_NONCE_INDEX) {
+ throw new IllegalStateException("unable to assign nonce handle: " + mName);
}
}
- mStore.setNonce(mHandle, value);
+ mStore.setNonce(handle, value);
}
}
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index c4a6dec..aac963a 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -364,8 +364,9 @@
// Do nothing
}
- private TaskInfo(Parcel source) {
- readFromParcel(source);
+ /** @hide */
+ public TaskInfo(Parcel source) {
+ readTaskFromParcel(source);
}
/**
@@ -524,7 +525,7 @@
/**
* Reads the TaskInfo from a parcel.
*/
- void readFromParcel(Parcel source) {
+ void readTaskFromParcel(Parcel source) {
userId = source.readInt();
taskId = source.readInt();
effectiveUid = source.readInt();
@@ -577,8 +578,9 @@
/**
* Writes the TaskInfo to a parcel.
+ * @hide
*/
- void writeToParcel(Parcel dest, int flags) {
+ public void writeTaskToParcel(Parcel dest, int flags) {
dest.writeInt(userId);
dest.writeInt(taskId);
dest.writeInt(effectiveUid);
diff --git a/core/java/android/app/admin/DevicePolicyIdentifiers.java b/core/java/android/app/admin/DevicePolicyIdentifiers.java
index c0e435c..35149b5 100644
--- a/core/java/android/app/admin/DevicePolicyIdentifiers.java
+++ b/core/java/android/app/admin/DevicePolicyIdentifiers.java
@@ -191,6 +191,12 @@
public static final String PASSWORD_COMPLEXITY_POLICY = "passwordComplexity";
/**
+ * String identifier for {@link DevicePolicyManager#setMtePolicy(int)}.
+ */
+ @FlaggedApi(android.app.admin.flags.Flags.FLAG_SET_MTE_POLICY_COEXISTENCE)
+ public static final String MEMORY_TAGGING_POLICY = "memoryTagging";
+
+ /**
* @hide
*/
public static final String USER_RESTRICTION_PREFIX = "userRestriction_";
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 9f7b22c..fee071b 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -276,6 +276,16 @@
}
flag {
+ name: "suspend_packages_coexistence"
+ namespace: "enterprise"
+ description: "Migrate setPackagesSuspended for unmanaged mode"
+ bug: "335624297"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "backup_connected_apps_settings"
namespace: "enterprise"
description: "backup and restore connected work and personal apps user settings across devices"
diff --git a/core/java/android/app/compat/ChangeIdStateCache.java b/core/java/android/app/compat/ChangeIdStateCache.java
index db663f8..7d21cbf 100644
--- a/core/java/android/app/compat/ChangeIdStateCache.java
+++ b/core/java/android/app/compat/ChangeIdStateCache.java
@@ -31,13 +31,24 @@
* Handles caching of calls to {@link com.android.internal.compat.IPlatformCompat}
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class ChangeIdStateCache
extends PropertyInvalidatedCache<ChangeIdStateQuery, Boolean> {
private static final String CACHE_KEY = createSystemCacheKey("is_compat_change_enabled");
private static final int MAX_ENTRIES = 2048;
- private static boolean sDisabled = false;
+ private static boolean sDisabled = getDefaultDisabled();
private volatile IPlatformCompat mPlatformCompat;
+
+ @android.ravenwood.annotation.RavenwoodReplace
+ private static boolean getDefaultDisabled() {
+ return false;
+ }
+
+ private static boolean getDefaultDisabled$ravenwood() {
+ return true; // TODO(b/376676753) Disable the cache for now.
+ }
+
/** @hide */
public ChangeIdStateCache() {
super(MAX_ENTRIES, CACHE_KEY);
diff --git a/core/java/android/app/compat/ChangeIdStateQuery.java b/core/java/android/app/compat/ChangeIdStateQuery.java
index 7598d6c..26d9ab6 100644
--- a/core/java/android/app/compat/ChangeIdStateQuery.java
+++ b/core/java/android/app/compat/ChangeIdStateQuery.java
@@ -35,6 +35,7 @@
* @hide
*/
@Immutable
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
final class ChangeIdStateQuery {
static final int QUERY_BY_PACKAGE_NAME = 0;
diff --git a/core/java/android/app/compat/CompatChanges.java b/core/java/android/app/compat/CompatChanges.java
index d7b2ab4..643d4c9 100644
--- a/core/java/android/app/compat/CompatChanges.java
+++ b/core/java/android/app/compat/CompatChanges.java
@@ -39,6 +39,7 @@
* @hide
*/
@SystemApi
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatChanges {
private static final ChangeIdStateCache QUERY_CACHE = new ChangeIdStateCache();
diff --git a/core/java/android/app/compat/PackageOverride.java b/core/java/android/app/compat/PackageOverride.java
index ebc2945..ffc1eec 100644
--- a/core/java/android/app/compat/PackageOverride.java
+++ b/core/java/android/app/compat/PackageOverride.java
@@ -36,6 +36,7 @@
* @hide
*/
@SystemApi
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class PackageOverride {
/** @hide */
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 0fc4291..ee93870 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -8,8 +8,7 @@
flag {
name: "notifications_redesign_app_icons"
namespace: "systemui"
- description: "Notifications Redesign: Use app icons in notification rows (not to be confused with"
- " notifications_use_app_icons, notifications_use_app_icon_in_row which are just experiments)."
+ description: "Notifications Redesign: Use app icons in notification rows"
bug: "371174789"
}
@@ -110,31 +109,6 @@
}
}
-# vvv Prototypes for using app icons in notifications vvv
-
-flag {
- name: "notifications_use_app_icon"
- namespace: "systemui"
- description: "Experiment to replace the small icon in a notification with the app icon. This includes the status bar, AOD, shelf and notification row itself."
- bug: "335211019"
-}
-
-flag {
- name: "notifications_use_app_icon_in_row"
- namespace: "systemui"
- description: "Experiment to replace the small icon in a notification row with the app icon."
- bug: "335211019"
-}
-
-flag {
- name: "notifications_use_monochrome_app_icon"
- namespace: "systemui"
- description: "Experiment to replace the notification icon in the status bar and shelf with the monochrome app icon, if available."
- bug: "335211019"
-}
-
-# ^^^ Prototypes for using app icons in notifications ^^^
-
flag {
name: "notification_expansion_optional"
namespace: "systemui"
diff --git a/core/java/android/app/wallpaper/WallpaperDescription.java b/core/java/android/app/wallpaper/WallpaperDescription.java
index c3d6340..8ffda72 100644
--- a/core/java/android/app/wallpaper/WallpaperDescription.java
+++ b/core/java/android/app/wallpaper/WallpaperDescription.java
@@ -18,8 +18,6 @@
import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
-import static java.nio.charset.StandardCharsets.UTF_8;
-
import android.annotation.FlaggedApi;
import android.app.WallpaperInfo;
import android.content.ComponentName;
@@ -31,7 +29,6 @@
import android.text.Spanned;
import android.text.SpannedString;
import android.util.Log;
-import android.util.Xml;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -43,8 +40,6 @@
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -154,46 +149,6 @@
return Objects.hash(mComponent, mId);
}
- ////// Stream read/write
-
- /**
- * Writes the content of the {@link WallpaperDescription} to a {@link OutputStream}.
- *
- * <p>The content can be read by {@link #readFromStream}. This method is intended for use by
- * trusted apps only, and the format is not guaranteed to be stable.</p>
- */
- public void writeToStream(@NonNull OutputStream outputStream) throws IOException {
- TypedXmlSerializer serializer = Xml.newFastSerializer();
- serializer.setOutput(outputStream, UTF_8.name());
- serializer.startTag(null, "description");
- try {
- saveToXml(serializer);
- } catch (XmlPullParserException e) {
- throw new IOException(e);
- }
- serializer.endTag(null, "description");
- serializer.flush();
- }
-
- /**
- * Reads a {@link PersistableBundle} from an {@link InputStream}.
- *
- * <p>The stream must be generated by {@link #writeToStream}. This method is intended for use by
- * trusted apps only, and the format is not guaranteed to be stable.</p>
- */
- @NonNull
- public static WallpaperDescription readFromStream(@NonNull InputStream inputStream)
- throws IOException {
- try {
- TypedXmlPullParser parser = Xml.newFastPullParser();
- parser.setInput(inputStream, UTF_8.name());
- parser.next();
- return WallpaperDescription.restoreFromXml(parser);
- } catch (XmlPullParserException e) {
- throw new IOException(e);
- }
- }
-
////// XML storage
/** @hide */
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 9af2016..c47fe23 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -153,3 +153,10 @@
bug: "371173368"
is_exported: true
}
+
+flag {
+ name: "vdm_settings"
+ namespace: "virtual_devices"
+ description: "Show virtual devices in Settings"
+ bug: "338974320"
+}
diff --git a/core/java/android/content/pm/IOnAppsChangedListener.aidl b/core/java/android/content/pm/IOnAppsChangedListener.aidl
index 830cbe0..ade58c4 100644
--- a/core/java/android/content/pm/IOnAppsChangedListener.aidl
+++ b/core/java/android/content/pm/IOnAppsChangedListener.aidl
@@ -16,6 +16,7 @@
package android.content.pm;
+import android.content.pm.LauncherUserInfo;
import android.content.pm.ParceledListSlice;
import android.os.Bundle;
import android.os.UserHandle;
@@ -34,4 +35,5 @@
void onPackagesUnsuspended(in UserHandle user, in String[] packageNames);
void onShortcutChanged(in UserHandle user, String packageName, in ParceledListSlice shortcuts);
void onPackageLoadingProgressChanged(in UserHandle user, String packageName, float progress);
+ void onUserConfigChanged(in LauncherUserInfo launcherUserInfo);
}
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 26f919f..26b8356 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -182,6 +182,8 @@
*/
public static final int FLAG_CACHE_PEOPLE_TILE_SHORTCUTS = 2;
+ private static final String LAUNCHER_USER_INFO_EXTRA_KEY = "launcher_user_info";
+
/** @hide */
@IntDef(flag = false, prefix = { "FLAG_CACHE_" }, value = {
FLAG_CACHE_NOTIFICATION_SHORTCUTS,
@@ -349,6 +351,19 @@
*/
public void onPackageLoadingProgressChanged(@NonNull String packageName,
@NonNull UserHandle user, float progress) {}
+
+ /**
+ * Indicates {@link LauncherUserInfo} configs for a user have changed. The new
+ * {@link LauncherUserInfo} is given as a parameter.
+ *
+ * {@link LauncherUserInfo#getUserConfig} to get the updated user configs.
+ *
+ * @param launcherUserInfo The LauncherUserInfo of the user/profile whose configs have
+ * changed.
+ */
+ @FlaggedApi(android.multiuser.Flags.FLAG_ADD_LAUNCHER_USER_CONFIG)
+ public void onUserConfigChanged(@NonNull LauncherUserInfo launcherUserInfo) {
+ }
}
/**
@@ -2168,6 +2183,21 @@
}
}
}
+
+ public void onUserConfigChanged(LauncherUserInfo launcherUserInfo) {
+ if (DEBUG) {
+ if (Flags.allowPrivateProfile()
+ && android.multiuser.Flags.addLauncherUserConfig()) {
+ Log.d(TAG, "OnUserConfigChanged for user type " + launcherUserInfo.getUserType()
+ + ", new userConfig: " + launcherUserInfo.getUserConfig());
+ }
+ }
+ synchronized (LauncherApps.this) {
+ for (CallbackMessageHandler callback : mCallbacks) {
+ callback.postOnUserConfigChanged(launcherUserInfo);
+ }
+ }
+ }
};
/**
@@ -2224,6 +2254,7 @@
private static final int MSG_UNSUSPENDED = 7;
private static final int MSG_SHORTCUT_CHANGED = 8;
private static final int MSG_LOADING_PROGRESS_CHANGED = 9;
+ private static final int MSG_USER_CONFIG_CHANGED = 10;
private final LauncherApps.Callback mCallback;
@@ -2278,6 +2309,14 @@
mCallback.onPackageLoadingProgressChanged(info.packageName, info.user,
info.mLoadingProgress);
break;
+ case MSG_USER_CONFIG_CHANGED:
+ if (Flags.allowPrivateProfile()
+ && android.multiuser.Flags.addLauncherUserConfig()) {
+ mCallback.onUserConfigChanged(Objects.requireNonNull(
+ info.launcherExtras.getParcelable(LAUNCHER_USER_INFO_EXTRA_KEY,
+ LauncherUserInfo.class)));
+ }
+ break;
}
}
@@ -2353,6 +2392,13 @@
info.mLoadingProgress = progress;
obtainMessage(MSG_LOADING_PROGRESS_CHANGED, info).sendToTarget();
}
+
+ public void postOnUserConfigChanged(LauncherUserInfo launcherUserInfo) {
+ CallbackInfo info = new CallbackInfo();
+ info.launcherExtras = new Bundle();
+ info.launcherExtras.putParcelable(LAUNCHER_USER_INFO_EXTRA_KEY, launcherUserInfo);
+ obtainMessage(MSG_USER_CONFIG_CHANGED, info).sendToTarget();
+ }
}
/**
diff --git a/core/java/android/content/pm/LauncherUserInfo.java b/core/java/android/content/pm/LauncherUserInfo.java
index 8426f54..574af59 100644
--- a/core/java/android/content/pm/LauncherUserInfo.java
+++ b/core/java/android/content/pm/LauncherUserInfo.java
@@ -18,6 +18,7 @@
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
+import android.os.Bundle;
import android.os.Flags;
import android.os.Parcel;
import android.os.Parcelable;
@@ -31,11 +32,25 @@
@FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE)
public final class LauncherUserInfo implements Parcelable {
+ /**
+ * A boolean extra indicating whether the private space entrypoint should be hidden when locked.
+ *
+ * @see #getUserConfig
+ */
+ @FlaggedApi(android.multiuser.Flags.FLAG_ADD_LAUNCHER_USER_CONFIG)
+ public static final String PRIVATE_SPACE_ENTRYPOINT_HIDDEN =
+ "private_space_entrypoint_hidden";
+
private final String mUserType;
// Serial number for the user, should be same as in the {@link UserInfo} object.
private final int mUserSerialNumber;
+ // Additional configs for the user, e.g., whether to hide the private space entrypoint when
+ // locked.
+ private final Bundle mUserConfig;
+
+
/**
* Returns type of the user as defined in {@link UserManager}. e.g.,
* {@link UserManager.USER_TYPE_PROFILE_MANAGED} or {@link UserManager.USER_TYPE_PROFILE_ClONE}
@@ -50,6 +65,17 @@
}
/**
+ * Returns additional configs for this launcher user
+ *
+ * @see #PRIVATE_SPACE_ENTRYPOINT_HIDDEN
+ */
+ @FlaggedApi(android.multiuser.Flags.FLAG_ADD_LAUNCHER_USER_CONFIG)
+ @NonNull
+ public Bundle getUserConfig() {
+ return mUserConfig;
+ }
+
+ /**
* Returns serial number of user as returned by
* {@link UserManager#getSerialNumberForUser(UserHandle)}
*
@@ -63,6 +89,7 @@
private LauncherUserInfo(@NonNull Parcel in) {
mUserType = in.readString16NoHelper();
mUserSerialNumber = in.readInt();
+ mUserConfig = in.readBundle(Bundle.class.getClassLoader());
}
@Override
@@ -70,6 +97,7 @@
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString16NoHelper(mUserType);
dest.writeInt(mUserSerialNumber);
+ dest.writeBundle(mUserConfig);
}
@Override
@@ -99,23 +127,36 @@
private final String mUserType;
private final int mUserSerialNumber;
+ private final Bundle mUserConfig;
+
+
+ @FlaggedApi(android.multiuser.Flags.FLAG_ADD_LAUNCHER_USER_CONFIG)
+ public Builder(@NonNull String userType, int userSerialNumber, @NonNull Bundle config) {
+ this.mUserType = userType;
+ this.mUserSerialNumber = userSerialNumber;
+ this.mUserConfig = config;
+ }
public Builder(@NonNull String userType, int userSerialNumber) {
this.mUserType = userType;
this.mUserSerialNumber = userSerialNumber;
+ this.mUserConfig = new Bundle();
}
/**
* Builds the LauncherUserInfo object
*/
- @NonNull public LauncherUserInfo build() {
- return new LauncherUserInfo(this.mUserType, this.mUserSerialNumber);
+ @NonNull
+ public LauncherUserInfo build() {
+ return new LauncherUserInfo(this.mUserType, this.mUserSerialNumber, this.mUserConfig);
}
} // End builder
- private LauncherUserInfo(@NonNull String userType, int userSerialNumber) {
+ private LauncherUserInfo(@NonNull String userType, int userSerialNumber,
+ @NonNull Bundle config) {
this.mUserType = userType;
this.mUserSerialNumber = userSerialNumber;
+ this.mUserConfig = config;
}
}
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 5b0cee7..4285b0a 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -251,6 +251,7 @@
* {@link android.Manifest.permission#NFC},
* {@link android.Manifest.permission#TRANSMIT_IR},
* {@link android.Manifest.permission#UWB_RANGING},
+ * {@link android.Manifest.permission#RANGING},
* or has been granted the access to one of the attached USB devices/accessories.
*/
@RequiresPermission(
@@ -267,6 +268,7 @@
Manifest.permission.NFC,
Manifest.permission.TRANSMIT_IR,
Manifest.permission.UWB_RANGING,
+ Manifest.permission.RANGING,
},
conditional = true
)
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index 6f70586..c424229 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -349,3 +349,12 @@
bug: "364760703"
is_fixed_read_only: true
}
+
+flag {
+ name: "cloud_compilation_pm"
+ is_exported: true
+ namespace: "art_mainline"
+ description: "Feature flag to enable the Cloud Compilation support on the package manager side."
+ bug: "377474232"
+ is_fixed_read_only: true
+}
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 528bde8..3d89ce1 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -543,3 +543,10 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "add_launcher_user_config"
+ namespace: "profile_experiences"
+ description: "Add support for LauncherUserInfo configs"
+ bug: "346553745"
+}
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index e98fc0c..26ecbd1 100644
--- a/core/java/android/content/res/flags.aconfig
+++ b/core/java/android/content/res/flags.aconfig
@@ -83,3 +83,15 @@
bug: "364035303"
}
+flag {
+ name: "system_context_handle_app_info_changed"
+ is_exported: true
+ namespace: "resource_manager"
+ description: "Feature flag for allowing system context to handle application info changes"
+ bug: "362420029"
+ # This flag is read at boot time.
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/database/sqlite/flags.aconfig b/core/java/android/database/sqlite/flags.aconfig
index 2d18d26..d43a669 100644
--- a/core/java/android/database/sqlite/flags.aconfig
+++ b/core/java/android/database/sqlite/flags.aconfig
@@ -2,13 +2,6 @@
container: "system"
flag {
- name: "oneway_finalizer_close"
- namespace: "system_performance"
- description: "Make BuildCursorNative.close oneway if in the the finalizer"
- bug: "368221351"
-}
-
-flag {
name: "oneway_finalizer_close_fixed"
namespace: "system_performance"
is_fixed_read_only: true
diff --git a/core/java/android/hardware/DataSpace.java b/core/java/android/hardware/DataSpace.java
index 6117384..1cd9244 100644
--- a/core/java/android/hardware/DataSpace.java
+++ b/core/java/android/hardware/DataSpace.java
@@ -420,18 +420,38 @@
public static final int DATASPACE_HEIF = 4100;
/**
- * ISO/IEC TBD
+ * Ultra HDR
*
- * JPEG image with embedded recovery map following the Jpeg/R specification.
+ * JPEG image with embedded HDR gain map following the Ultra HDR specification and
+ * starting with Android version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM V}
+ * ISO/CD 21496‐1
*
- * <p>This value must always remain aligned with the public ImageFormat Jpeg/R definition and is
- * valid with formats:
- * HAL_PIXEL_FORMAT_BLOB: JPEG image encoded by Jpeg/R encoder according to ISO/IEC TBD.
- * The image contains a standard SDR JPEG and a recovery map. Jpeg/R decoders can use the
- * map to recover the input image.</p>
+ * <p>This value is valid with formats:</p>
+ * <ul>
+ * <li>HAL_PIXEL_FORMAT_BLOB: JPEG image encoded by Jpeg/R encoder according to
+ * ISO/CD 21496‐1</li>
+ * </ul>
+ * <p>
+ * The image contains a standard SDR JPEG and a gain map. Ultra HDR decoders can use the
+ * gain map to boost the brightness of the rendered image.</p>
*/
public static final int DATASPACE_JPEG_R = 4101;
+ /**
+ * ISO/IEC 23008-12:2024
+ *
+ * High Efficiency Image File Format (HEIF) with embedded HDR gain map
+ *
+ * <p>This value is valid with formats:</p>
+ * <ul>
+ * <li>HAL_PIXEL_FORMAT_BLOB: A HEIC image encoded by HEVC encoder
+ * according to ISO/IEC 23008-12:2024 that includes an HDR gain map and
+ * metadata according to ISO/CD 21496‐1.</li>
+ * </ul>
+ */
+ @FlaggedApi(com.android.internal.camera.flags.Flags.FLAG_CAMERA_HEIF_GAINMAP)
+ public static final int DATASPACE_HEIF_ULTRAHDR = 4102;
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {
@@ -660,6 +680,7 @@
DATASPACE_DEPTH,
DATASPACE_DYNAMIC_DEPTH,
DATASPACE_HEIF,
+ DATASPACE_HEIF_ULTRAHDR,
DATASPACE_JPEG_R,
DATASPACE_UNKNOWN,
DATASPACE_SCRGB_LINEAR,
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 16d82ca..a37648f7 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -5775,6 +5775,122 @@
new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.heic.availableHeicStallDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
/**
+ * <p>The available HEIC (ISO/IEC 23008-12/24) UltraHDR stream
+ * configurations that this camera device supports
+ * (i.e. format, width, height, output/input stream).</p>
+ * <p>The configurations are listed as <code>(format, width, height, input?)</code> tuples.</p>
+ * <p>All the static, control, and dynamic metadata tags related to JPEG apply to HEIC formats.
+ * Configuring JPEG and HEIC streams at the same time is not supported.</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+ *
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_HEIF_GAINMAP)
+ public static final Key<android.hardware.camera2.params.StreamConfiguration[]> HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS =
+ new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.heic.availableHeicUltraHdrStreamConfigurations", android.hardware.camera2.params.StreamConfiguration[].class);
+
+ /**
+ * <p>This lists the minimum frame duration for each
+ * format/size combination for HEIC UltraHDR output formats.</p>
+ * <p>This should correspond to the frame duration when only that
+ * stream is active, with all processing (typically in android.*.mode)
+ * set to either OFF or FAST.</p>
+ * <p>When multiple streams are used in a request, the minimum frame
+ * duration will be max(individual stream min durations).</p>
+ * <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} and
+ * android.scaler.availableStallDurations for more details about
+ * calculating the max frame rate.</p>
+ * <p><b>Units</b>: (format, width, height, ns) x n</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+ *
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CaptureRequest#SENSOR_FRAME_DURATION
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_HEIF_GAINMAP)
+ public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS =
+ new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.heic.availableHeicUltraHdrMinFrameDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+ /**
+ * <p>This lists the maximum stall duration for each
+ * output format/size combination for HEIC UltraHDR streams.</p>
+ * <p>A stall duration is how much extra time would get added
+ * to the normal minimum frame duration for a repeating request
+ * that has streams with non-zero stall.</p>
+ * <p>This functions similarly to
+ * android.scaler.availableStallDurations for HEIC UltraHDR
+ * streams.</p>
+ * <p>All HEIC output stream formats may have a nonzero stall
+ * duration.</p>
+ * <p><b>Units</b>: (format, width, height, ns) x n</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+ *
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_HEIF_GAINMAP)
+ public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS =
+ new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.heic.availableHeicUltraHdrStallDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+ /**
+ * <p>The available HEIC (ISO/IEC 23008-12/24) UltraHDR stream
+ * configurations that this camera device supports
+ * (i.e. format, width, height, output/input stream) for CaptureRequests where
+ * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+ * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+ * <p>Refer to android.heic.availableHeicStreamConfigurations for details.</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#SENSOR_PIXEL_MODE
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_HEIF_GAINMAP)
+ public static final Key<android.hardware.camera2.params.StreamConfiguration[]> HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION =
+ new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.heic.availableHeicUltraHdrStreamConfigurationsMaximumResolution", android.hardware.camera2.params.StreamConfiguration[].class);
+
+ /**
+ * <p>This lists the minimum frame duration for each
+ * format/size combination for HEIC UltraHDR output formats for CaptureRequests where
+ * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+ * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+ * <p>Refer to android.heic.availableHeicMinFrameDurations for details.</p>
+ * <p><b>Units</b>: (format, width, height, ns) x n</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#SENSOR_PIXEL_MODE
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_HEIF_GAINMAP)
+ public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION =
+ new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.heic.availableHeicUltraHdrMinFrameDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+ /**
+ * <p>This lists the maximum stall duration for each
+ * output format/size combination for HEIC UltraHDR streams for CaptureRequests where
+ * {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
+ * {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }.</p>
+ * <p>Refer to android.heic.availableHeicStallDurations for details.</p>
+ * <p><b>Units</b>: (format, width, height, ns) x n</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#SENSOR_PIXEL_MODE
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_HEIF_GAINMAP)
+ public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION =
+ new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.heic.availableHeicUltraHdrStallDurationsMaximumResolution", android.hardware.camera2.params.StreamConfigurationDuration[].class);
+
+ /**
* <p>The direction of the camera faces relative to the vehicle body frame and the
* passenger seats.</p>
* <p>This enum defines the lens facing characteristic of the cameras on the automotive
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index ef7f3f8..e22c263 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -1385,6 +1385,9 @@
/*jpegRconfiguration*/ null,
/*jpegRminduration*/ null,
/*jpegRstallduration*/ null,
+ /*heicUltraHDRconfiguration*/ null,
+ /*heicUltraHDRminduration*/ null,
+ /*heicUltraHDRstallduration*/ null,
/*highspeedvideoconfigurations*/ null,
/*inputoutputformatsmap*/ null, listHighResolution, supportsPrivate[i]);
break;
@@ -1402,6 +1405,9 @@
/*jpegRconfiguration*/ null,
/*jpegRminduration*/ null,
/*jpegRstallduration*/ null,
+ /*heicUltraHDRconfiguration*/ null,
+ /*heicUltraHDRminduration*/ null,
+ /*heicUltraHDRstallduration*/ null,
highSpeedVideoConfigurations,
/*inputoutputformatsmap*/ null, listHighResolution, supportsPrivate[i]);
break;
@@ -1419,6 +1425,9 @@
/*jpegRconfiguration*/ null,
/*jpegRminduration*/ null,
/*jpegRstallduration*/ null,
+ /*heicUltraHDRcconfiguration*/ null,
+ /*heicUltraHDRminduration*/ null,
+ /*heicUltraHDRstallduration*/ null,
/*highSpeedVideoConfigurations*/ null,
inputOutputFormatsMap, listHighResolution, supportsPrivate[i]);
break;
@@ -1436,6 +1445,9 @@
/*jpegRconfiguration*/ null,
/*jpegRminduration*/ null,
/*jpegRstallduration*/ null,
+ /*heicUltraHDRcconfiguration*/ null,
+ /*heicUltraHDRminduration*/ null,
+ /*heicUltraHDRstallduration*/ null,
/*highSpeedVideoConfigurations*/ null,
/*inputOutputFormatsMap*/ null, listHighResolution, supportsPrivate[i]);
}
@@ -1607,6 +1619,17 @@
CameraCharacteristics.HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS);
StreamConfigurationDuration[] heicStallDurations = getBase(
CameraCharacteristics.HEIC_AVAILABLE_HEIC_STALL_DURATIONS);
+ StreamConfiguration[] heicUltraHDRConfigurations = null;
+ StreamConfigurationDuration[] heicUltraHDRMinFrameDurations = null;
+ StreamConfigurationDuration[] heicUltraHDRStallDurations = null;
+ if (Flags.cameraHeifGainmap()) {
+ heicUltraHDRConfigurations = getBase(
+ CameraCharacteristics.HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS);
+ heicUltraHDRMinFrameDurations = getBase(
+ CameraCharacteristics.HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS);
+ heicUltraHDRStallDurations = getBase(
+ CameraCharacteristics.HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS);
+ }
StreamConfiguration[] jpegRConfigurations = getBase(
CameraCharacteristics.JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS);
StreamConfigurationDuration[] jpegRMinFrameDurations = getBase(
@@ -1625,7 +1648,8 @@
dynamicDepthStallDurations, heicConfigurations,
heicMinFrameDurations, heicStallDurations,
jpegRConfigurations, jpegRMinFrameDurations, jpegRStallDurations,
- highSpeedVideoConfigurations, inputOutputFormatsMap,
+ heicUltraHDRConfigurations, heicUltraHDRMinFrameDurations,
+ heicUltraHDRStallDurations, highSpeedVideoConfigurations, inputOutputFormatsMap,
listHighResolution);
}
@@ -1662,6 +1686,17 @@
CameraCharacteristics.HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION);
StreamConfigurationDuration[] heicStallDurations = getBase(
CameraCharacteristics.HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION);
+ StreamConfiguration[] heicUltraHDRConfigurations = null;
+ StreamConfigurationDuration[] heicUltraHDRMinFrameDurations = null;
+ StreamConfigurationDuration[] heicUltraHDRStallDurations = null;
+ if (Flags.cameraHeifGainmap()) {
+ heicUltraHDRConfigurations = getBase(
+ CameraCharacteristics.HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION);
+ heicUltraHDRMinFrameDurations = getBase(
+ CameraCharacteristics.HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION);
+ heicUltraHDRStallDurations = getBase(
+ CameraCharacteristics.HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION);
+ }
StreamConfiguration[] jpegRConfigurations = getBase(
CameraCharacteristics.JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION);
StreamConfigurationDuration[] jpegRMinFrameDurations = getBase(
@@ -1681,7 +1716,8 @@
dynamicDepthStallDurations, heicConfigurations,
heicMinFrameDurations, heicStallDurations,
jpegRConfigurations, jpegRMinFrameDurations, jpegRStallDurations,
- highSpeedVideoConfigurations, inputOutputFormatsMap,
+ heicUltraHDRConfigurations, heicUltraHDRMinFrameDurations,
+ heicUltraHDRStallDurations, highSpeedVideoConfigurations, inputOutputFormatsMap,
listHighResolution, false);
}
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index e3dbb2b..ec028bf 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -20,6 +20,7 @@
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
+import android.hardware.DataSpace;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraMetadata;
@@ -31,6 +32,8 @@
import android.util.SparseIntArray;
import android.view.Surface;
+import com.android.internal.camera.flags.Flags;
+
import java.util.Arrays;
import java.util.HashMap;
import java.util.Objects;
@@ -100,6 +103,12 @@
* {@link StreamConfigurationDuration}
* @param jpegRStallDurations a non-{@code null} array of Jpeg/R
* {@link StreamConfigurationDuration}
+ * @param heicUltraHDRConfigurations a non-{@code null} array of Heic UltraHDR
+ * {@link StreamConfiguration}
+ * @param heicUltraHDRMinFrameDurations a non-{@code null} array of Heic UltraHDR
+ * {@link StreamConfigurationDuration}
+ * @param heicUltraHDRStallDurations a non-{@code null} array of Heic UltraHDR
+ * {@link StreamConfigurationDuration}
* @param highSpeedVideoConfigurations an array of {@link HighSpeedVideoConfiguration}, null if
* camera device does not support high speed video recording
* @param listHighResolution a flag indicating whether the device supports BURST_CAPTURE
@@ -125,6 +134,9 @@
StreamConfiguration[] jpegRConfigurations,
StreamConfigurationDuration[] jpegRMinFrameDurations,
StreamConfigurationDuration[] jpegRStallDurations,
+ StreamConfiguration[] heicUltraHDRConfigurations,
+ StreamConfigurationDuration[] heicUltraHDRMinFrameDurations,
+ StreamConfigurationDuration[] heicUltraHDRStallDurations,
HighSpeedVideoConfiguration[] highSpeedVideoConfigurations,
ReprocessFormatsMap inputOutputFormatsMap,
boolean listHighResolution) {
@@ -134,8 +146,9 @@
dynamicDepthStallDurations,
heicConfigurations, heicMinFrameDurations, heicStallDurations,
jpegRConfigurations, jpegRMinFrameDurations, jpegRStallDurations,
- highSpeedVideoConfigurations, inputOutputFormatsMap, listHighResolution,
- /*enforceImplementationDefined*/ true);
+ heicUltraHDRConfigurations, heicUltraHDRMinFrameDurations,
+ heicUltraHDRStallDurations, highSpeedVideoConfigurations, inputOutputFormatsMap,
+ listHighResolution, /*enforceImplementationDefined*/ true);
}
/**
@@ -168,6 +181,12 @@
* {@link StreamConfigurationDuration}
* @param jpegRStallDurations a non-{@code null} array of Jpeg/R
* {@link StreamConfigurationDuration}
+ * @param heicUltraHDRConfigurations an array of Heic UltraHDR
+ * {@link StreamConfiguration}, {@code null} if camera doesn't support the format
+ * @param heicUltraHDRMinFrameDurations an array of Heic UltraHDR
+ * {@link StreamConfigurationDuration}, {@code null} if camera doesn't support the format
+ * @param heicUltraHDRStallDurations an array of Heic UltraHDR
+ * {@link StreamConfigurationDuration}, {@code null} if camera doesn't support the format
* @param highSpeedVideoConfigurations an array of {@link HighSpeedVideoConfiguration}, null if
* camera device does not support high speed video recording
* @param listHighResolution a flag indicating whether the device supports BURST_CAPTURE
@@ -195,6 +214,9 @@
StreamConfiguration[] jpegRConfigurations,
StreamConfigurationDuration[] jpegRMinFrameDurations,
StreamConfigurationDuration[] jpegRStallDurations,
+ StreamConfiguration[] heicUltraHDRConfigurations,
+ StreamConfigurationDuration[] heicUltraHDRMinFrameDurations,
+ StreamConfigurationDuration[] heicUltraHDRStallDurations,
HighSpeedVideoConfiguration[] highSpeedVideoConfigurations,
ReprocessFormatsMap inputOutputFormatsMap,
boolean listHighResolution,
@@ -259,6 +281,18 @@
"heicStallDurations");
}
+ if (heicUltraHDRConfigurations == null || (!Flags.cameraHeifGainmap())) {
+ mHeicUltraHDRConfigurations = new StreamConfiguration[0];
+ mHeicUltraHDRMinFrameDurations = new StreamConfigurationDuration[0];
+ mHeicUltraHDRStallDurations = new StreamConfigurationDuration[0];
+ } else {
+ mHeicUltraHDRConfigurations = checkArrayElementsNotNull(heicUltraHDRConfigurations,
+ "heicUltraHDRConfigurations");
+ mHeicUltraHDRMinFrameDurations = checkArrayElementsNotNull(
+ heicUltraHDRMinFrameDurations, "heicUltraHDRMinFrameDurations");
+ mHeicUltraHDRStallDurations = checkArrayElementsNotNull(heicUltraHDRStallDurations,
+ "heicUltraHDRStallDurations");
+ }
if (jpegRConfigurations == null) {
mJpegRConfigurations = new StreamConfiguration[0];
@@ -336,6 +370,19 @@
mHeicOutputFormats.get(config.getFormat()) + 1);
}
+ if (Flags.cameraHeifGainmap()) {
+ // For each Heic UlrtaHDR format, track how many sizes there are available to configure
+ for (StreamConfiguration config : mHeicUltraHDRConfigurations) {
+ if (!config.isOutput()) {
+ // Ignoring input Heic UltraHDR configs
+ continue;
+ }
+
+ mHeicUltraHDROutputFormats.put(config.getFormat(),
+ mHeicUltraHDROutputFormats.get(config.getFormat()) + 1);
+ }
+ }
+
// For each Jpeg/R format, track how many sizes there are available to configure
for (StreamConfiguration config : mJpegRConfigurations) {
if (!config.isOutput()) {
@@ -483,6 +530,11 @@
int internalFormat = imageFormatToInternal(format);
int dataspace = imageFormatToDataspace(format);
+ if (Flags.cameraHeifGainmap()) {
+ if (dataspace == DataSpace.DATASPACE_HEIF_ULTRAHDR) {
+ return mHeicUltraHDROutputFormats.indexOfKey(internalFormat) >= 0;
+ }
+ }
if (dataspace == HAL_DATASPACE_DEPTH) {
return mDepthOutputFormats.indexOfKey(internalFormat) >= 0;
} else if (dataspace == HAL_DATASPACE_DYNAMIC_DEPTH) {
@@ -607,6 +659,11 @@
surfaceDataspace == HAL_DATASPACE_HEIF ? mHeicConfigurations :
surfaceDataspace == HAL_DATASPACE_JPEG_R ? mJpegRConfigurations :
mConfigurations;
+ if (Flags.cameraHeifGainmap()) {
+ if (surfaceDataspace == DataSpace.DATASPACE_HEIF_ULTRAHDR) {
+ configs = mHeicUltraHDRConfigurations;
+ }
+ }
for (StreamConfiguration config : configs) {
if (config.getFormat() == surfaceFormat && config.isOutput()) {
// Matching format, either need exact size match, or a flexible consumer
@@ -646,6 +703,11 @@
dataspace == HAL_DATASPACE_HEIF ? mHeicConfigurations :
dataspace == HAL_DATASPACE_JPEG_R ? mJpegRConfigurations :
mConfigurations;
+ if (Flags.cameraHeifGainmap()) {
+ if (dataspace == DataSpace.DATASPACE_HEIF_ULTRAHDR ) {
+ configs = mHeicUltraHDRConfigurations;
+ }
+ }
for (StreamConfiguration config : configs) {
if ((config.getFormat() == internalFormat) && config.isOutput() &&
config.getSize().equals(size)) {
@@ -1176,6 +1238,10 @@
Arrays.equals(mHeicConfigurations, other.mHeicConfigurations) &&
Arrays.equals(mHeicMinFrameDurations, other.mHeicMinFrameDurations) &&
Arrays.equals(mHeicStallDurations, other.mHeicStallDurations) &&
+ Arrays.equals(mHeicUltraHDRConfigurations, other.mHeicUltraHDRConfigurations) &&
+ Arrays.equals(mHeicUltraHDRMinFrameDurations,
+ other.mHeicUltraHDRMinFrameDurations) &&
+ Arrays.equals(mHeicUltraHDRStallDurations, other.mHeicUltraHDRStallDurations) &&
Arrays.equals(mJpegRConfigurations, other.mJpegRConfigurations) &&
Arrays.equals(mJpegRMinFrameDurations, other.mJpegRMinFrameDurations) &&
Arrays.equals(mJpegRStallDurations, other.mJpegRStallDurations) &&
@@ -1197,8 +1263,9 @@
mDynamicDepthConfigurations, mDynamicDepthMinFrameDurations,
mDynamicDepthStallDurations, mHeicConfigurations,
mHeicMinFrameDurations, mHeicStallDurations,
- mJpegRConfigurations, mJpegRMinFrameDurations, mJpegRStallDurations,
- mHighSpeedVideoConfigurations);
+ mHeicUltraHDRConfigurations, mHeicUltraHDRMinFrameDurations,
+ mHeicUltraHDRStallDurations, mJpegRConfigurations, mJpegRMinFrameDurations,
+ mJpegRStallDurations, mHighSpeedVideoConfigurations);
}
// Check that the argument is supported by #getOutputFormats or #getInputFormats
@@ -1209,6 +1276,13 @@
int internalDataspace = imageFormatToDataspace(format);
if (output) {
+ if (Flags.cameraHeifGainmap()) {
+ if (internalDataspace == DataSpace.DATASPACE_HEIF_ULTRAHDR) {
+ if (mHeicUltraHDROutputFormats.indexOfKey(internalFormat) >= 0) {
+ return format;
+ }
+ }
+ }
if (internalDataspace == HAL_DATASPACE_DEPTH) {
if (mDepthOutputFormats.indexOfKey(internalFormat) >= 0) {
return format;
@@ -1429,6 +1503,7 @@
* <li>ImageFormat.DEPTH_POINT_CLOUD => HAL_PIXEL_FORMAT_BLOB
* <li>ImageFormat.DEPTH_JPEG => HAL_PIXEL_FORMAT_BLOB
* <li>ImageFormat.HEIC => HAL_PIXEL_FORMAT_BLOB
+ * <li>ImageFormat.HEIC_ULTRAHDR => HAL_PIXEL_FORMAT_BLOB
* <li>ImageFormat.JPEG_R => HAL_PIXEL_FORMAT_BLOB
* <li>ImageFormat.DEPTH16 => HAL_PIXEL_FORMAT_Y16
* </ul>
@@ -1451,6 +1526,11 @@
* if {@code format} was {@code HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED}
*/
static int imageFormatToInternal(int format) {
+ if (Flags.cameraHeifGainmap()) {
+ if (format == ImageFormat.HEIC_ULTRAHDR) {
+ return HAL_PIXEL_FORMAT_BLOB;
+ }
+ }
switch (format) {
case ImageFormat.JPEG:
case ImageFormat.DEPTH_POINT_CLOUD:
@@ -1480,6 +1560,7 @@
* <li>ImageFormat.DEPTH16 => HAL_DATASPACE_DEPTH
* <li>ImageFormat.DEPTH_JPEG => HAL_DATASPACE_DYNAMIC_DEPTH
* <li>ImageFormat.HEIC => HAL_DATASPACE_HEIF
+ * <li>ImageFormat.HEIC_ULTRAHDR => DATASPACE_HEIF_ULTRAHDR
* <li>ImageFormat.JPEG_R => HAL_DATASPACE_JPEG_R
* <li>ImageFormat.YUV_420_888 => HAL_DATASPACE_JFIF
* <li>ImageFormat.RAW_SENSOR => HAL_DATASPACE_ARBITRARY
@@ -1508,6 +1589,11 @@
* if {@code format} was {@code HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED}
*/
static int imageFormatToDataspace(int format) {
+ if (Flags.cameraHeifGainmap()) {
+ if (format == ImageFormat.HEIC_ULTRAHDR) {
+ return DataSpace.DATASPACE_HEIF_ULTRAHDR;
+ }
+ }
switch (format) {
case ImageFormat.JPEG:
return HAL_DATASPACE_V0_JFIF;
@@ -1584,13 +1670,21 @@
dataspace == HAL_DATASPACE_JPEG_R ? mJpegROutputFormats :
highRes ? mHighResOutputFormats :
mOutputFormats;
-
+ boolean isDataSpaceHeifUltraHDR = false;
+ if (Flags.cameraHeifGainmap()) {
+ if (dataspace == DataSpace.DATASPACE_HEIF_ULTRAHDR) {
+ formatsMap = mHeicUltraHDROutputFormats;
+ isDataSpaceHeifUltraHDR = true;
+ }
+ }
int sizesCount = formatsMap.get(format);
if ( ((!output || (dataspace == HAL_DATASPACE_DEPTH || dataspace == HAL_DATASPACE_JPEG_R ||
dataspace == HAL_DATASPACE_DYNAMIC_DEPTH ||
- dataspace == HAL_DATASPACE_HEIF)) && sizesCount == 0) ||
+ dataspace == HAL_DATASPACE_HEIF ||
+ isDataSpaceHeifUltraHDR)) && sizesCount == 0) ||
(output && (dataspace != HAL_DATASPACE_DEPTH && dataspace != HAL_DATASPACE_JPEG_R &&
dataspace != HAL_DATASPACE_DYNAMIC_DEPTH &&
+ !isDataSpaceHeifUltraHDR &&
dataspace != HAL_DATASPACE_HEIF) &&
mAllOutputFormats.get(format) == 0)) {
return null;
@@ -1604,12 +1698,14 @@
(dataspace == HAL_DATASPACE_DYNAMIC_DEPTH) ? mDynamicDepthConfigurations :
(dataspace == HAL_DATASPACE_HEIF) ? mHeicConfigurations :
(dataspace == HAL_DATASPACE_JPEG_R) ? mJpegRConfigurations :
+ (isDataSpaceHeifUltraHDR) ? mHeicUltraHDRConfigurations :
mConfigurations;
StreamConfigurationDuration[] minFrameDurations =
(dataspace == HAL_DATASPACE_DEPTH) ? mDepthMinFrameDurations :
(dataspace == HAL_DATASPACE_DYNAMIC_DEPTH) ? mDynamicDepthMinFrameDurations :
(dataspace == HAL_DATASPACE_HEIF) ? mHeicMinFrameDurations :
(dataspace == HAL_DATASPACE_JPEG_R) ? mJpegRMinFrameDurations :
+ (isDataSpaceHeifUltraHDR) ? mHeicUltraHDRMinFrameDurations :
mMinFrameDurations;
for (StreamConfiguration config : configurations) {
@@ -1639,7 +1735,8 @@
// Dynamic depth streams can have both fast and also high res modes.
if ((sizeIndex != sizesCount) && (dataspace == HAL_DATASPACE_DYNAMIC_DEPTH ||
- dataspace == HAL_DATASPACE_HEIF) || (dataspace == HAL_DATASPACE_JPEG_R)) {
+ dataspace == HAL_DATASPACE_HEIF) || (dataspace == HAL_DATASPACE_JPEG_R) ||
+ isDataSpaceHeifUltraHDR) {
if (sizeIndex > sizesCount) {
throw new AssertionError(
@@ -1682,6 +1779,11 @@
if (mHeicOutputFormats.size() > 0) {
formats[i++] = ImageFormat.HEIC;
}
+ if (Flags.cameraHeifGainmap()) {
+ if (mHeicUltraHDROutputFormats.size() > 0) {
+ formats[i++] = ImageFormat.HEIC_ULTRAHDR;
+ }
+ }
if (mJpegROutputFormats.size() > 0) {
formats[i++] = ImageFormat.JPEG_R;
}
@@ -1725,12 +1827,19 @@
* @see #DURATION_STALL
* */
private StreamConfigurationDuration[] getDurations(int duration, int dataspace) {
+ boolean isDataSpaceHeifUltraHDR = false;
+ if (Flags.cameraHeifGainmap()) {
+ if (dataspace == DataSpace.DATASPACE_HEIF_ULTRAHDR) {
+ isDataSpaceHeifUltraHDR = true;
+ }
+ }
switch (duration) {
case DURATION_MIN_FRAME:
return (dataspace == HAL_DATASPACE_DEPTH) ? mDepthMinFrameDurations :
(dataspace == HAL_DATASPACE_DYNAMIC_DEPTH) ?
mDynamicDepthMinFrameDurations :
(dataspace == HAL_DATASPACE_HEIF) ? mHeicMinFrameDurations :
+ isDataSpaceHeifUltraHDR ? mHeicUltraHDRMinFrameDurations :
(dataspace == HAL_DATASPACE_JPEG_R) ? mJpegRMinFrameDurations :
mMinFrameDurations;
@@ -1738,6 +1847,7 @@
return (dataspace == HAL_DATASPACE_DEPTH) ? mDepthStallDurations :
(dataspace == HAL_DATASPACE_DYNAMIC_DEPTH) ? mDynamicDepthStallDurations :
(dataspace == HAL_DATASPACE_HEIF) ? mHeicStallDurations :
+ isDataSpaceHeifUltraHDR ? mHeicUltraHDRStallDurations :
(dataspace == HAL_DATASPACE_JPEG_R) ? mJpegRStallDurations :
mStallDurations;
default:
@@ -1754,6 +1864,7 @@
size += mDynamicDepthOutputFormats.size();
size += mHeicOutputFormats.size();
size += mJpegROutputFormats.size();
+ size += mHeicUltraHDROutputFormats.size();
}
return size;
@@ -1774,11 +1885,18 @@
}
private boolean isSupportedInternalConfiguration(int format, int dataspace, Size size) {
+ boolean isDataSpaceHeifUltraHDR = false;
+ if (Flags.cameraHeifGainmap()) {
+ if (dataspace == DataSpace.DATASPACE_HEIF_ULTRAHDR) {
+ isDataSpaceHeifUltraHDR = true;
+ }
+ }
StreamConfiguration[] configurations =
(dataspace == HAL_DATASPACE_DEPTH) ? mDepthConfigurations :
(dataspace == HAL_DATASPACE_DYNAMIC_DEPTH) ? mDynamicDepthConfigurations :
(dataspace == HAL_DATASPACE_HEIF) ? mHeicConfigurations :
(dataspace == HAL_DATASPACE_JPEG_R) ? mJpegRConfigurations :
+ isDataSpaceHeifUltraHDR ? mHeicUltraHDRConfigurations :
mConfigurations;
for (int i = 0; i < configurations.length; i++) {
@@ -1954,6 +2072,11 @@
* @hide
*/
public static String formatToString(int format) {
+ if (Flags.cameraHeifGainmap()) {
+ if (format == ImageFormat.HEIC_ULTRAHDR) {
+ return "HEIC_ULTRAHDR";
+ }
+ }
switch (format) {
case ImageFormat.YV12:
return "YV12";
@@ -2078,6 +2201,10 @@
private final StreamConfigurationDuration[] mHeicMinFrameDurations;
private final StreamConfigurationDuration[] mHeicStallDurations;
+ private final StreamConfiguration[] mHeicUltraHDRConfigurations;
+ private final StreamConfigurationDuration[] mHeicUltraHDRMinFrameDurations;
+ private final StreamConfigurationDuration[] mHeicUltraHDRStallDurations;
+
private final StreamConfiguration[] mJpegRConfigurations;
private final StreamConfigurationDuration[] mJpegRMinFrameDurations;
private final StreamConfigurationDuration[] mJpegRStallDurations;
@@ -2103,6 +2230,8 @@
private final SparseIntArray mDynamicDepthOutputFormats = new SparseIntArray();
/** internal format -> num heic output sizes mapping, for HAL_DATASPACE_HEIF */
private final SparseIntArray mHeicOutputFormats = new SparseIntArray();
+ /** internal format -> num heic output sizes mapping, for DATASPACE_HEIF_GAINMAP */
+ private final SparseIntArray mHeicUltraHDROutputFormats = new SparseIntArray();
/** internal format -> num Jpeg/R output sizes mapping, for HAL_DATASPACE_JPEG_R */
private final SparseIntArray mJpegROutputFormats = new SparseIntArray();
diff --git a/core/java/android/hardware/display/BrightnessInfo.java b/core/java/android/hardware/display/BrightnessInfo.java
index 6a96a54..529ee91 100644
--- a/core/java/android/hardware/display/BrightnessInfo.java
+++ b/core/java/android/hardware/display/BrightnessInfo.java
@@ -113,16 +113,24 @@
*/
public final int brightnessMaxReason;
+ /**
+ * Whether the current brightness value is overridden by the application window via
+ * {@link android.view.WindowManager.LayoutParams#screenBrightness}.
+ */
+ public final boolean isBrightnessOverrideByWindow;
+
public BrightnessInfo(float brightness, float brightnessMinimum, float brightnessMaximum,
@HighBrightnessMode int highBrightnessMode, float highBrightnessTransitionPoint,
@BrightnessMaxReason int brightnessMaxReason) {
this(brightness, brightness, brightnessMinimum, brightnessMaximum, highBrightnessMode,
- highBrightnessTransitionPoint, brightnessMaxReason);
+ highBrightnessTransitionPoint, brightnessMaxReason,
+ false /* isBrightnessOverrideByWindow */);
}
public BrightnessInfo(float brightness, float adjustedBrightness, float brightnessMinimum,
float brightnessMaximum, @HighBrightnessMode int highBrightnessMode,
- float highBrightnessTransitionPoint, @BrightnessMaxReason int brightnessMaxReason) {
+ float highBrightnessTransitionPoint, @BrightnessMaxReason int brightnessMaxReason,
+ boolean isBrightnessOverrideByWindow) {
this.brightness = brightness;
this.adjustedBrightness = adjustedBrightness;
this.brightnessMinimum = brightnessMinimum;
@@ -130,6 +138,7 @@
this.highBrightnessMode = highBrightnessMode;
this.highBrightnessTransitionPoint = highBrightnessTransitionPoint;
this.brightnessMaxReason = brightnessMaxReason;
+ this.isBrightnessOverrideByWindow = isBrightnessOverrideByWindow;
}
/**
@@ -178,6 +187,7 @@
dest.writeInt(highBrightnessMode);
dest.writeFloat(highBrightnessTransitionPoint);
dest.writeInt(brightnessMaxReason);
+ dest.writeBoolean(isBrightnessOverrideByWindow);
}
public static final @android.annotation.NonNull Creator<BrightnessInfo> CREATOR =
@@ -201,6 +211,7 @@
highBrightnessMode = source.readInt();
highBrightnessTransitionPoint = source.readFloat();
brightnessMaxReason = source.readInt();
+ isBrightnessOverrideByWindow = source.readBoolean();
}
}
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index a81bcbc..a452226 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -575,14 +575,22 @@
EVENT_FLAG_DISPLAY_ADDED,
EVENT_FLAG_DISPLAY_CHANGED,
EVENT_FLAG_DISPLAY_REMOVED,
- EVENT_FLAG_DISPLAY_BRIGHTNESS,
- EVENT_FLAG_HDR_SDR_RATIO_CHANGED,
- EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface EventFlag {}
/**
+ * @hide
+ */
+ @LongDef(flag = true, prefix = {"PRIVATE_EVENT_FLAG_"}, value = {
+ PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS,
+ PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED,
+ PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PrivateEventFlag {}
+
+ /**
* Event type for when a new display is added.
*
* @see #registerDisplayListener(DisplayListener, Handler, long)
@@ -618,7 +626,7 @@
*
* @hide
*/
- public static final long EVENT_FLAG_DISPLAY_BRIGHTNESS = 1L << 3;
+ public static final long PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS = 1L << 0;
/**
* Event flag to register for a display's hdr/sdr ratio changes. This notification is sent
@@ -631,14 +639,16 @@
*
* @hide
*/
- public static final long EVENT_FLAG_HDR_SDR_RATIO_CHANGED = 1L << 4;
+ public static final long PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED = 1L << 1;
/**
* Event flag to register for a display's connection changed.
*
+ * @see #registerDisplayListener(DisplayListener, Handler, long)
* @hide
*/
- public static final long EVENT_FLAG_DISPLAY_CONNECTION_CHANGED = 1L << 5;
+ public static final long PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED = 1L << 2;
+
/** @hide */
public DisplayManager(Context context) {
@@ -774,20 +784,49 @@
* @param listener The listener to register.
* @param handler The handler on which the listener should be invoked, or null
* if the listener should be invoked on the calling thread's looper.
- * @param eventFlagsMask A bitmask of the event types for which this listener is subscribed.
+ * @param eventFlags A bitmask of the event types for which this listener is subscribed.
*
* @see #EVENT_FLAG_DISPLAY_ADDED
* @see #EVENT_FLAG_DISPLAY_CHANGED
* @see #EVENT_FLAG_DISPLAY_REMOVED
- * @see #EVENT_FLAG_DISPLAY_BRIGHTNESS
* @see #registerDisplayListener(DisplayListener, Handler)
* @see #unregisterDisplayListener
*
* @hide
*/
public void registerDisplayListener(@NonNull DisplayListener listener,
- @Nullable Handler handler, @EventFlag long eventFlagsMask) {
- mGlobal.registerDisplayListener(listener, handler, eventFlagsMask,
+ @Nullable Handler handler, @EventFlag long eventFlags) {
+ mGlobal.registerDisplayListener(listener, handler,
+ mGlobal.mapFlagsToInternalEventFlag(eventFlags, 0),
+ ActivityThread.currentPackageName());
+ }
+
+ /**
+ * Registers a display listener to receive notifications about given display event types.
+ *
+ * @param listener The listener to register.
+ * @param handler The handler on which the listener should be invoked, or null
+ * if the listener should be invoked on the calling thread's looper.
+ * @param eventFlags A bitmask of the event types for which this listener is subscribed.
+ * @param privateEventFlags A bitmask of the private event types for which this listener
+ * is subscribed.
+ *
+ * @see #EVENT_FLAG_DISPLAY_ADDED
+ * @see #EVENT_FLAG_DISPLAY_CHANGED
+ * @see #EVENT_FLAG_DISPLAY_REMOVED
+ * @see #PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS
+ * @see #PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED
+ * @see #PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED
+ * @see #registerDisplayListener(DisplayListener, Handler)
+ * @see #unregisterDisplayListener
+ *
+ * @hide
+ */
+ public void registerDisplayListener(@NonNull DisplayListener listener,
+ @Nullable Handler handler, @EventFlag long eventFlags,
+ @PrivateEventFlag long privateEventFlags) {
+ mGlobal.registerDisplayListener(listener, handler,
+ mGlobal.mapFlagsToInternalEventFlag(eventFlags, privateEventFlags),
ActivityThread.currentPackageName());
}
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 3c6841c..644850a 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -24,6 +24,7 @@
import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntDef;
+import android.annotation.LongDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -118,6 +119,24 @@
public static final int EVENT_DISPLAY_CONNECTED = 6;
public static final int EVENT_DISPLAY_DISCONNECTED = 7;
+ @LongDef(prefix = {"INTERNAL_EVENT_DISPLAY"}, flag = true, value = {
+ INTERNAL_EVENT_FLAG_DISPLAY_ADDED,
+ INTERNAL_EVENT_FLAG_DISPLAY_CHANGED,
+ INTERNAL_EVENT_FLAG_DISPLAY_REMOVED,
+ INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED,
+ INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED,
+ INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface InternalEventFlag {}
+
+ public static final long INTERNAL_EVENT_FLAG_DISPLAY_ADDED = 1L << 0;
+ public static final long INTERNAL_EVENT_FLAG_DISPLAY_CHANGED = 1L << 1;
+ public static final long INTERNAL_EVENT_FLAG_DISPLAY_REMOVED = 1L << 2;
+ public static final long INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED = 1L << 3;
+ public static final long INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED = 1L << 4;
+ public static final long INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED = 1L << 5;
+
@UnsupportedAppUsage
private static DisplayManagerGlobal sInstance;
@@ -130,7 +149,7 @@
private final IDisplayManager mDm;
private DisplayManagerCallback mCallback;
- private @EventFlag long mRegisteredEventFlagsMask = 0;
+ private @InternalEventFlag long mRegisteredInternalEventFlag = 0;
private final CopyOnWriteArrayList<DisplayListenerDelegate> mDisplayListeners =
new CopyOnWriteArrayList<>();
@@ -346,11 +365,11 @@
* @param packageName of the calling package.
*/
public void registerDisplayListener(@NonNull DisplayListener listener,
- @Nullable Handler handler, @EventFlag long eventFlagsMask,
+ @Nullable Handler handler, @InternalEventFlag long internalEventFlagsMask,
String packageName) {
Looper looper = getLooperForHandler(handler);
Handler springBoard = new Handler(looper);
- registerDisplayListener(listener, new HandlerExecutor(springBoard), eventFlagsMask,
+ registerDisplayListener(listener, new HandlerExecutor(springBoard), internalEventFlagsMask,
packageName);
}
@@ -359,32 +378,34 @@
*
* @param listener The listener that will be called when display changes occur.
* @param executor Executor for the thread that will be receiving the callbacks. Cannot be null.
- * @param eventFlagsMask Flag of events to be listened to.
+ * @param internalEventFlagsMask Mask of events to be listened to.
* @param packageName of the calling package.
*/
public void registerDisplayListener(@NonNull DisplayListener listener,
- @NonNull Executor executor, @EventFlag long eventFlagsMask, String packageName) {
+ @NonNull Executor executor, @InternalEventFlag long internalEventFlagsMask,
+ String packageName) {
if (listener == null) {
throw new IllegalArgumentException("listener must not be null");
}
- if (eventFlagsMask == 0) {
+ if (internalEventFlagsMask == 0) {
throw new IllegalArgumentException("The set of events to listen to must not be empty.");
}
if (extraLogging()) {
Slog.i(TAG, "Registering Display Listener: "
- + Long.toBinaryString(eventFlagsMask) + ", packageName: " + packageName);
+ + Long.toBinaryString(internalEventFlagsMask)
+ + ", packageName: " + packageName);
}
synchronized (mLock) {
int index = findDisplayListenerLocked(listener);
if (index < 0) {
mDisplayListeners.add(new DisplayListenerDelegate(listener, executor,
- eventFlagsMask, packageName));
+ internalEventFlagsMask, packageName));
registerCallbackIfNeededLocked();
} else {
- mDisplayListeners.get(index).setEventFlagsMask(eventFlagsMask);
+ mDisplayListeners.get(index).setEventsMask(internalEventFlagsMask);
}
updateCallbackIfNeededLocked();
maybeLogAllDisplayListeners();
@@ -456,17 +477,17 @@
return -1;
}
- @EventFlag
- private int calculateEventFlagsMaskLocked() {
- int mask = 0;
+ @InternalEventFlag
+ private long calculateEventsMaskLocked() {
+ long mask = 0;
final int numListeners = mDisplayListeners.size();
for (int i = 0; i < numListeners; i++) {
- mask |= mDisplayListeners.get(i).mEventFlagsMask;
+ mask |= mDisplayListeners.get(i).mInternalEventFlagsMask;
}
if (mDispatchNativeCallbacks) {
- mask |= DisplayManager.EVENT_FLAG_DISPLAY_ADDED
- | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED;
+ mask |= INTERNAL_EVENT_FLAG_DISPLAY_ADDED
+ | INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
+ | INTERNAL_EVENT_FLAG_DISPLAY_REMOVED;
}
return mask;
}
@@ -479,14 +500,14 @@
}
private void updateCallbackIfNeededLocked() {
- int mask = calculateEventFlagsMaskLocked();
+ long mask = calculateEventsMaskLocked();
if (DEBUG) {
- Log.d(TAG, "Flag for listener: " + mask);
+ Log.d(TAG, "Mask for listener: " + mask);
}
- if (mask != mRegisteredEventFlagsMask) {
+ if (mask != mRegisteredInternalEventFlag) {
try {
mDm.registerCallbackWithEventMask(mCallback, mask);
- mRegisteredEventFlagsMask = mask;
+ mRegisteredInternalEventFlag = mask;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -1268,8 +1289,8 @@
@Override
public void onDisplayEvent(int displayId, @DisplayEvent int event) {
if (DEBUG) {
- Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + eventToString(
- event));
+ Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event="
+ + eventToString(event));
}
handleDisplayEvent(displayId, event, false /* forceUpdate */);
}
@@ -1277,7 +1298,7 @@
private static final class DisplayListenerDelegate {
public final DisplayListener mListener;
- public volatile long mEventFlagsMask;
+ public volatile long mInternalEventFlagsMask;
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private final Executor mExecutor;
@@ -1285,10 +1306,10 @@
private final String mPackageName;
DisplayListenerDelegate(DisplayListener listener, @NonNull Executor executor,
- @EventFlag long eventFlag, String packageName) {
+ @InternalEventFlag long internalEventFlag, String packageName) {
mExecutor = executor;
mListener = listener;
- mEventFlagsMask = eventFlag;
+ mInternalEventFlagsMask = internalEventFlag;
mPackageName = packageName;
}
@@ -1310,16 +1331,16 @@
mGenerationId.incrementAndGet();
}
- void setEventFlagsMask(@EventFlag long newEventsFlag) {
- mEventFlagsMask = newEventsFlag;
+ void setEventsMask(@InternalEventFlag long newInternalEventFlagsMask) {
+ mInternalEventFlagsMask = newInternalEventFlagsMask;
}
- private void handleDisplayEventInner(int displayId, @DisplayEvent int eventFlagsMask,
+ private void handleDisplayEventInner(int displayId, @DisplayEvent int event,
@Nullable DisplayInfo info, boolean forceUpdate) {
if (extraLogging()) {
- Slog.i(TAG, "DLD(" + eventToString(eventFlagsMask)
+ Slog.i(TAG, "DLD(" + eventToString(event)
+ ", display=" + displayId
- + ", mEventsFlagMask=" + Long.toBinaryString(mEventFlagsMask)
+ + ", mEventsMask=" + Long.toBinaryString(mInternalEventFlagsMask)
+ ", mPackageName=" + mPackageName
+ ", displayInfo=" + info
+ ", listener=" + mListener.getClass() + ")");
@@ -1327,18 +1348,19 @@
if (DEBUG) {
Trace.beginSection(
TextUtils.trimToSize(
- "DLD(" + eventToString(eventFlagsMask)
+ "DLD(" + eventToString(event)
+ ", display=" + displayId
+ ", listener=" + mListener.getClass() + ")", 127));
}
- switch (eventFlagsMask) {
+ switch (event) {
case EVENT_DISPLAY_ADDED:
- if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
+ if ((mInternalEventFlagsMask & INTERNAL_EVENT_FLAG_DISPLAY_ADDED) != 0) {
mListener.onDisplayAdded(displayId);
}
break;
case EVENT_DISPLAY_CHANGED:
- if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0) {
+ if ((mInternalEventFlagsMask & INTERNAL_EVENT_FLAG_DISPLAY_CHANGED)
+ != 0) {
if (info != null && (forceUpdate || !info.equals(mDisplayInfo))) {
if (extraLogging()) {
Slog.i(TAG, "Sending onDisplayChanged: Display Changed. Info: "
@@ -1350,29 +1372,32 @@
}
break;
case EVENT_DISPLAY_BRIGHTNESS_CHANGED:
- if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0) {
+ if ((mInternalEventFlagsMask
+ & INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED) != 0) {
mListener.onDisplayChanged(displayId);
}
break;
case EVENT_DISPLAY_REMOVED:
- if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0) {
+ if ((mInternalEventFlagsMask & INTERNAL_EVENT_FLAG_DISPLAY_REMOVED)
+ != 0) {
mListener.onDisplayRemoved(displayId);
}
break;
case EVENT_DISPLAY_HDR_SDR_RATIO_CHANGED:
- if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0) {
+ if ((mInternalEventFlagsMask
+ & INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED) != 0) {
mListener.onDisplayChanged(displayId);
}
break;
case EVENT_DISPLAY_CONNECTED:
- if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED)
- != 0) {
+ if ((mInternalEventFlagsMask
+ & INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
mListener.onDisplayConnected(displayId);
}
break;
case EVENT_DISPLAY_DISCONNECTED:
- if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED)
- != 0) {
+ if ((mInternalEventFlagsMask
+ & INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
mListener.onDisplayDisconnected(displayId);
}
break;
@@ -1384,7 +1409,7 @@
@Override
public String toString() {
- return "mEventFlagsMask: {" + mEventFlagsMask + "}, for " + mListener.getClass();
+ return "flag: {" + mInternalEventFlagsMask + "}, for " + mListener.getClass();
}
}
@@ -1432,6 +1457,13 @@
mExecutor.execute(mCallback::onStopped);
}
}
+
+ @Override // Binder call
+ public void onRequestedBrightnessChanged(float brightness) {
+ if (mCallback != null) {
+ mExecutor.execute(() -> mCallback.onRequestedBrightnessChanged(brightness));
+ }
+ }
}
/**
@@ -1525,4 +1557,53 @@
private static boolean extraLogging() {
return sExtraDisplayListenerLogging;
}
+
+
+ /**
+ * Maps the supplied public and private event flags to a unified InternalEventFlag
+ * @param eventFlags A bitmask of the event types for which this listener is subscribed.
+ * @param privateEventFlags A bitmask of the private event types for which this listener
+ * is subscribed.
+ * @return returns the bitmask of both public and private event flags unified to
+ * InternalEventFlag
+ */
+ public @InternalEventFlag long mapFlagsToInternalEventFlag(@EventFlag long eventFlags,
+ @DisplayManager.PrivateEventFlag long privateEventFlags) {
+ return mapPrivateEventFlags(privateEventFlags) | mapPublicEventFlags(eventFlags);
+ }
+
+ private long mapPrivateEventFlags(@DisplayManager.PrivateEventFlag long privateEventFlags) {
+ long baseEventMask = 0;
+ if ((privateEventFlags & DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0) {
+ baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED;
+ }
+
+ if ((privateEventFlags & DisplayManager.PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0) {
+ baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED;
+ }
+
+ if ((privateEventFlags
+ & DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
+ baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED;
+ }
+ return baseEventMask;
+ }
+
+ private long mapPublicEventFlags(@EventFlag long eventFlags) {
+ long baseEventMask = 0;
+ if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
+ baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_ADDED;
+ }
+
+ if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0) {
+ baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_CHANGED;
+ }
+
+ if ((eventFlags
+ & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0) {
+ baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_REMOVED;
+ }
+
+ return baseEventMask;
+ }
}
diff --git a/core/java/android/hardware/display/IVirtualDisplayCallback.aidl b/core/java/android/hardware/display/IVirtualDisplayCallback.aidl
index c3490d1..9cc0364 100644
--- a/core/java/android/hardware/display/IVirtualDisplayCallback.aidl
+++ b/core/java/android/hardware/display/IVirtualDisplayCallback.aidl
@@ -38,4 +38,9 @@
* of the application to release() the virtual display.
*/
void onStopped();
+
+ /**
+ * Called when the virtual display's requested brightness has changed.
+ */
+ void onRequestedBrightnessChanged(float brightness);
}
diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java
index 32b6405..3b573ea 100644
--- a/core/java/android/hardware/display/VirtualDisplay.java
+++ b/core/java/android/hardware/display/VirtualDisplay.java
@@ -16,6 +16,8 @@
package android.hardware.display;
import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.SystemApi;
import android.view.Display;
import android.view.Surface;
@@ -164,5 +166,25 @@
* of the application to release() the virtual display.
*/
public void onStopped() { }
+
+ /**
+ * Called when the requested brightness of the display has changed.
+ *
+ * <p>The system may adjust the display's brightness based on user or app activity. This
+ * callback will only be invoked if the display has an explicitly specified default
+ * brightness value.</p>
+ *
+ * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of
+ * {@code 1.0} indicates the maximum supported brightness.</p>
+ *
+ * @see android.view.View#setKeepScreenOn(boolean)
+ * @see android.view.WindowManager.LayoutParams#screenBrightness
+ * @see VirtualDisplayConfig.Builder#setDefaultBrightness(float)
+ * @hide
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
+ @SystemApi
+ public void onRequestedBrightnessChanged(
+ @FloatRange(from = 0.0f, to = 1.0f) float brightness) {}
}
}
diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java
index 49944c7..57d9d28 100644
--- a/core/java/android/hardware/display/VirtualDisplayConfig.java
+++ b/core/java/android/hardware/display/VirtualDisplayConfig.java
@@ -29,6 +29,7 @@
import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PowerManager;
import android.util.ArraySet;
import android.view.Display;
import android.view.DisplayCutout;
@@ -61,6 +62,7 @@
private final boolean mIsHomeSupported;
private final DisplayCutout mDisplayCutout;
private final boolean mIgnoreActivitySizeRestrictions;
+ private final float mDefaultBrightness;
private VirtualDisplayConfig(
@NonNull String name,
@@ -76,7 +78,8 @@
float requestedRefreshRate,
boolean isHomeSupported,
@Nullable DisplayCutout displayCutout,
- boolean ignoreActivitySizeRestrictions) {
+ boolean ignoreActivitySizeRestrictions,
+ @FloatRange(from = 0.0f, to = 1.0f) float defaultBrightness) {
mName = name;
mWidth = width;
mHeight = height;
@@ -91,6 +94,7 @@
mIsHomeSupported = isHomeSupported;
mDisplayCutout = displayCutout;
mIgnoreActivitySizeRestrictions = ignoreActivitySizeRestrictions;
+ mDefaultBrightness = defaultBrightness;
}
/**
@@ -157,6 +161,22 @@
}
/**
+ * Returns the default brightness of the display.
+ *
+ * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of {@code 1.0}
+ * indicates the maximum supported brightness.</p>
+ *
+ * @see Builder#setDefaultBrightness(float)
+ * @hide
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
+ @SystemApi
+ public @FloatRange(from = 0.0f, to = 1.0f) float getDefaultBrightness() {
+ return mDefaultBrightness;
+ }
+
+
+ /**
* Returns the unique identifier for the display. Shouldn't be displayed to the user.
* @hide
*/
@@ -245,6 +265,7 @@
dest.writeBoolean(mIsHomeSupported);
DisplayCutout.ParcelableWrapper.writeCutoutToParcel(mDisplayCutout, dest, flags);
dest.writeBoolean(mIgnoreActivitySizeRestrictions);
+ dest.writeFloat(mDefaultBrightness);
}
@Override
@@ -272,7 +293,8 @@
&& mRequestedRefreshRate == that.mRequestedRefreshRate
&& mIsHomeSupported == that.mIsHomeSupported
&& mIgnoreActivitySizeRestrictions == that.mIgnoreActivitySizeRestrictions
- && Objects.equals(mDisplayCutout, that.mDisplayCutout);
+ && Objects.equals(mDisplayCutout, that.mDisplayCutout)
+ && mDefaultBrightness == that.mDefaultBrightness;
}
@Override
@@ -281,7 +303,7 @@
mName, mWidth, mHeight, mDensityDpi, mFlags, mSurface, mUniqueId,
mDisplayIdToMirror, mWindowManagerMirroringEnabled, mDisplayCategories,
mRequestedRefreshRate, mIsHomeSupported, mDisplayCutout,
- mIgnoreActivitySizeRestrictions);
+ mIgnoreActivitySizeRestrictions, mDefaultBrightness);
return hashCode;
}
@@ -303,6 +325,7 @@
+ " mIsHomeSupported=" + mIsHomeSupported
+ " mDisplayCutout=" + mDisplayCutout
+ " mIgnoreActivitySizeRestrictions=" + mIgnoreActivitySizeRestrictions
+ + " mDefaultBrightness=" + mDefaultBrightness
+ ")";
}
@@ -321,6 +344,7 @@
mIsHomeSupported = in.readBoolean();
mDisplayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(in);
mIgnoreActivitySizeRestrictions = in.readBoolean();
+ mDefaultBrightness = in.readFloat();
}
@NonNull
@@ -355,6 +379,7 @@
private boolean mIsHomeSupported = false;
private DisplayCutout mDisplayCutout = null;
private boolean mIgnoreActivitySizeRestrictions = false;
+ private float mDefaultBrightness = 0.0f;
/**
* Creates a new Builder.
@@ -547,6 +572,35 @@
}
/**
+ * Sets the default brightness of the display.
+ *
+ * <p>The system will use this brightness value whenever the display should be bright, i.e.
+ * it is powered on and not dimmed due to user activity or app activity.</p>
+ *
+ * <p>Value of {@code 0.0} indicates the minimum supported brightness and value of
+ * {@code 1.0} indicates the maximum supported brightness.</p>
+ *
+ * <p>If unset, defaults to {@code 0.0}</p>
+ *
+ * @see android.view.View#setKeepScreenOn(boolean)
+ * @see Builder#setDefaultBrightness(float)
+ * @see VirtualDisplay.Callback#onRequestedBrightnessChanged(float)
+ * @hide
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
+ @SystemApi
+ @NonNull
+ public Builder setDefaultBrightness(@FloatRange(from = 0.0f, to = 1.0f) float brightness) {
+ if (brightness < PowerManager.BRIGHTNESS_MIN
+ || brightness > PowerManager.BRIGHTNESS_MAX) {
+ throw new IllegalArgumentException(
+ "Virtual display default brightness must be in range [0.0, 1.0]");
+ }
+ mDefaultBrightness = brightness;
+ return this;
+ }
+
+ /**
* Builds the {@link VirtualDisplayConfig} instance.
*/
@NonNull
@@ -565,7 +619,8 @@
mRequestedRefreshRate,
mIsHomeSupported,
mDisplayCutout,
- mIgnoreActivitySizeRestrictions);
+ mIgnoreActivitySizeRestrictions,
+ mDefaultBrightness);
}
}
}
diff --git a/core/java/android/hardware/input/AidlInputGestureData.aidl b/core/java/android/hardware/input/AidlInputGestureData.aidl
index 137f672..e33ec53 100644
--- a/core/java/android/hardware/input/AidlInputGestureData.aidl
+++ b/core/java/android/hardware/input/AidlInputGestureData.aidl
@@ -19,13 +19,26 @@
/** @hide */
@JavaDerive(equals=true)
parcelable AidlInputGestureData {
- int keycode;
- int modifierState;
- int gestureType;
+ Trigger trigger;
- // App launch parameters: Only set if gestureType is KEY_GESTURE_TYPE_LAUNCH_APPLICATION
+ int gestureType;
+ // App launch parameters (Only set if gestureType is LAUNCH_APPLICATION)
String appLaunchCategory;
String appLaunchRole;
String appLaunchPackageName;
String appLaunchClassName;
+
+ parcelable KeyTrigger {
+ int keycode;
+ int modifierState;
+ }
+
+ parcelable TouchpadGestureTrigger {
+ int gestureType;
+ }
+
+ union Trigger {
+ KeyTrigger key;
+ TouchpadGestureTrigger touchpadGesture;
+ }
}
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 39dddb7..3284761 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -266,19 +266,19 @@
@PermissionManuallyEnforced
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.MANAGE_KEY_GESTURES)")
- int addCustomInputGesture(in AidlInputGestureData data);
+ int addCustomInputGesture(int userId, in AidlInputGestureData data);
@PermissionManuallyEnforced
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.MANAGE_KEY_GESTURES)")
- int removeCustomInputGesture(in AidlInputGestureData data);
+ int removeCustomInputGesture(int userId, in AidlInputGestureData data);
@PermissionManuallyEnforced
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.MANAGE_KEY_GESTURES)")
- void removeAllCustomInputGestures();
+ void removeAllCustomInputGestures(int userId, int tag);
- AidlInputGestureData[] getCustomInputGestures();
+ AidlInputGestureData[] getCustomInputGestures(int userId, int tag);
AidlInputGestureData[] getAppLaunchBookmarks();
}
diff --git a/core/java/android/hardware/input/InputGestureData.java b/core/java/android/hardware/input/InputGestureData.java
index 5ab73ce..f41550f 100644
--- a/core/java/android/hardware/input/InputGestureData.java
+++ b/core/java/android/hardware/input/InputGestureData.java
@@ -35,20 +35,40 @@
*/
public final class InputGestureData {
+ public static final int TOUCHPAD_GESTURE_TYPE_UNKNOWN = 0;
+ public static final int TOUCHPAD_GESTURE_TYPE_THREE_FINGER_TAP = 1;
+
@NonNull
private final AidlInputGestureData mInputGestureData;
- public InputGestureData(AidlInputGestureData inputGestureData) {
+ public InputGestureData(@NonNull AidlInputGestureData inputGestureData) {
this.mInputGestureData = inputGestureData;
validate();
}
/** Returns the trigger information for this input gesture */
public Trigger getTrigger() {
- if (mInputGestureData.keycode != KeyEvent.KEYCODE_UNKNOWN) {
- return new KeyTrigger(mInputGestureData.keycode, mInputGestureData.modifierState);
+ switch (mInputGestureData.trigger.getTag()) {
+ case AidlInputGestureData.Trigger.Tag.key: {
+ AidlInputGestureData.KeyTrigger trigger = mInputGestureData.trigger.getKey();
+ if (trigger == null) {
+ throw new RuntimeException("InputGestureData is corrupted, null key trigger!");
+ }
+ return createKeyTrigger(trigger.keycode, trigger.modifierState);
+ }
+ case AidlInputGestureData.Trigger.Tag.touchpadGesture: {
+ AidlInputGestureData.TouchpadGestureTrigger trigger =
+ mInputGestureData.trigger.getTouchpadGesture();
+ if (trigger == null) {
+ throw new RuntimeException(
+ "InputGestureData is corrupted, null touchpad trigger!");
+ }
+ return createTouchpadTrigger(trigger.gestureType);
+ }
+ default:
+ throw new RuntimeException("InputGestureData is corrupted, invalid trigger type!");
+
}
- throw new RuntimeException("InputGestureData is corrupted, invalid trigger type!");
}
/** Returns the action to perform for this input gesture */
@@ -127,9 +147,15 @@
"No app launch data for system action launch application");
}
AidlInputGestureData data = new AidlInputGestureData();
+ data.trigger = new AidlInputGestureData.Trigger();
if (mTrigger instanceof KeyTrigger keyTrigger) {
- data.keycode = keyTrigger.getKeycode();
- data.modifierState = keyTrigger.getModifierState();
+ data.trigger.setKey(new AidlInputGestureData.KeyTrigger());
+ data.trigger.getKey().keycode = keyTrigger.getKeycode();
+ data.trigger.getKey().modifierState = keyTrigger.getModifierState();
+ } else if (mTrigger instanceof TouchpadTrigger touchpadTrigger) {
+ data.trigger.setTouchpadGesture(new AidlInputGestureData.TouchpadGestureTrigger());
+ data.trigger.getTouchpadGesture().gestureType =
+ touchpadTrigger.getTouchpadGestureType();
} else {
throw new IllegalArgumentException("Invalid trigger type!");
}
@@ -163,30 +189,12 @@
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InputGestureData that = (InputGestureData) o;
- return mInputGestureData.keycode == that.mInputGestureData.keycode
- && mInputGestureData.modifierState == that.mInputGestureData.modifierState
- && mInputGestureData.gestureType == that.mInputGestureData.gestureType
- && Objects.equals(mInputGestureData.appLaunchCategory, that.mInputGestureData.appLaunchCategory)
- && Objects.equals(mInputGestureData.appLaunchRole, that.mInputGestureData.appLaunchRole)
- && Objects.equals(mInputGestureData.appLaunchPackageName, that.mInputGestureData.appLaunchPackageName)
- && Objects.equals(mInputGestureData.appLaunchPackageName, that.mInputGestureData.appLaunchPackageName);
+ return Objects.equals(mInputGestureData, that.mInputGestureData);
}
@Override
public int hashCode() {
- int _hash = 1;
- _hash = 31 * _hash + mInputGestureData.keycode;
- _hash = 31 * _hash + mInputGestureData.modifierState;
- _hash = 31 * _hash + mInputGestureData.gestureType;
- _hash = 31 * _hash + (mInputGestureData.appLaunchCategory != null
- ? mInputGestureData.appLaunchCategory.hashCode() : 0);
- _hash = 31 * _hash + (mInputGestureData.appLaunchRole != null
- ? mInputGestureData.appLaunchRole.hashCode() : 0);
- _hash = 31 * _hash + (mInputGestureData.appLaunchPackageName != null
- ? mInputGestureData.appLaunchPackageName.hashCode() : 0);
- _hash = 31 * _hash + (mInputGestureData.appLaunchPackageName != null
- ? mInputGestureData.appLaunchPackageName.hashCode() : 0);
- return _hash;
+ return mInputGestureData.hashCode();
}
public interface Trigger {
@@ -197,6 +205,11 @@
return new KeyTrigger(keycode, modifierState);
}
+ /** Creates a input gesture trigger based on a touchpad gesture */
+ public static Trigger createTouchpadTrigger(int touchpadGestureType) {
+ return new TouchpadTrigger(touchpadGestureType);
+ }
+
/** Key based input gesture trigger */
public static class KeyTrigger implements Trigger {
private static final int SHORTCUT_META_MASK =
@@ -242,8 +255,76 @@
}
}
+ /** Touchpad based input gesture trigger */
+ public static class TouchpadTrigger implements Trigger {
+ private final int mTouchpadGestureType;
+
+ private TouchpadTrigger(int touchpadGestureType) {
+ if (touchpadGestureType != TOUCHPAD_GESTURE_TYPE_THREE_FINGER_TAP) {
+ throw new IllegalArgumentException(
+ "Invalid touchpadGestureType = " + touchpadGestureType);
+ }
+ mTouchpadGestureType = touchpadGestureType;
+ }
+
+ public int getTouchpadGestureType() {
+ return mTouchpadGestureType;
+ }
+
+ @Override
+ public String toString() {
+ return "TouchpadTrigger{" +
+ "mTouchpadGestureType=" + mTouchpadGestureType +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TouchpadTrigger that = (TouchpadTrigger) o;
+ return mTouchpadGestureType == that.mTouchpadGestureType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(mTouchpadGestureType);
+ }
+ }
+
/** Data for action to perform when input gesture is triggered */
public record Action(@KeyGestureEvent.KeyGestureType int keyGestureType,
@Nullable AppLaunchData appLaunchData) {
}
+
+ /** Filter definition for InputGestureData */
+ public enum Filter {
+ KEY(AidlInputGestureData.Trigger.Tag.key),
+ TOUCHPAD(AidlInputGestureData.Trigger.Tag.touchpadGesture);
+
+ @AidlInputGestureData.Trigger.Tag
+ private final int mTag;
+
+ Filter(@AidlInputGestureData.Trigger.Tag int tag) {
+ mTag = tag;
+ }
+
+ @Nullable
+ public static Filter of(@AidlInputGestureData.Trigger.Tag int tag) {
+ return switch (tag) {
+ case AidlInputGestureData.Trigger.Tag.key -> KEY;
+ case AidlInputGestureData.Trigger.Tag.touchpadGesture -> TOUCHPAD;
+ default -> null;
+ };
+ }
+
+ @AidlInputGestureData.Trigger.Tag
+ public int getTag() {
+ return mTag;
+ }
+
+ public boolean matches(@NonNull InputGestureData inputGestureData) {
+ return mTag == inputGestureData.mInputGestureData.trigger.getTag();
+ }
+ }
}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 2051dbe..f824192 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -34,6 +34,7 @@
import android.annotation.SuppressLint;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.annotation.UserHandleAware;
import android.annotation.UserIdInt;
import android.app.ActivityThread;
import android.compat.annotation.ChangeId;
@@ -1487,12 +1488,13 @@
*/
@RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
@CustomInputGestureResult
+ @UserHandleAware
public int addCustomInputGesture(@NonNull InputGestureData inputGestureData) {
if (!enableCustomizableInputGestures()) {
return CUSTOM_INPUT_GESTURE_RESULT_ERROR_OTHER;
}
try {
- return mIm.addCustomInputGesture(inputGestureData.getAidlData());
+ return mIm.addCustomInputGesture(mContext.getUserId(), inputGestureData.getAidlData());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1509,12 +1511,14 @@
*/
@RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
@CustomInputGestureResult
+ @UserHandleAware
public int removeCustomInputGesture(@NonNull InputGestureData inputGestureData) {
if (!enableCustomizableInputGestures()) {
return CUSTOM_INPUT_GESTURE_RESULT_ERROR_OTHER;
}
try {
- return mIm.removeCustomInputGesture(inputGestureData.getAidlData());
+ return mIm.removeCustomInputGesture(mContext.getUserId(),
+ inputGestureData.getAidlData());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1522,15 +1526,20 @@
/** Removes all custom input gestures
*
+ * @param filter for removing all gestures of a category. If {@code null}, all custom input
+ * gestures will be removed
+ *
* @hide
*/
@RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
- public void removeAllCustomInputGestures() {
+ @UserHandleAware
+ public void removeAllCustomInputGestures(@Nullable InputGestureData.Filter filter) {
if (!enableCustomizableInputGestures()) {
return;
}
try {
- mIm.removeAllCustomInputGestures();
+ mIm.removeAllCustomInputGestures(mContext.getUserId(),
+ filter == null ? -1 : filter.getTag());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1538,15 +1547,20 @@
/** Get all custom input gestures
*
+ * @param filter for fetching all gestures of a category. If {@code null}, then will return
+ * all custom input gestures
+ *
* @hide
*/
- public List<InputGestureData> getCustomInputGestures() {
+ @UserHandleAware
+ public List<InputGestureData> getCustomInputGestures(@Nullable InputGestureData.Filter filter) {
List<InputGestureData> result = new ArrayList<>();
if (!enableCustomizableInputGestures()) {
return result;
}
try {
- for (AidlInputGestureData data : mIm.getCustomInputGestures()) {
+ for (AidlInputGestureData data : mIm.getCustomInputGestures(mContext.getUserId(),
+ filter == null ? -1 : filter.getTag())) {
result.add(new InputGestureData(data));
}
} catch (RemoteException e) {
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index c456698..96f6ad1 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -30,6 +30,7 @@
import static com.android.hardware.input.Flags.touchpadTapDragging;
import static com.android.hardware.input.Flags.touchpadThreeFingerTapShortcut;
import static com.android.hardware.input.Flags.touchpadVisualizer;
+import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
import static com.android.input.flags.Flags.FLAG_KEYBOARD_REPEAT_KEYS;
import static com.android.input.flags.Flags.enableInputFilterRustImpl;
import static com.android.input.flags.Flags.keyboardRepeatKeys;
@@ -386,7 +387,7 @@
* @hide
*/
public static boolean isTouchpadThreeFingerTapShortcutFeatureFlagEnabled() {
- return enableCustomizableInputGestures() && touchpadThreeFingerTapShortcut();
+ return isCustomizableInputGesturesFeatureFlagEnabled() && touchpadThreeFingerTapShortcut();
}
/**
@@ -1132,4 +1133,18 @@
Settings.Secure.KEY_REPEAT_DELAY_MS, delayTimeMillis,
UserHandle.USER_CURRENT);
}
+
+ /**
+ * Whether "Customizable key gestures" feature flag is enabled.
+ *
+ * <p>
+ * ‘Customizable key gestures’ is a feature which allows users to customize key based
+ * shortcuts on the physical keyboard.
+ * </p>
+ *
+ * @hide
+ */
+ public static boolean isCustomizableInputGesturesFeatureFlagEnabled() {
+ return enableCustomizableInputGestures() && useKeyGestureEventHandler();
+ }
}
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index f9cb94a..38e32c6 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -141,7 +141,7 @@
flag {
name: "keyboard_a11y_shortcut_control"
namespace: "input"
- description: "Adds shortcuts to toggle and control a11y features"
+ description: "Adds shortcuts to toggle and control a11y keyboard features"
bug: "373458181"
}
@@ -165,3 +165,10 @@
description: "Turns three-finger touchpad taps into a customizable shortcut."
bug: "365063048"
}
+
+flag {
+ name: "enable_talkback_and_magnifier_key_gestures"
+ namespace: "input"
+ description: "Adds key gestures for talkback and magnifier"
+ bug: "375277034"
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/location/OWNERS b/core/java/android/hardware/location/OWNERS
index 747f909..340d6f2 100644
--- a/core/java/android/hardware/location/OWNERS
+++ b/core/java/android/hardware/location/OWNERS
@@ -9,4 +9,4 @@
yuhany@google.com
# ContextHub team
-per-file *ContextHub*,*NanoApp* = file:platform/system/chre:/OWNERS
+per-file Android.bp,*Hub*,*NanoApp* = file:platform/system/chre:/OWNERS
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index c6fd0ee..7745b03 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -1521,8 +1521,7 @@
private final boolean mAllowMultipleTriggers;
private final KeyphraseRecognitionExtra mKeyphrases[];
private final byte[] mData;
- @ModuleProperties.AudioCapabilities
- private final int mAudioCapabilities;
+ private final @ModuleProperties.AudioCapabilities int mAudioCapabilities;
/**
* Constructor for {@link RecognitionConfig} with {@code audioCapabilities} describes a
@@ -1535,11 +1534,12 @@
* @param keyphrases List of keyphrases in the sound model.
* @param data Opaque data for use by system applications who know about voice engine
* internals, typically during enrollment.
- * @param audioCapabilities Bit field encoding of the AudioCapabilities.
+ * @param audioCapabilities Bit field encoding of the AudioCapabilities. See
+ * {@link ModuleProperties.AudioCapabilities} for details.
*/
private RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
@Nullable KeyphraseRecognitionExtra[] keyphrases, @Nullable byte[] data,
- int audioCapabilities) {
+ @ModuleProperties.AudioCapabilities int audioCapabilities) {
this.mCaptureRequested = captureRequested;
this.mAllowMultipleTriggers = allowMultipleTriggers;
this.mKeyphrases = keyphrases != null ? keyphrases : new KeyphraseRecognitionExtra[0];
@@ -1617,8 +1617,11 @@
return mData;
}
- /** Bit field encoding of the AudioCapabilities supported by the firmware. */
- public int getAudioCapabilities() {
+ /**
+ * Bit field encoding of the AudioCapabilities supported by the firmware. See
+ * {@link ModuleProperties.AudioCapabilities} for details.
+ */
+ public @ModuleProperties.AudioCapabilities int getAudioCapabilities() {
return mAudioCapabilities;
}
@@ -1702,7 +1705,7 @@
private boolean mAllowMultipleTriggers;
@Nullable private KeyphraseRecognitionExtra[] mKeyphrases;
@Nullable private byte[] mData;
- private int mAudioCapabilities;
+ private @ModuleProperties.AudioCapabilities int mAudioCapabilities;
/**
* Constructs a new Builder with the default values.
@@ -1750,18 +1753,20 @@
* internals, typically during enrollment.
* @return the same Builder instance.
*/
- public @NonNull Builder setData(@Nullable byte[] data) {
- mData = data;
+ public @NonNull Builder setData(@NonNull byte[] data) {
+ mData = requireNonNull(data, "Data must not be null");
return this;
}
/**
* Sets the audio capabilities field.
* @param audioCapabilities The bit field encoding of the audio capabilities associated
- * with this recognition session.
+ * with this recognition session. See
+ * {@link ModuleProperties.AudioCapabilities} for details.
* @return the same Builder instance.
*/
- public @NonNull Builder setAudioCapabilities(int audioCapabilities) {
+ public @NonNull Builder setAudioCapabilities(
+ @ModuleProperties.AudioCapabilities int audioCapabilities) {
mAudioCapabilities = audioCapabilities;
return this;
}
diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig
index 1adefe5..1b2c575 100644
--- a/core/java/android/net/vcn/flags.aconfig
+++ b/core/java/android/net/vcn/flags.aconfig
@@ -18,13 +18,6 @@
}
flag {
- name: "safe_mode_timeout_config"
- namespace: "vcn"
- description: "Feature flag for adjustable safe mode timeout"
- bug: "317406085"
-}
-
-flag {
name: "fix_config_garbage_collection"
namespace: "vcn"
description: "Handle race condition in subscription change"
diff --git a/core/java/android/os/AggregateBatteryConsumer.java b/core/java/android/os/AggregateBatteryConsumer.java
index c7f8878..f0e12ca 100644
--- a/core/java/android/os/AggregateBatteryConsumer.java
+++ b/core/java/android/os/AggregateBatteryConsumer.java
@@ -85,7 +85,7 @@
throw new XmlPullParserException("Invalid XML parser state");
}
- consumerBuilder.setConsumedPower(
+ consumerBuilder.addConsumedPower(
parser.getAttributeDouble(null, BatteryUsageStats.XML_ATTR_POWER));
while (!(eventType == XmlPullParser.END_TAG && parser.getName().equals(
@@ -132,11 +132,19 @@
}
/**
+ * Adds the total power included in this aggregate.
+ */
+ public Builder addConsumedPower(double consumedPowerMah) {
+ mData.putDouble(COLUMN_INDEX_CONSUMED_POWER,
+ mData.getDouble(COLUMN_INDEX_CONSUMED_POWER) + consumedPowerMah);
+ return this;
+ }
+
+ /**
* Adds power and usage duration from the supplied AggregateBatteryConsumer.
*/
public void add(AggregateBatteryConsumer aggregateBatteryConsumer) {
- setConsumedPower(mData.getDouble(COLUMN_INDEX_CONSUMED_POWER)
- + aggregateBatteryConsumer.getConsumedPower());
+ addConsumedPower(aggregateBatteryConsumer.getConsumedPower());
mPowerComponentsBuilder.addPowerAndDuration(aggregateBatteryConsumer.mPowerComponents);
}
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index b0ecca7..14b67f6 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -1064,7 +1064,9 @@
* @param componentId The ID of the power component, e.g.
* {@link BatteryConsumer#POWER_COMPONENT_CPU}.
* @param componentPower Amount of consumed power in mAh.
+ * @deprecated use {@link #addConsumedPower}
*/
+ @Deprecated
@NonNull
public T setConsumedPower(@PowerComponentId int componentId, double componentPower) {
return setConsumedPower(componentId, componentPower, POWER_MODEL_POWER_PROFILE);
@@ -1076,7 +1078,9 @@
* @param componentId The ID of the power component, e.g.
* {@link BatteryConsumer#POWER_COMPONENT_CPU}.
* @param componentPower Amount of consumed power in mAh.
+ * @deprecated use {@link #addConsumedPower}
*/
+ @Deprecated
@SuppressWarnings("unchecked")
@NonNull
public T setConsumedPower(@PowerComponentId int componentId, double componentPower,
@@ -1104,6 +1108,21 @@
@SuppressWarnings("unchecked")
@NonNull
+ public T addConsumedPower(@PowerComponentId int componentId, double componentPower) {
+ mPowerComponentsBuilder.addConsumedPower(getKey(componentId, PROCESS_STATE_UNSPECIFIED),
+ componentPower, POWER_MODEL_UNDEFINED);
+ return (T) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ @NonNull
+ public T addConsumedPower(Key key, double componentPower) {
+ mPowerComponentsBuilder.addConsumedPower(key, componentPower, POWER_MODEL_UNDEFINED);
+ return (T) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ @NonNull
public T addConsumedPower(Key key, double componentPower, @PowerModel int powerModel) {
mPowerComponentsBuilder.addConsumedPower(key, componentPower, powerModel);
return (T) this;
@@ -1115,7 +1134,9 @@
* @param componentId The ID of the power component, e.g.
* {@link UidBatteryConsumer#POWER_COMPONENT_CPU}.
* @param componentUsageTimeMillis Amount of time in microseconds.
+ * @deprecated use {@link #addUsageDurationMillis}
*/
+ @Deprecated
@SuppressWarnings("unchecked")
@NonNull
public T setUsageDurationMillis(@PowerComponentId int componentId,
@@ -1126,6 +1147,7 @@
return (T) this;
}
+ @Deprecated
@SuppressWarnings("unchecked")
@NonNull
public T setUsageDurationMillis(Key key, long componentUsageTimeMillis) {
@@ -1133,6 +1155,14 @@
return (T) this;
}
+ @NonNull
+ public T addUsageDurationMillis(@PowerComponentId int componentId,
+ long componentUsageTimeMillis) {
+ mPowerComponentsBuilder.addUsageDurationMillis(
+ getKey(componentId, PROCESS_STATE_UNSPECIFIED), componentUsageTimeMillis);
+ return (T) this;
+ }
+
@SuppressWarnings("unchecked")
@NonNull
public T addUsageDurationMillis(Key key, long componentUsageTimeMillis) {
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index 5ae425f..72e4cef 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -209,7 +209,7 @@
}
builder.getAggregateBatteryConsumerBuilder(AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
- .setConsumedPower(totalPowerMah);
+ .addConsumedPower(totalPowerMah);
mAggregateBatteryConsumers =
new AggregateBatteryConsumer[AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT];
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index b3aebad..102bdd0 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1565,6 +1565,61 @@
/** A string that uniquely identifies this build. Do not attempt to parse this value. */
public static final String FINGERPRINT = deriveFingerprint();
+ /** The status of the known issue on this device is not known. */
+ @FlaggedApi(android.os.Flags.FLAG_API_FOR_BACKPORTED_FIXES)
+ public static final int BACKPORTED_FIX_STATUS_UNKNOWN = 0;
+ /** The known issue is fixed on this device. */
+ @FlaggedApi(android.os.Flags.FLAG_API_FOR_BACKPORTED_FIXES)
+ public static final int BACKPORTED_FIX_STATUS_FIXED = 1;
+ /**
+ * The known issue is not applicable to this device.
+ *
+ * <p>For example if the issue only affects a specific brand, devices
+ * from other brands would report not applicable.
+ */
+ @FlaggedApi(android.os.Flags.FLAG_API_FOR_BACKPORTED_FIXES)
+ public static final int BACKPORTED_FIX_STATUS_NOT_APPLICABLE = 2;
+ /** The known issue is not fixed on this device. */
+ @FlaggedApi(android.os.Flags.FLAG_API_FOR_BACKPORTED_FIXES)
+ public static final int BACKPORTED_FIX_STATUS_NOT_FIXED = 3;
+
+ /**
+ * The status of the backported fix for a known issue on this device.
+ *
+ * @hide
+ */
+ @IntDef(
+ prefix = {"BACKPORTED_FIX_STATUS_"},
+ value = {
+ BACKPORTED_FIX_STATUS_UNKNOWN,
+ BACKPORTED_FIX_STATUS_FIXED,
+ BACKPORTED_FIX_STATUS_NOT_APPLICABLE,
+ BACKPORTED_FIX_STATUS_NOT_FIXED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface BackportedFixStatus {
+ }
+
+ /**
+ * The status of the backported fix for a known issue on this device.
+ *
+ * @param id The id of the known issue to check.
+ * @return {@link #BACKPORTED_FIX_STATUS_FIXED} if the known issue is
+ * fixed on this device,
+ * {@link #BACKPORTED_FIX_STATUS_NOT_FIXED} if the known issue is not
+ * fixed on this device,
+ * {@link #BACKPORTED_FIX_STATUS_NOT_APPLICABLE} if the known issue is
+ * is not applicable on this device,
+ * otherwise {@link #BACKPORTED_FIX_STATUS_UNKNOWN}.
+ */
+
+ @FlaggedApi(android.os.Flags.FLAG_API_FOR_BACKPORTED_FIXES)
+ public static @BackportedFixStatus int getBackportedFixStatus(long id) {
+ // TODO: b/308461809 - query aliases from system prop
+ // TODO: b/372518979 - use backported fix datastore.
+ return BACKPORTED_FIX_STATUS_UNKNOWN;
+ }
+
/**
* Some devices split the fingerprint components between multiple
* partitions, so we might derive the fingerprint at runtime.
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 66f4198..acda0c5 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -93,9 +93,7 @@
* system processes and provides a higher level of concurrency and higher enqueue throughput
* than the legacy implementation.
*/
- private static boolean sUseConcurrent;
-
- private static boolean sUseConcurrentInitialized = false;
+ private boolean mUseConcurrent;
@RavenwoodRedirect
private native static long nativeInit();
@@ -112,10 +110,7 @@
private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
MessageQueue(boolean quitAllowed) {
- if (!sUseConcurrentInitialized) {
- sUseConcurrent = UserHandle.isCore(Process.myUid());
- sUseConcurrentInitialized = true;
- }
+ mUseConcurrent = UserHandle.isCore(Process.myUid());
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
}
@@ -158,7 +153,7 @@
* @return True if the looper is idle.
*/
public boolean isIdle() {
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
final long now = SystemClock.uptimeMillis();
if (stackHasMessages(null, 0, null, null, now, mMatchDeliverableMessages, false)) {
@@ -208,7 +203,7 @@
if (handler == null) {
throw new NullPointerException("Can't add a null IdleHandler");
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
synchronized (mIdleHandlersLock) {
mIdleHandlers.add(handler);
}
@@ -229,7 +224,7 @@
* @param handler The IdleHandler to be removed.
*/
public void removeIdleHandler(@NonNull IdleHandler handler) {
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
synchronized (mIdleHandlersLock) {
mIdleHandlers.remove(handler);
}
@@ -252,7 +247,7 @@
* @hide
*/
public boolean isPolling() {
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
// If the loop is quitting then it must not be idling.
// We can assume mPtr != 0 when sQuitting is false.
return !((boolean) sQuitting.getVolatile(this)) && nativeIsPolling(mPtr);
@@ -303,7 +298,7 @@
throw new IllegalArgumentException("listener must not be null");
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
synchronized (mFileDescriptorRecordsLock) {
updateOnFileDescriptorEventListenerLocked(fd, events, listener);
}
@@ -331,7 +326,7 @@
if (fd == null) {
throw new IllegalArgumentException("fd must not be null");
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
synchronized (mFileDescriptorRecordsLock) {
updateOnFileDescriptorEventListenerLocked(fd, 0, null);
}
@@ -388,7 +383,7 @@
final int oldWatchedEvents;
final OnFileDescriptorEventListener listener;
final int seq;
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
synchronized (mFileDescriptorRecordsLock) {
record = mFileDescriptorRecords.get(fd);
if (record == null) {
@@ -431,13 +426,26 @@
// Update the file descriptor record if the listener changed the set of
// events to watch and the listener itself hasn't been updated since.
if (newWatchedEvents != oldWatchedEvents) {
- synchronized (this) {
- int index = mFileDescriptorRecords.indexOfKey(fd);
- if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
- && record.mSeq == seq) {
- record.mEvents = newWatchedEvents;
- if (newWatchedEvents == 0) {
- mFileDescriptorRecords.removeAt(index);
+ if (mUseConcurrent) {
+ synchronized (mFileDescriptorRecordsLock) {
+ int index = mFileDescriptorRecords.indexOfKey(fd);
+ if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
+ && record.mSeq == seq) {
+ record.mEvents = newWatchedEvents;
+ if (newWatchedEvents == 0) {
+ mFileDescriptorRecords.removeAt(index);
+ }
+ }
+ }
+ } else {
+ synchronized (this) {
+ int index = mFileDescriptorRecords.indexOfKey(fd);
+ if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
+ && record.mSeq == seq) {
+ record.mEvents = newWatchedEvents;
+ if (newWatchedEvents == 0) {
+ mFileDescriptorRecords.removeAt(index);
+ }
}
}
}
@@ -708,7 +716,7 @@
@UnsupportedAppUsage
Message next() {
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
return nextConcurrent();
}
@@ -834,7 +842,7 @@
throw new IllegalStateException("Main thread not allowed to quit.");
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
synchronized (mIdleHandlersLock) {
if (sQuitting.compareAndSet(this, false, true)) {
if (safe) {
@@ -898,7 +906,7 @@
private int postSyncBarrier(long when) {
// Enqueue a new sync barrier token.
// We don't need to wake the queue because the purpose of a barrier is to stall it.
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
final int token = mNextBarrierTokenAtomic.getAndIncrement();
// b/376573804: apps and tests may expect to be able to use reflection
@@ -991,7 +999,7 @@
public void removeSyncBarrier(int token) {
// Remove a sync barrier token from the queue.
// If the queue is no longer stalled by a barrier then wake it.
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
boolean removed;
MessageNode first;
final MatchBarrierToken matchBarrierToken = new MatchBarrierToken(token);
@@ -1058,7 +1066,7 @@
throw new IllegalArgumentException("Message must have a target.");
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
@@ -1187,7 +1195,7 @@
if (h == null) {
return false;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject,
false);
}
@@ -1219,7 +1227,7 @@
if (h == null) {
return false;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals,
false);
@@ -1253,7 +1261,7 @@
if (h == null) {
return false;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
return findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject,
false);
}
@@ -1285,7 +1293,7 @@
if (h == null) {
return false;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
return findOrRemoveMessages(h, -1, null, null, 0, mMatchHandler, false);
}
synchronized (this) {
@@ -1304,7 +1312,7 @@
if (h == null) {
return;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, true);
return;
}
@@ -1355,7 +1363,7 @@
return;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals, true);
return;
}
@@ -1407,7 +1415,7 @@
return;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, true);
return;
}
@@ -1470,7 +1478,7 @@
return;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObjectEquals, true);
return;
}
@@ -1532,7 +1540,7 @@
return;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObject, true);
return;
}
@@ -1594,7 +1602,7 @@
return;
}
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObjectEquals, true);
return;
}
@@ -1742,7 +1750,7 @@
@NeverCompile
void dump(Printer pw, String prefix, Handler h) {
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
long now = SystemClock.uptimeMillis();
int n = 0;
@@ -1803,7 +1811,7 @@
@NeverCompile
void dumpDebug(ProtoOutputStream proto, long fieldId) {
- if (sUseConcurrent) {
+ if (mUseConcurrent) {
final long messageQueueToken = proto.start(fieldId);
StackNode node = (StackNode) sState.getVolatile(this);
diff --git a/core/java/android/os/IThermalHeadroomListener.aidl b/core/java/android/os/IThermalHeadroomListener.aidl
new file mode 100644
index 0000000..b2797d8
--- /dev/null
+++ b/core/java/android/os/IThermalHeadroomListener.aidl
@@ -0,0 +1,31 @@
+/*
+** Copyright 2024, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT 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.os;
+
+/**
+ * Listener for thermal headroom and threshold changes.
+ * This is mainly used by {@link android.os.PowerManager} to serve public thermal headoom related
+ * APIs.
+ * {@hide}
+ */
+oneway interface IThermalHeadroomListener {
+ /**
+ * Called when thermal headroom or thresholds changed.
+ */
+ void onHeadroomChange(in float headroom, in float forecastHeadroom,
+ in int forecastSeconds, in float[] thresholds);
+}
diff --git a/core/java/android/os/IThermalService.aidl b/core/java/android/os/IThermalService.aidl
index bcffa45..aa3bcfa 100644
--- a/core/java/android/os/IThermalService.aidl
+++ b/core/java/android/os/IThermalService.aidl
@@ -18,6 +18,7 @@
import android.os.CoolingDevice;
import android.os.IThermalEventListener;
+import android.os.IThermalHeadroomListener;
import android.os.IThermalStatusListener;
import android.os.Temperature;
@@ -116,4 +117,20 @@
* @return thermal headroom for each thermal status
*/
float[] getThermalHeadroomThresholds();
+
+ /**
+ * Register a listener for thermal headroom change.
+ * @param listener the {@link android.os.IThermalHeadroomListener} to be notified.
+ * @return true if registered successfully.
+ * {@hide}
+ */
+ boolean registerThermalHeadroomListener(in IThermalHeadroomListener listener);
+
+ /**
+ * Unregister a previously-registered listener for thermal headroom.
+ * @param listener the {@link android.os.IThermalHeadroomListener} to no longer be notified.
+ * @return true if unregistered successfully.
+ * {@hide}
+ */
+ boolean unregisterThermalHeadroomListener(in IThermalHeadroomListener listener);
}
diff --git a/core/java/android/os/IVibratorManagerService.aidl b/core/java/android/os/IVibratorManagerService.aidl
index 6aa9852..ecb5e6f 100644
--- a/core/java/android/os/IVibratorManagerService.aidl
+++ b/core/java/android/os/IVibratorManagerService.aidl
@@ -17,13 +17,17 @@
package android.os;
import android.os.CombinedVibration;
+import android.os.ICancellationSignal;
import android.os.IVibratorStateListener;
import android.os.VibrationAttributes;
import android.os.VibratorInfo;
+import android.os.vibrator.IVibrationSession;
+import android.os.vibrator.IVibrationSessionCallback;
/** {@hide} */
interface IVibratorManagerService {
int[] getVibratorIds();
+ int getCapabilities();
VibratorInfo getVibratorInfo(int vibratorId);
@EnforcePermission("ACCESS_VIBRATOR_STATE")
boolean isVibrating(int vibratorId);
@@ -50,4 +54,9 @@
oneway void performHapticFeedbackForInputDevice(int uid, int deviceId, String opPkg,
int constant, int inputDeviceId, int inputSource, String reason, int flags,
int privFlags);
+
+ @EnforcePermission(allOf={"VIBRATE", "VIBRATE_VENDOR_EFFECTS", "START_VIBRATION_SESSIONS"})
+ ICancellationSignal startVendorVibrationSession(int uid, int deviceId, String opPkg,
+ in int[] vibratorIds, in VibrationAttributes attributes, String reason,
+ in IVibrationSessionCallback callback);
}
diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java
index f4e3f3b..d116e07 100644
--- a/core/java/android/os/PowerComponents.java
+++ b/core/java/android/os/PowerComponents.java
@@ -439,8 +439,8 @@
}
final BatteryConsumer.Key key = builder.mData.layout.getKey(componentId,
processState, screenState, powerState);
- builder.setConsumedPower(key, powerMah, model);
- builder.setUsageDurationMillis(key, durationMs);
+ builder.addConsumedPower(key, powerMah, model);
+ builder.addUsageDurationMillis(key, durationMs);
break;
}
}
@@ -468,6 +468,10 @@
}
}
+ /**
+ * @deprecated use {@link #addConsumedPower(BatteryConsumer.Key, double, int)}
+ */
+ @Deprecated
@NonNull
public Builder setConsumedPower(BatteryConsumer.Key key, double componentPower,
int powerModel) {
@@ -489,6 +493,10 @@
return this;
}
+ /**
+ * @deprecated use {@link #addUsageDurationMillis(BatteryConsumer.Key, long)}
+ */
+ @Deprecated
@NonNull
public Builder setUsageDurationMillis(BatteryConsumer.Key key,
long componentUsageDurationMillis) {
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 9d4ac29..07fded1 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -20,6 +20,7 @@
import android.annotation.CallbackExecutor;
import android.annotation.CurrentTimeMillisLong;
import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -40,6 +41,7 @@
import android.util.proto.ProtoOutputStream;
import android.view.Display;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import java.lang.annotation.ElementType;
@@ -1199,10 +1201,12 @@
/** We lazily initialize it.*/
private PowerExemptionManager mPowerExemptionManager;
+ @GuardedBy("mThermalStatusListenerMap")
private final ArrayMap<OnThermalStatusChangedListener, IThermalStatusListener>
- mListenerMap = new ArrayMap<>();
- private final Object mThermalHeadroomThresholdsLock = new Object();
- private float[] mThermalHeadroomThresholds = null;
+ mThermalStatusListenerMap = new ArrayMap<>();
+ @GuardedBy("mThermalHeadroomListenerMap")
+ private final ArrayMap<OnThermalHeadroomChangedListener, IThermalHeadroomListener>
+ mThermalHeadroomListenerMap = new ArrayMap<>();
/**
* {@hide}
@@ -2689,15 +2693,59 @@
void onThermalStatusChanged(@ThermalStatus int status);
}
+ /**
+ * Listener passed to
+ * {@link PowerManager#addThermalHeadroomListener} and
+ * {@link PowerManager#removeThermalHeadroomListener}
+ * to notify caller of Thermal headroom or thresholds changes.
+ */
+ @FlaggedApi(Flags.FLAG_ALLOW_THERMAL_THRESHOLDS_CALLBACK)
+ public interface OnThermalHeadroomChangedListener {
+
+ /**
+ * Called when overall thermal headroom or headroom thresholds have significantly
+ * changed that requires action.
+ * <p>
+ * This may not be used to fully replace the {@link #getThermalHeadroom(int)} API as it will
+ * only notify on one of the conditions below that will significantly change one or both
+ * values of current headroom and headroom thresholds since previous callback:
+ * 1. thermal throttling events: when the skin temperature has cross any of the thresholds
+ * and there isn't a previous callback in a short time ago with similar values.
+ * 2. skin temperature threshold change events: note that if the absolute °C threshold
+ * values change in a way that does not significantly change the current headroom nor
+ * headroom thresholds, it will not trigger any callback. The client should not
+ * need to take action in such case since the difference from temperature vs threshold
+ * hasn't changed.
+ * <p>
+ * By API version 36, it provides a forecast in the same call for developer's convenience
+ * based on a {@code forecastSeconds} defined by the device, which can be static or dynamic
+ * varied by OEM. Be aware that it will not notify on forecast temperature change but the
+ * events mentioned above. So periodically polling against {@link #getThermalHeadroom(int)}
+ * API should still be used to actively monitor temperature forecast in advance.
+ * <p>
+ * This serves as a more advanced option compared to thermal status listener, where the
+ * latter will only notify on thermal throttling events with status update.
+ *
+ * @param headroom current headroom
+ * @param forecastHeadroom forecasted headroom in future
+ * @param forecastSeconds how many seconds in the future used in forecast
+ * @param thresholds new headroom thresholds, see {@link #getThermalHeadroomThresholds()}
+ */
+ void onThermalHeadroomChanged(
+ @FloatRange(from = 0f) float headroom,
+ @FloatRange(from = 0f) float forecastHeadroom,
+ @IntRange(from = 0) int forecastSeconds,
+ @NonNull Map<@ThermalStatus Integer, Float> thresholds);
+ }
/**
- * This function adds a listener for thermal status change, listen call back will be
+ * This function adds a listener for thermal status change, listener callback will be
* enqueued tasks on the main thread
*
* @param listener listener to be added,
*/
public void addThermalStatusListener(@NonNull OnThermalStatusChangedListener listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
+ Objects.requireNonNull(listener, "Thermal status listener cannot be null");
addThermalStatusListener(mContext.getMainExecutor(), listener);
}
@@ -2709,29 +2757,31 @@
*/
public void addThermalStatusListener(@NonNull @CallbackExecutor Executor executor,
@NonNull OnThermalStatusChangedListener listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
- Objects.requireNonNull(executor, "executor cannot be null");
- Preconditions.checkArgument(!mListenerMap.containsKey(listener),
- "Listener already registered: %s", listener);
- IThermalStatusListener internalListener = new IThermalStatusListener.Stub() {
- @Override
- public void onStatusChange(int status) {
- final long token = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> listener.onThermalStatusChanged(status));
- } finally {
- Binder.restoreCallingIdentity(token);
+ Objects.requireNonNull(listener, "Thermal status listener cannot be null");
+ Objects.requireNonNull(executor, "Executor cannot be null");
+ synchronized (mThermalStatusListenerMap) {
+ Preconditions.checkArgument(!mThermalStatusListenerMap.containsKey(listener),
+ "Thermal status listener already registered: %s", listener);
+ IThermalStatusListener internalListener = new IThermalStatusListener.Stub() {
+ @Override
+ public void onStatusChange(int status) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> listener.onThermalStatusChanged(status));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
+ };
+ try {
+ if (mThermalService.registerThermalStatusListener(internalListener)) {
+ mThermalStatusListenerMap.put(listener, internalListener);
+ } else {
+ throw new RuntimeException("Thermal status listener failed to set");
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- };
- try {
- if (mThermalService.registerThermalStatusListener(internalListener)) {
- mListenerMap.put(listener, internalListener);
- } else {
- throw new RuntimeException("Listener failed to set");
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
}
}
@@ -2741,20 +2791,101 @@
* @param listener listener to be removed
*/
public void removeThermalStatusListener(@NonNull OnThermalStatusChangedListener listener) {
- Objects.requireNonNull(listener, "listener cannot be null");
- IThermalStatusListener internalListener = mListenerMap.get(listener);
- Preconditions.checkArgument(internalListener != null, "Listener was not added");
- try {
- if (mThermalService.unregisterThermalStatusListener(internalListener)) {
- mListenerMap.remove(listener);
- } else {
- throw new RuntimeException("Listener failed to remove");
+ Objects.requireNonNull(listener, "Thermal status listener cannot be null");
+ synchronized (mThermalStatusListenerMap) {
+ IThermalStatusListener internalListener = mThermalStatusListenerMap.get(listener);
+ Preconditions.checkArgument(internalListener != null,
+ "Thermal status listener was not added");
+ try {
+ if (mThermalService.unregisterThermalStatusListener(internalListener)) {
+ mThermalStatusListenerMap.remove(listener);
+ } else {
+ throw new RuntimeException("Failed to unregister thermal status listener");
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
}
}
+ /**
+ * This function adds a listener for thermal headroom change, listener callback will be
+ * enqueued tasks on the main thread
+ *
+ * @param listener listener to be added,
+ */
+ @FlaggedApi(Flags.FLAG_ALLOW_THERMAL_THRESHOLDS_CALLBACK)
+ public void addThermalHeadroomListener(@NonNull OnThermalHeadroomChangedListener listener) {
+ Objects.requireNonNull(listener, "Thermal headroom listener cannot be null");
+ addThermalHeadroomListener(mContext.getMainExecutor(), listener);
+ }
+
+ /**
+ * This function adds a listener for thermal headroom change.
+ *
+ * @param executor {@link Executor} to handle listener callback.
+ * @param listener listener to be added.
+ */
+ @FlaggedApi(Flags.FLAG_ALLOW_THERMAL_THRESHOLDS_CALLBACK)
+ public void addThermalHeadroomListener(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OnThermalHeadroomChangedListener listener) {
+ Objects.requireNonNull(listener, "Thermal headroom listener cannot be null");
+ Objects.requireNonNull(executor, "Executor cannot be null");
+ synchronized (mThermalHeadroomListenerMap) {
+ Preconditions.checkArgument(!mThermalHeadroomListenerMap.containsKey(listener),
+ "Thermal headroom listener already registered: %s", listener);
+ IThermalHeadroomListener internalListener = new IThermalHeadroomListener.Stub() {
+ @Override
+ public void onHeadroomChange(float headroom, float forecastHeadroom,
+ int forecastSeconds, float[] thresholds)
+ throws RemoteException {
+ final Map<Integer, Float> map = convertThresholdsToMap(thresholds);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> listener.onThermalHeadroomChanged(headroom,
+ forecastHeadroom, forecastSeconds, map));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ };
+ try {
+ if (mThermalService.registerThermalHeadroomListener(internalListener)) {
+ mThermalHeadroomListenerMap.put(listener, internalListener);
+ } else {
+ throw new RuntimeException("Thermal headroom listener failed to set");
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * This function removes a listener for Thermal headroom change
+ *
+ * @param listener listener to be removed
+ */
+ @FlaggedApi(Flags.FLAG_ALLOW_THERMAL_THRESHOLDS_CALLBACK)
+ public void removeThermalHeadroomListener(@NonNull OnThermalHeadroomChangedListener listener) {
+ Objects.requireNonNull(listener, "Thermal headroom listener cannot be null");
+ synchronized (mThermalHeadroomListenerMap) {
+ IThermalHeadroomListener internalListener = mThermalHeadroomListenerMap.get(listener);
+ Preconditions.checkArgument(internalListener != null,
+ "Thermal headroom listener was not added");
+ try {
+ if (mThermalService.unregisterThermalHeadroomListener(internalListener)) {
+ mThermalHeadroomListenerMap.remove(listener);
+ } else {
+ throw new RuntimeException("Failed to unregister thermal status listener");
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+
@CurrentTimeMillisLong
private final AtomicLong mLastHeadroomUpdate = new AtomicLong(0L);
private static final int MINIMUM_HEADROOM_TIME_MILLIS = 500;
@@ -2794,7 +2925,8 @@
* functionality or if this function is called significantly faster than once per
* second.
*/
- public float getThermalHeadroom(@IntRange(from = 0, to = 60) int forecastSeconds) {
+ public @FloatRange(from = 0f) float getThermalHeadroom(
+ @IntRange(from = 0, to = 60) int forecastSeconds) {
// Rate-limit calls into the thermal service
long now = SystemClock.elapsedRealtime();
long timeSinceLastUpdate = now - mLastHeadroomUpdate.get();
@@ -2839,9 +2971,11 @@
* headroom of 0.75 will never come with {@link #THERMAL_STATUS_MODERATE} but lower, and 0.65
* will never come with {@link #THERMAL_STATUS_LIGHT} but {@link #THERMAL_STATUS_NONE}.
* <p>
- * The returned map of thresholds will not change between calls to this function, so it's
- * best to call this once on initialization. Modifying the result will not change the thresholds
- * cached by the system, and a new call to the API will get a new copy.
+ * Starting at {@link android.os.Build.VERSION_CODES#BAKLAVA} the returned map of thresholds can
+ * change between calls to this function, one could use the new
+ * {@link #addThermalHeadroomListener(Executor, OnThermalHeadroomChangedListener)} API to
+ * register a listener and get callback for changes to thresholds.
+ * <p>
*
* @return map from each thermal status to its thermal headroom
* @throws IllegalStateException if the thermal service is not ready
@@ -2850,24 +2984,22 @@
@FlaggedApi(Flags.FLAG_ALLOW_THERMAL_HEADROOM_THRESHOLDS)
public @NonNull Map<@ThermalStatus Integer, Float> getThermalHeadroomThresholds() {
try {
- synchronized (mThermalHeadroomThresholdsLock) {
- if (mThermalHeadroomThresholds == null) {
- mThermalHeadroomThresholds = mThermalService.getThermalHeadroomThresholds();
- }
- final ArrayMap<Integer, Float> ret = new ArrayMap<>(THERMAL_STATUS_SHUTDOWN);
- for (int status = THERMAL_STATUS_LIGHT; status <= THERMAL_STATUS_SHUTDOWN;
- status++) {
- if (!Float.isNaN(mThermalHeadroomThresholds[status])) {
- ret.put(status, mThermalHeadroomThresholds[status]);
- }
- }
- return ret;
- }
+ return convertThresholdsToMap(mThermalService.getThermalHeadroomThresholds());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
+ private Map<@ThermalStatus Integer, Float> convertThresholdsToMap(final float[] thresholds) {
+ final ArrayMap<Integer, Float> ret = new ArrayMap<>(THERMAL_STATUS_SHUTDOWN);
+ for (int status = THERMAL_STATUS_LIGHT; status <= THERMAL_STATUS_SHUTDOWN; status++) {
+ if (!Float.isNaN(thresholds[status])) {
+ ret.put(status, thresholds[status]);
+ }
+ }
+ return ret;
+ }
+
/**
* If true, the doze component is not started until after the screen has been
* turned off and the screen off animation has been performed.
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 011a3ee..c3cddf3 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -18,8 +18,11 @@
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.hardware.vibrator.IVibratorManager;
+import android.os.vibrator.VendorVibrationSession;
import android.os.vibrator.VibratorInfoFactory;
import android.util.ArrayMap;
import android.util.Log;
@@ -53,6 +56,7 @@
private final Object mLock = new Object();
@GuardedBy("mLock")
private VibratorInfo mVibratorInfo;
+ private int[] mVibratorIds;
@UnsupportedAppUsage
public SystemVibrator(Context context) {
@@ -71,7 +75,11 @@
Log.w(TAG, "Failed to retrieve vibrator info; no vibrator manager.");
return VibratorInfo.EMPTY_VIBRATOR_INFO;
}
- int[] vibratorIds = mVibratorManager.getVibratorIds();
+ int[] vibratorIds = getVibratorIds();
+ if (vibratorIds == null) {
+ Log.w(TAG, "Failed to retrieve vibrator info; error retrieving vibrator ids.");
+ return VibratorInfo.EMPTY_VIBRATOR_INFO;
+ }
if (vibratorIds.length == 0) {
// It is known that the device has no vibrator, so cache and return info that
// reflects the lack of support for effects/primitives.
@@ -95,20 +103,22 @@
@Override
public boolean hasVibrator() {
- if (mVibratorManager == null) {
+ int[] vibratorIds = getVibratorIds();
+ if (vibratorIds == null) {
Log.w(TAG, "Failed to check if vibrator exists; no vibrator manager.");
return false;
}
- return mVibratorManager.getVibratorIds().length > 0;
+ return vibratorIds.length > 0;
}
@Override
public boolean isVibrating() {
- if (mVibratorManager == null) {
+ int[] vibratorIds = getVibratorIds();
+ if (vibratorIds == null) {
Log.w(TAG, "Failed to vibrate; no vibrator manager.");
return false;
}
- for (int vibratorId : mVibratorManager.getVibratorIds()) {
+ for (int vibratorId : vibratorIds) {
if (mVibratorManager.getVibrator(vibratorId).isVibrating()) {
return true;
}
@@ -136,6 +146,11 @@
Log.w(TAG, "Failed to add vibrate state listener; no vibrator manager.");
return;
}
+ int[] vibratorIds = getVibratorIds();
+ if (vibratorIds == null) {
+ Log.w(TAG, "Failed to add vibrate state listener; error retrieving vibrator ids.");
+ return;
+ }
MultiVibratorStateListener delegate = null;
try {
synchronized (mRegisteredListeners) {
@@ -145,7 +160,7 @@
return;
}
delegate = new MultiVibratorStateListener(executor, listener);
- delegate.register(mVibratorManager);
+ delegate.register(mVibratorManager, vibratorIds);
mRegisteredListeners.put(listener, delegate);
delegate = null;
}
@@ -184,6 +199,11 @@
}
@Override
+ public boolean areVendorSessionsSupported() {
+ return mVibratorManager.hasCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ }
+
+ @Override
public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, VibrationEffect effect,
VibrationAttributes attrs) {
if (mVibratorManager == null) {
@@ -243,6 +263,41 @@
mVibratorManager.cancel(usageFilter);
}
+ @Override
+ public void startVendorSession(@NonNull VibrationAttributes attrs, @Nullable String reason,
+ @Nullable CancellationSignal cancellationSignal, @NonNull Executor executor,
+ @NonNull VendorVibrationSession.Callback callback) {
+ if (mVibratorManager == null) {
+ Log.w(TAG, "Failed to start vibration session; no vibrator manager.");
+ executor.execute(
+ () -> callback.onFinished(VendorVibrationSession.STATUS_UNKNOWN_ERROR));
+ return;
+ }
+ int[] vibratorIds = getVibratorIds();
+ if (vibratorIds == null) {
+ Log.w(TAG, "Failed to start vibration session; error retrieving vibrator ids.");
+ executor.execute(
+ () -> callback.onFinished(VendorVibrationSession.STATUS_UNKNOWN_ERROR));
+ return;
+ }
+ mVibratorManager.startVendorSession(vibratorIds, attrs, reason, cancellationSignal,
+ executor, callback);
+ }
+
+ @Nullable
+ private int[] getVibratorIds() {
+ synchronized (mLock) {
+ if (mVibratorIds != null) {
+ return mVibratorIds;
+ }
+ if (mVibratorManager == null) {
+ Log.w(TAG, "Failed to retrieve vibrator ids; no vibrator manager.");
+ return null;
+ }
+ return mVibratorIds = mVibratorManager.getVibratorIds();
+ }
+ }
+
/**
* Tries to unregister individual {@link android.os.Vibrator.OnVibratorStateChangedListener}
* that were left registered to vibrators after failures to register them to all vibrators.
@@ -319,8 +374,7 @@
}
/** Registers a listener to all individual vibrators in {@link VibratorManager}. */
- public void register(VibratorManager vibratorManager) {
- int[] vibratorIds = vibratorManager.getVibratorIds();
+ public void register(VibratorManager vibratorManager, @NonNull int[] vibratorIds) {
synchronized (mLock) {
for (int i = 0; i < vibratorIds.length; i++) {
int vibratorId = vibratorIds[i];
diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java
index a5697fb..f9935d2 100644
--- a/core/java/android/os/SystemVibratorManager.java
+++ b/core/java/android/os/SystemVibratorManager.java
@@ -22,6 +22,10 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.hardware.vibrator.IVibratorManager;
+import android.os.vibrator.IVibrationSession;
+import android.os.vibrator.IVibrationSessionCallback;
+import android.os.vibrator.VendorVibrationSession;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
@@ -47,6 +51,8 @@
@GuardedBy("mLock")
private int[] mVibratorIds;
@GuardedBy("mLock")
+ private int mCapabilities;
+ @GuardedBy("mLock")
private final SparseArray<Vibrator> mVibrators = new SparseArray<>();
@GuardedBy("mLock")
@@ -84,6 +90,11 @@
}
}
+ @Override
+ public boolean hasCapabilities(int capabilities) {
+ return (getCapabilities() & capabilities) == capabilities;
+ }
+
@NonNull
@Override
public Vibrator getVibrator(int vibratorId) {
@@ -173,7 +184,7 @@
int inputSource, String reason, int flags, int privFlags) {
if (mService == null) {
Log.w(TAG, "Failed to perform haptic feedback for input device;"
- + " no vibrator manager service.");
+ + " no vibrator manager service.");
return;
}
Trace.traceBegin(TRACE_TAG_VIBRATOR, "performHapticFeedbackForInputDevice");
@@ -197,6 +208,50 @@
cancelVibration(usageFilter);
}
+ @Override
+ public void startVendorSession(@NonNull int[] vibratorIds, @NonNull VibrationAttributes attrs,
+ @Nullable String reason, @Nullable CancellationSignal cancellationSignal,
+ @NonNull Executor executor, @NonNull VendorVibrationSession.Callback callback) {
+ Objects.requireNonNull(vibratorIds);
+ VendorVibrationSessionCallbackDelegate callbackDelegate =
+ new VendorVibrationSessionCallbackDelegate(executor, callback);
+ if (mService == null) {
+ Log.w(TAG, "Failed to start vibration session; no vibrator manager service.");
+ callbackDelegate.onFinished(VendorVibrationSession.STATUS_UNKNOWN_ERROR);
+ return;
+ }
+ try {
+ ICancellationSignal remoteCancellationSignal = mService.startVendorVibrationSession(
+ mUid, mContext.getDeviceId(), mPackageName, vibratorIds, attrs, reason,
+ callbackDelegate);
+ if (cancellationSignal != null) {
+ cancellationSignal.setRemote(remoteCancellationSignal);
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to start vibration session.", e);
+ callbackDelegate.onFinished(VendorVibrationSession.STATUS_UNKNOWN_ERROR);
+ }
+ }
+
+ private int getCapabilities() {
+ synchronized (mLock) {
+ if (mCapabilities != 0) {
+ return mCapabilities;
+ }
+ try {
+ if (mService == null) {
+ Log.w(TAG, "Failed to retrieve vibrator manager capabilities;"
+ + " no vibrator manager service.");
+ } else {
+ return mCapabilities = mService.getCapabilities();
+ }
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ return 0;
+ }
+ }
+
private void cancelVibration(int usageFilter) {
if (mService == null) {
Log.w(TAG, "Failed to cancel vibration; no vibrator manager service.");
@@ -228,12 +283,45 @@
}
}
+ /** Callback for vendor vibration sessions. */
+ private static class VendorVibrationSessionCallbackDelegate extends
+ IVibrationSessionCallback.Stub {
+ private final Executor mExecutor;
+ private final VendorVibrationSession.Callback mCallback;
+
+ VendorVibrationSessionCallbackDelegate(
+ @NonNull Executor executor,
+ @NonNull VendorVibrationSession.Callback callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ mExecutor = executor;
+ mCallback = callback;
+ }
+
+ @Override
+ public void onStarted(IVibrationSession session) {
+ mExecutor.execute(() -> mCallback.onStarted(new VendorVibrationSession(session)));
+ }
+
+ @Override
+ public void onFinishing() {
+ mExecutor.execute(() -> mCallback.onFinishing());
+ }
+
+ @Override
+ public void onFinished(int status) {
+ mExecutor.execute(() -> mCallback.onFinished(status));
+ }
+ }
+
/** Controls vibrations on a single vibrator. */
private final class SingleVibrator extends Vibrator {
private final VibratorInfo mVibratorInfo;
+ private final int[] mVibratorId;
SingleVibrator(@NonNull VibratorInfo vibratorInfo) {
mVibratorInfo = vibratorInfo;
+ mVibratorId = new int[]{mVibratorInfo.getId()};
}
@Override
@@ -252,6 +340,11 @@
}
@Override
+ public boolean areVendorSessionsSupported() {
+ return SystemVibratorManager.this.hasCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ }
+
+ @Override
public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
@Nullable VibrationEffect effect, @Nullable VibrationAttributes attrs) {
CombinedVibration combined = CombinedVibration.startParallel()
@@ -369,5 +462,13 @@
}
}
}
+
+ @Override
+ public void startVendorSession(@NonNull VibrationAttributes attrs, String reason,
+ @Nullable CancellationSignal cancellationSignal, @NonNull Executor executor,
+ @NonNull VendorVibrationSession.Callback callback) {
+ SystemVibratorManager.this.startVendorSession(mVibratorId, attrs, reason,
+ cancellationSignal, executor, callback);
+ }
}
}
diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java
index f893739..976bfe4 100644
--- a/core/java/android/os/UidBatteryConsumer.java
+++ b/core/java/android/os/UidBatteryConsumer.java
@@ -210,12 +210,6 @@
serializer.attribute(null, BatteryUsageStats.XML_ATTR_HIGHEST_DRAIN_PACKAGE,
packageWithHighestDrain);
}
- serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND,
- getTimeInProcessStateMs(PROCESS_STATE_FOREGROUND));
- serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_BACKGROUND,
- getTimeInProcessStateMs(PROCESS_STATE_BACKGROUND));
- serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND_SERVICE,
- getTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE));
mPowerComponents.writeToXml(serializer);
serializer.endTag(null, BatteryUsageStats.XML_TAG_UID);
}
@@ -235,13 +229,6 @@
consumerBuilder.setPackageWithHighestDrain(
parser.getAttributeValue(null, BatteryUsageStats.XML_ATTR_HIGHEST_DRAIN_PACKAGE));
- consumerBuilder.setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND,
- parser.getAttributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND));
- consumerBuilder.setTimeInProcessStateMs(PROCESS_STATE_BACKGROUND,
- parser.getAttributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_BACKGROUND));
- consumerBuilder.setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE,
- parser.getAttributeLong(null,
- BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND_SERVICE));
while (!(eventType == XmlPullParser.END_TAG
&& parser.getName().equals(BatteryUsageStats.XML_TAG_UID))
&& eventType != XmlPullParser.END_DOCUMENT) {
@@ -335,7 +322,11 @@
/**
* Sets the duration, in milliseconds, that this UID was active in a particular process
* state, such as foreground service.
+ *
+ * @deprecated time in process is now derived from the
+ * {@link BatteryConsumer#POWER_COMPONENT_BASE} duration
*/
+ @Deprecated
@NonNull
public Builder setTimeInProcessStateMs(@ProcessState int state, long timeInProcessStateMs) {
Key key = getKey(POWER_COMPONENT_BASE, state);
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index c4c4580..53f8a92 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -33,6 +33,7 @@
import android.hardware.vibrator.IVibrator;
import android.media.AudioAttributes;
import android.os.vibrator.Flags;
+import android.os.vibrator.VendorVibrationSession;
import android.os.vibrator.VibrationConfig;
import android.os.vibrator.VibratorFrequencyProfile;
import android.os.vibrator.VibratorFrequencyProfileLegacy;
@@ -247,6 +248,34 @@
}
/**
+ * Check whether the vibrator has support for vendor-specific effects.
+ *
+ * <p>Vendor vibration effects can be created via {@link VibrationEffect#createVendorEffect}.
+ *
+ * @return True if the hardware can play vendor-specific vibration effects, false otherwise.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public boolean areVendorEffectsSupported() {
+ return getInfo().hasCapability(IVibrator.CAP_PERFORM_VENDOR_EFFECTS);
+ }
+
+ /**
+ * Check whether the vibrator has support for vendor-specific vibration sessions.
+ *
+ * <p>Vendor vibration sessions can be started via {@link #startVendorSession}.
+ *
+ * @return True if the hardware can play vendor-specific vibration sessions, false otherwise.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public boolean areVendorSessionsSupported() {
+ return false;
+ }
+
+ /**
* Check whether the vibrator can be controlled by an external service with the
* {@link IExternalVibratorService}.
*
@@ -922,4 +951,44 @@
@RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)
public void removeVibratorStateListener(@NonNull OnVibratorStateChangedListener listener) {
}
+
+ /**
+ * Starts a vibration session in this vibrator.
+ *
+ * <p>The session will start asynchronously once the vibrator control can be acquired. Once it's
+ * started the {@link VendorVibrationSession} will be provided to the callback. This session
+ * should be used to play vibrations until the session is ended or canceled.
+ *
+ * <p>The vendor app will have exclusive control over the vibrator during this session. This
+ * control can be revoked by the vibrator service, which will be notified to the same session
+ * callback with the {@link VendorVibrationSession#STATUS_CANCELED}.
+ *
+ * <p>The {@link VibrationAttributes} will be used to decide the priority of the vendor
+ * vibrations that will be performed in this session. All vibrations within this session will
+ * apply the same attributes.
+ *
+ * @param attrs The {@link VibrationAttributes} corresponding to the vibrations that will be
+ * performed in the session. This will be used to decide the priority of this
+ * session against other system vibrations.
+ * @param reason The description for this session, used for debugging purposes.
+ * @param cancellationSignal A signal to cancel the session before it starts.
+ * @param executor The executor for the session callbacks.
+ * @param callback The {@link VendorVibrationSession.Callback} for the started session.
+ *
+ * @see VendorVibrationSession
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.VIBRATE,
+ android.Manifest.permission.VIBRATE_VENDOR_EFFECTS,
+ android.Manifest.permission.START_VIBRATION_SESSIONS,
+ })
+ public void startVendorSession(@NonNull VibrationAttributes attrs, @Nullable String reason,
+ @Nullable CancellationSignal cancellationSignal, @NonNull Executor executor,
+ @NonNull VendorVibrationSession.Callback callback) {
+ Log.w(TAG, "startVendorSession is not supported");
+ executor.execute(() -> callback.onFinished(VendorVibrationSession.STATUS_UNSUPPORTED));
+ }
}
diff --git a/core/java/android/os/VibratorManager.java b/core/java/android/os/VibratorManager.java
index 0428876..0072bc2 100644
--- a/core/java/android/os/VibratorManager.java
+++ b/core/java/android/os/VibratorManager.java
@@ -22,9 +22,12 @@
import android.annotation.SystemService;
import android.app.ActivityThread;
import android.content.Context;
+import android.os.vibrator.VendorVibrationSession;
import android.util.Log;
import android.view.HapticFeedbackConstants;
+import java.util.concurrent.Executor;
+
/**
* Provides access to all vibrators from the device, as well as the ability to run them
* in a synchronized fashion.
@@ -62,6 +65,14 @@
public abstract int[] getVibratorIds();
/**
+ * Return true if the vibrator manager has all capabilities, false otherwise.
+ * @hide
+ */
+ public boolean hasCapabilities(int capabilities) {
+ return false;
+ }
+
+ /**
* Retrieve a single vibrator by id.
*
* @param vibratorId The id of the vibrator to be retrieved.
@@ -190,4 +201,30 @@
*/
@RequiresPermission(android.Manifest.permission.VIBRATE)
public abstract void cancel(int usageFilter);
+
+
+ /**
+ * Starts a vibration session on given vibrators.
+ *
+ * @param vibratorIds The vibrators that will be controlled by this session.
+ * @param attrs The {@link VibrationAttributes} corresponding to the vibrations that will
+ * be performed in the session. This will be used to decide the priority of
+ * this session against other system vibrations.
+ * @param reason The description for this session, used for debugging purposes.
+ * @param cancellationSignal A signal to cancel the session before it starts.
+ * @param executor The executor for the session callbacks.
+ * @param callback The {@link VendorVibrationSession.Callback} for the started session.
+ * @see Vibrator#startVendorSession
+ * @hide
+ */
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.VIBRATE,
+ android.Manifest.permission.VIBRATE_VENDOR_EFFECTS,
+ android.Manifest.permission.START_VIBRATION_SESSIONS,
+ })
+ public void startVendorSession(@NonNull int[] vibratorIds, @NonNull VibrationAttributes attrs,
+ @Nullable String reason, @Nullable CancellationSignal cancellationSignal,
+ @NonNull Executor executor, @NonNull VendorVibrationSession.Callback callback) {
+ Log.w(TAG, "startVendorSession is not supported");
+ }
}
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 1ab48a2..09b96da 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -181,6 +181,5 @@
* device's useful lifetime remains. If no information is available, -1
* is returned.
*/
- @EnforcePermission("READ_PRIVILEGED_PHONE_STATE")
int getInternalStorageRemainingLifetime() = 99;
}
diff --git a/core/java/android/os/vibrator/IVibrationSession.aidl b/core/java/android/os/vibrator/IVibrationSession.aidl
new file mode 100644
index 0000000..e829549
--- /dev/null
+++ b/core/java/android/os/vibrator/IVibrationSession.aidl
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2024, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.os.vibrator;
+
+import android.os.CombinedVibration;
+
+/**
+ * The communication channel by which an app control the system vibrators.
+ *
+ * In order to synchronize the places where vibrations might be controlled we provide this interface
+ * so the vibrator subsystem has a chance to:
+ *
+ * 1) Decide whether the current session should have the vibrator control.
+ * 2) Stop any on-going session for a new session/vibration, based on current system policy.
+ * {@hide}
+ */
+interface IVibrationSession {
+ const int STATUS_UNKNOWN = 0;
+ const int STATUS_SUCCESS = 1;
+ const int STATUS_IGNORED = 2;
+ const int STATUS_UNSUPPORTED = 3;
+ const int STATUS_CANCELED = 4;
+ const int STATUS_UNKNOWN_ERROR = 5;
+
+ /**
+ * A method called to start a vibration within this session. This will fail if the session
+ * is finishing or was canceled.
+ */
+ void vibrate(in CombinedVibration vibration, String reason);
+
+ /**
+ * A method called by the app to stop this session gracefully. The vibrator will complete any
+ * ongoing vibration before the session is ended.
+ */
+ void finishSession();
+
+ /**
+ * A method called by the app to stop this session immediatelly by interrupting any ongoing
+ * vibration.
+ */
+ void cancelSession();
+}
diff --git a/core/java/android/os/vibrator/IVibrationSessionCallback.aidl b/core/java/android/os/vibrator/IVibrationSessionCallback.aidl
new file mode 100644
index 0000000..36c3695
--- /dev/null
+++ b/core/java/android/os/vibrator/IVibrationSessionCallback.aidl
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2024, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.os.vibrator;
+
+import android.os.vibrator.IVibrationSession;
+
+/**
+ * Callback for vibration session state.
+ * {@hide}
+ */
+oneway interface IVibrationSessionCallback {
+
+ /**
+ * A method called by the service after a vibration session has successfully started. After this
+ * is called the app has control over the vibrator through this given session.
+ */
+ void onStarted(in IVibrationSession session);
+
+ /**
+ * A method called by the service to indicate the session is ending and should no longer receive
+ * vibration requests.
+ */
+ void onFinishing();
+
+ /**
+ * A method called by the service after the session has ended. This might be triggered by the
+ * app or the service. The status code indicates the end reason.
+ */
+ void onFinished(int status);
+}
diff --git a/core/java/android/os/vibrator/VendorVibrationSession.java b/core/java/android/os/vibrator/VendorVibrationSession.java
new file mode 100644
index 0000000..c23f2ed
--- /dev/null
+++ b/core/java/android/os/vibrator/VendorVibrationSession.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.os.vibrator;
+
+import static android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.os.CombinedVibration;
+import android.os.RemoteException;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * A vendor session that temporarily gains control over the system vibrators.
+ *
+ * <p>Vibration effects can be played by the vibrator in a vendor session via {@link #vibrate}. The
+ * effects will be forwarded to the vibrator hardware immediately. Any concurrency support is
+ * defined and controlled by the vibrator hardware implementation.
+ *
+ * <p>The session should be ended by {@link #close()}, which will wait until the last vibration ends
+ * and the vibrator is released. The end of the session will be notified to the {@link Callback}
+ * provided when the session was created.
+ *
+ * <p>Any ongoing session can be immediately interrupted by the vendor app via {@link #cancel()},
+ * including after {@link #close()} was called and the session is tearing down. A session can also
+ * be canceled by the vibrator service when it needs to regain control of the system vibrators.
+ *
+ * @see Vibrator#startVendorSession
+ * @hide
+ */
+@FlaggedApi(FLAG_VENDOR_VIBRATION_EFFECTS)
+@SystemApi
+public final class VendorVibrationSession implements AutoCloseable {
+ private static final String TAG = "VendorVibrationSession";
+
+ /**
+ * The session ended successfully.
+ */
+ public static final int STATUS_SUCCESS = IVibrationSession.STATUS_SUCCESS;
+
+ /**
+ * The session was ignored.
+ *
+ * <p>This might be caused by user settings, vibration policies or the device state that
+ * prevents the app from performing vibrations for the requested
+ * {@link android.os.VibrationAttributes}.
+ */
+ public static final int STATUS_IGNORED = IVibrationSession.STATUS_IGNORED;
+
+ /**
+ * The session is not supported.
+ *
+ * <p>The support for vendor vibration sessions can be checked via
+ * {@link Vibrator#areVendorSessionsSupported()}.
+ */
+ public static final int STATUS_UNSUPPORTED = IVibrationSession.STATUS_UNSUPPORTED;
+
+ /**
+ * The session was canceled.
+ *
+ * <p>This might be triggered by the app after a session starts via {@link #cancel()}, or it
+ * can be triggered by the platform before or after the session has started.
+ */
+ public static final int STATUS_CANCELED = IVibrationSession.STATUS_CANCELED;
+
+ /**
+ * The session status is unknown.
+ */
+ public static final int STATUS_UNKNOWN = IVibrationSession.STATUS_UNKNOWN;
+
+ /**
+ * The session failed with unknown error.
+ *
+ * <p>This can be caused by a failure to start a vibration session or after it has started, to
+ * indicate it has ended unexpectedly because of a system failure.
+ */
+ public static final int STATUS_UNKNOWN_ERROR = IVibrationSession.STATUS_UNKNOWN_ERROR;
+
+ /** @hide */
+ @IntDef(prefix = { "STATUS_" }, value = {
+ STATUS_SUCCESS,
+ STATUS_IGNORED,
+ STATUS_UNSUPPORTED,
+ STATUS_CANCELED,
+ STATUS_UNKNOWN,
+ STATUS_UNKNOWN_ERROR,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Status{}
+
+ private final IVibrationSession mSession;
+
+ /** @hide */
+ public VendorVibrationSession(@NonNull IVibrationSession session) {
+ Objects.requireNonNull(session);
+ mSession = session;
+ }
+
+ /**
+ * Vibrate with a given effect.
+ *
+ * <p>The vibration will be sent to the vibrator hardware immediately, without waiting for any
+ * previous vibration completion. The vendor should control the concurrency behavior at the
+ * hardware level (e.g. queueing, mixing, interrupting).
+ *
+ * <p>If the provided effect is played by the vibrator service with controlled timings (e.g.
+ * effects created via {@link VibrationEffect#createWaveform}), then triggering a new vibration
+ * will cause the ongoing playback to be interrupted in favor of the new vibration. If the
+ * effect is broken down into multiple consecutive commands (e.g. large primitive compositions)
+ * then the hardware commands will be triggered in succession without waiting for the completion
+ * callback.
+ *
+ * <p>The vendor app is responsible for timing the session requests and the vibrator hardware
+ * implementation is free to handle concurrency with different policies.
+ *
+ * @param effect The {@link VibrationEffect} describing the vibration to be performed.
+ * @param reason The description for the vibration reason, for debugging purposes.
+ */
+ @RequiresPermission(android.Manifest.permission.VIBRATE)
+ public void vibrate(@NonNull VibrationEffect effect, @Nullable String reason) {
+ try {
+ mSession.vibrate(CombinedVibration.createParallel(effect), reason);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to vibrate in a vendor vibration session.", e);
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Cancel ongoing session.
+ *
+ * <p>This will stop the vibration immediately and return the vibrator control to the
+ * platform. This can also be triggered after {@link #close()} to immediately release the
+ * vibrator.
+ *
+ * <p>This will trigger {@link VendorVibrationSession.Callback#onFinished} directly with
+ * {@link #STATUS_CANCELED}.
+ */
+ public void cancel() {
+ try {
+ mSession.cancelSession();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to cancel vendor vibration session.", e);
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * End ongoing session gracefully.
+ *
+ * <p>This might continue the vibration while it's ramping down and wrapping up the session
+ * in the vibrator hardware. No more vibration commands can be sent through this session
+ * after this method is called.
+ *
+ * <p>This will trigger {@link VendorVibrationSession.Callback#onFinishing()}.
+ */
+ @Override
+ public void close() {
+ try {
+ mSession.finishSession();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to finish vendor vibration session.", e);
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Callbacks for {@link VendorVibrationSession} events.
+ *
+ * @see Vibrator#startVendorSession
+ * @see VendorVibrationSession
+ */
+ public interface Callback {
+
+ /**
+ * New session was successfully started.
+ *
+ * <p>The vendor app can interact with the vibrator using the
+ * {@link VendorVibrationSession} provided.
+ */
+ void onStarted(@NonNull VendorVibrationSession session);
+
+ /**
+ * The session is ending and finishing any pending vibrations.
+ *
+ * <p>This is only invoked after {@link #onStarted(VendorVibrationSession)}. It will be
+ * triggered by both {@link VendorVibrationSession#cancel()} and
+ * {@link VendorVibrationSession#close()}. This might also be triggered if the platform
+ * cancels the ongoing session.
+ *
+ * <p>Session vibrations might be still ongoing in the vibrator hardware but the app can
+ * no longer send commands through the session. A finishing session can still be immediately
+ * stopped via calls to {@link VendorVibrationSession.Callback#cancel()}.
+ */
+ void onFinishing();
+
+ /**
+ * The session is finished.
+ *
+ * <p>The vibrator has finished any vibration and returned to the platform's control. This
+ * might be triggered by the vendor app or by the vibrator service.
+ *
+ * <p>If this is triggered before {@link #onStarted} then the session was finished before
+ * starting, either because it was cancelled or failed to start. If the session has already
+ * started then this will be triggered after {@link #onFinishing()} to indicate all session
+ * vibrations are complete and the vibrator is no longer under the session's control.
+ *
+ * @param status The session status.
+ */
+ void onFinished(@VendorVibrationSession.Status int status);
+ }
+}
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 6a49322..9e0d0e1 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -53,6 +53,24 @@
}
flag {
+ name: "enhanced_confirmation_in_call_apis_enabled"
+ is_exported: true
+ is_fixed_read_only: true
+ namespace: "permissions"
+ description: "enable enhanced confirmation incall apis"
+ bug: "310220212"
+}
+
+flag {
+ name: "unknown_call_package_install_blocking_enabled"
+ is_exported: true
+ is_fixed_read_only: true
+ namespace: "permissions"
+ description: "enable the blocking of certain app installs during an unknown call"
+ bug: "310220212"
+}
+
+flag {
name: "op_enable_mobile_data_by_user"
is_exported: true
namespace: "permissions"
@@ -332,3 +350,38 @@
description: "Enables ExtServices to leverage TextClassifier for OTP detection"
bug: "351976749"
}
+
+flag {
+ name: "health_connect_backup_restore_permission_enabled"
+ is_fixed_read_only: true
+ namespace: "health_connect"
+ description: "This flag protects the permission that is required to call Health Connect backup and restore apis"
+ bug: "376014879" # android_fr bug
+}
+
+flag {
+ name: "enable_aiai_proxied_text_classifiers"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "Enables the AiAi to utilize the default OTP text classifier that is also used by ExtServices"
+ bug: "377229653"
+}
+
+flag {
+ name: "enable_sqlite_appops_accesses"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "Enables SQlite for recording discrete and historical AppOp accesses"
+ bug: "377584611"
+}
+
+flag {
+ name: "ranging_permission_enabled"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "uwb"
+ description: "This fixed read-only flag is used to enable new ranging permission for all ranging use cases."
+ bug: "370977414"
+}
diff --git a/core/java/android/print/OWNERS b/core/java/android/print/OWNERS
index 0809de2..ce79f5d 100644
--- a/core/java/android/print/OWNERS
+++ b/core/java/android/print/OWNERS
@@ -2,3 +2,4 @@
anothermark@google.com
kumarashishg@google.com
+bmgordon@google.com
diff --git a/core/java/android/printservice/OWNERS b/core/java/android/printservice/OWNERS
index 0809de2..ce79f5d 100644
--- a/core/java/android/printservice/OWNERS
+++ b/core/java/android/printservice/OWNERS
@@ -2,3 +2,4 @@
anothermark@google.com
kumarashishg@google.com
+bmgordon@google.com
diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig
index 5995760..66e1f38 100644
--- a/core/java/android/security/responsible_apis_flags.aconfig
+++ b/core/java/android/security/responsible_apis_flags.aconfig
@@ -67,6 +67,7 @@
name: "aapm_api"
namespace: "responsible_apis"
description: "Android Advanced Protection Mode Service and Manager"
+ is_exported: true
bug: "352420507"
is_fixed_read_only: true
}
diff --git a/core/java/android/service/notification/flags.aconfig b/core/java/android/service/notification/flags.aconfig
index 34e311f..d065939 100644
--- a/core/java/android/service/notification/flags.aconfig
+++ b/core/java/android/service/notification/flags.aconfig
@@ -65,4 +65,11 @@
namespace: "systemui"
description: "Allows the NAS to create and modify conversation notifications"
bug: "373599715"
-}
\ No newline at end of file
+}
+
+flag {
+ name: "notification_regroup_on_classification"
+ namespace: "systemui"
+ description: "This flag controls regrouping after notification classification"
+ bug: "372775153"
+}
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 2e660fc..7d79fd3 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -1164,7 +1164,7 @@
public boolean startRecognition(@RecognitionFlags int recognitionFlags) {
if (DBG) Slog.d(TAG, "startRecognition(" + recognitionFlags + ")");
synchronized (mLock) {
- return startRecognitionLocked(recognitionFlags, null /* data */) == STATUS_OK;
+ return startRecognitionLocked(recognitionFlags, /* data= */new byte[0]) == STATUS_OK;
}
}
@@ -1496,8 +1496,8 @@
}
@GuardedBy("mLock")
- private int startRecognitionLocked(int recognitionFlags,
- @Nullable byte[] data) {
+ @SuppressWarnings("FlaggedApi") // RecognitionConfig.Builder is available internally.
+ private int startRecognitionLocked(int recognitionFlags, @NonNull byte[] data) {
if (DBG) {
Slog.d(TAG, "startRecognition("
+ recognitionFlags
diff --git a/core/java/android/service/wallpaper/IWallpaperService.aidl b/core/java/android/service/wallpaper/IWallpaperService.aidl
index f76e6ce..bcdd477 100644
--- a/core/java/android/service/wallpaper/IWallpaperService.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperService.aidl
@@ -28,6 +28,6 @@
void attach(IWallpaperConnection connection,
IBinder windowToken, int windowType, boolean isPreview,
int reqWidth, int reqHeight, in Rect padding, int displayId, int which,
- in WallpaperInfo info, in @nullable WallpaperDescription description);
+ in WallpaperInfo info, in WallpaperDescription description);
void detach(IBinder windowToken);
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 131fdc8..2061aba 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -17,6 +17,7 @@
package android.service.wallpaper;
import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
+import static android.app.Flags.liveWallpaperContentHandling;
import static android.app.WallpaperManager.COMMAND_FREEZE;
import static android.app.WallpaperManager.COMMAND_UNFREEZE;
import static android.app.WallpaperManager.SetWallpaperFlags;
@@ -2624,7 +2625,7 @@
private void doAttachEngine() {
Trace.beginSection("WPMS.onCreateEngine");
Engine engine;
- if (mDescription != null) {
+ if (liveWallpaperContentHandling()) {
engine = onCreateEngine(mDescription);
} else {
engine = onCreateEngine();
diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig
index e830d89..02923ed 100644
--- a/core/java/android/text/flags/flags.aconfig
+++ b/core/java/android/text/flags/flags.aconfig
@@ -202,3 +202,10 @@
description: "Deprecate the Paint#elegantTextHeight API and stick it to true"
bug: "349519475"
}
+
+flag {
+ name: "vertical_text_layout"
+ namespace: "text"
+ description: "Make Paint class work for vertical layout text."
+ bug: "355296926"
+}
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 8358b9a..1dd9d46 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -75,8 +75,7 @@
@android.ravenwood.annotation.RavenwoodClassLoadHook(
"com.android.platform.test.ravenwood.runtimehelper.ClassLoadHook.onClassLoaded")
// Uncomment the following annotation to switch to the Java substitution version.
-//@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
-// "com.android.platform.test.ravenwood.nativesubstitution.Log_host")
+@android.ravenwood.annotation.RavenwoodRedirectionClass("Log_host")
public final class Log {
/** @hide */
@IntDef({ASSERT, ERROR, WARN, INFO, DEBUG, VERBOSE})
@@ -250,6 +249,7 @@
* tag limit of concern after this API level.
*/
@FastNative
+ @android.ravenwood.annotation.RavenwoodRedirect
public static native boolean isLoggable(@Nullable String tag, @Level int level);
/**
@@ -425,6 +425,7 @@
* @hide
*/
@UnsupportedAppUsage
+ @android.ravenwood.annotation.RavenwoodRedirect
public static native int println_native(int bufID, int priority, String tag, String msg);
/**
@@ -452,6 +453,7 @@
* Return the maximum payload the log daemon accepts without truncation.
* @return LOGGER_ENTRY_MAX_PAYLOAD.
*/
+ @android.ravenwood.annotation.RavenwoodRedirect
private static native int logger_entry_max_payload_native();
/**
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 910e644..0241e94 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -1549,8 +1549,9 @@
// Although we only care about the HDR/SDR ratio changing, that can also come in the
// form of the larger DISPLAY_CHANGED event
mGlobal.registerDisplayListener(toRegister, executor,
- DisplayManager.EVENT_FLAG_HDR_SDR_RATIO_CHANGED
- | DisplayManagerGlobal.EVENT_DISPLAY_CHANGED,
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
+ | DisplayManagerGlobal
+ .INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED,
ActivityThread.currentPackageName());
}
diff --git a/core/java/android/view/ImeBackAnimationController.java b/core/java/android/view/ImeBackAnimationController.java
index b801465..19e0913 100644
--- a/core/java/android/view/ImeBackAnimationController.java
+++ b/core/java/android/view/ImeBackAnimationController.java
@@ -33,6 +33,7 @@
import android.view.animation.BackGestureInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.ImeTracker;
import android.window.BackEvent;
import android.window.OnBackAnimationCallback;
@@ -142,9 +143,15 @@
// control has been cancelled by the system. This can happen in multi-window mode for
// example (i.e. split-screen or activity-embedding)
notifyHideIme();
- return;
+ } else {
+ startPostCommitAnim(/*hideIme*/ true);
}
- startPostCommitAnim(/*hideIme*/ true);
+ if (Flags.refactorInsetsController()) {
+ // Unregister all IME back callbacks so that back events are sent to the next callback
+ // even while the hide animation is playing
+ mInsetsController.getHost().getInputMethodManager().getImeOnBackInvokedDispatcher()
+ .preliminaryClear();
+ }
}
private void setPreCommitProgress(float progress) {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 25d2246..26ca813 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1344,6 +1344,11 @@
boolean fromPredictiveBack) {
final boolean visible = layoutInsetsDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN;
+ if (Flags.refactorInsetsController() && !fromPredictiveBack && !visible
+ && (types & ime()) != 0 && (mRequestedVisibleTypes & ime()) != 0) {
+ // Clear IME back callbacks if a IME hide animation is requested
+ mHost.getInputMethodManager().getImeOnBackInvokedDispatcher().preliminaryClear();
+ }
// Basically, we accept the requested visibilities from the upstream callers...
setRequestedVisibleTypes(visible ? types : 0, types);
@@ -1921,6 +1926,14 @@
final @InsetsType int requestedVisibleTypes =
(mRequestedVisibleTypes & ~mask) | (visibleTypes & mask);
if (mRequestedVisibleTypes != requestedVisibleTypes) {
+ if (Flags.refactorInsetsController() && (mRequestedVisibleTypes & ime()) == 0
+ && (requestedVisibleTypes & ime()) != 0) {
+ // In case the IME back callbacks have been preliminarily cleared before, let's
+ // reregister them. This can happen if an IME hide animation was interrupted and the
+ // IME is requested to be shown again.
+ getHost().getInputMethodManager().getImeOnBackInvokedDispatcher()
+ .undoPreliminaryClear();
+ }
ProtoLog.d(IME_INSETS_CONTROLLER, "Setting requestedVisibleTypes to %d (was %d)",
requestedVisibleTypes, mRequestedVisibleTypes);
mRequestedVisibleTypes = requestedVisibleTypes;
diff --git a/core/java/android/view/RoundScrollbarRenderer.java b/core/java/android/view/RoundScrollbarRenderer.java
index 59c2598..5e1eada 100644
--- a/core/java/android/view/RoundScrollbarRenderer.java
+++ b/core/java/android/view/RoundScrollbarRenderer.java
@@ -35,7 +35,9 @@
* @hide
*/
public class RoundScrollbarRenderer {
- private static final String BLUECHIP_ENABLED_SYSPROP = "persist.cw_build.bluechip.enabled";
+ /** @hide */
+ public static final String BLUECHIP_ENABLED_SYSPROP = "persist.cw_build.bluechip.enabled";
+
// The range of the scrollbar position represented as an angle in degrees.
private static final float SCROLLBAR_ANGLE_RANGE = 28.8f;
private static final float MAX_SCROLLBAR_ANGLE_SWIPE = 26.3f; // 90%
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index b8b22e2..df54d31 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -312,6 +312,7 @@
private static native void nativeNotifyShutdown();
private static native void nativeSetLuts(long transactionObj, long nativeObject,
float[] buffers, int[] slots, int[] dimensions, int[] sizes, int[] samplingKeys);
+ private static native void nativeEnableDebugLogCallPoints(long transactionObj);
/**
* Transforms that can be applied to buffers as they are displayed to a window.
@@ -4605,7 +4606,6 @@
}
/**
- * TODO(b/366484871): To be removed once we have some logging in native
* This is called when BlastBufferQueue.mergeWithNextTransaction() is called from java, and
* for the purposes of logging that path.
*/
@@ -4616,6 +4616,7 @@
if (mCalls != null) {
mCalls.clear();
}
+ nativeEnableDebugLogCallPoints(mNativeObject);
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 5ee229f..618843c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -34,6 +34,7 @@
import static android.view.accessibility.Flags.FLAG_SUPPLEMENTAL_DESCRIPTION;
import static android.view.accessibility.Flags.removeChildHoverCheckForTouchExploration;
import static android.view.accessibility.Flags.supplementalDescription;
+import static android.view.accessibility.Flags.supportMultipleLabeledby;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN;
@@ -11402,7 +11403,11 @@
View label = rootView.findLabelForView(this, mID);
if (label != null) {
- info.setLabeledBy(label);
+ if (supportMultipleLabeledby()) {
+ info.addLabeledBy(label);
+ } else {
+ info.setLabeledBy(label);
+ }
}
if ((mAttachInfo.mAccessibilityFetchFlags
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 3ce6870..9a2aa0b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -185,7 +185,6 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.hardware.SyncFence;
-import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.input.InputManagerGlobal;
@@ -1816,9 +1815,9 @@
.registerDisplayListener(
mDisplayListener,
mHandler,
- DisplayManager.EVENT_FLAG_DISPLAY_ADDED
- | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED,
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED,
mBasePackageName);
if (forceInvertColor()) {
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 5e5f33e..14652035 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -857,8 +857,10 @@
* <p>
* The data can be retrieved from the {@code Bundle} returned by {@link #getExtras()} using this
* string as a key for {@link Bundle#getParcelableArray(String, Class)}. The
- * {@link android.graphics.RectF} will be null for characters that either do not exist or are
- * off the screen.
+ * {@link android.graphics.RectF} will be {@code null} for characters that either do not exist
+ * or are off the screen.
+ * <p>
+ * Note that character locations returned are modified by changes in display magnification.
*
* {@see #refreshWithExtraData(String, Bundle)}
*/
@@ -866,6 +868,36 @@
"android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_KEY";
/**
+ * Key used to request and locate extra data for text character location in
+ * window coordinates. This key requests that an array of
+ * {@link android.graphics.RectF}s be added to the extras. This request is made
+ * with {@link #refreshWithExtraData(String, Bundle)}. The arguments taken by
+ * this request are two integers:
+ * {@link #EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX} and
+ * {@link #EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH}. The starting index
+ * must be valid inside the CharSequence returned by {@link #getText()}, and
+ * the length must be positive.
+ * <p>
+ * Providers may advertise that they support text characters in window coordinates using
+ * {@link #setAvailableExtraData(List)}. Services may check if an implementation supports text
+ * characters in window coordinates with {@link #getAvailableExtraData()}.
+ * <p>
+ * The data can be retrieved from the {@code Bundle} returned by
+ * {@link #getExtras()} using this string as a key for
+ * {@link Bundle#getParcelableArray(String, Class)}. The
+ * {@link android.graphics.RectF} will be {@code null} for characters that either do
+ * not exist or are outside of the window bounds.
+ * <p>
+ * Note that character locations in window bounds are not modified by
+ * changes in display magnification.
+ *
+ * {@see #refreshWithExtraData(String, Bundle)}
+ */
+ @FlaggedApi(Flags.FLAG_A11Y_CHARACTER_IN_WINDOW_API)
+ public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_IN_WINDOW_KEY =
+ "android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_IN_WINDOW_KEY";
+
+ /**
* Integer argument specifying the start index of the requested text location data. Must be
* valid inside the CharSequence returned by {@link #getText()}.
*
@@ -4008,8 +4040,12 @@
* Sets the view which serves as the label of the view represented by
* this info for accessibility purposes.
*
+ * @deprecated Use {@link #addLabeledBy(View)} or {@link #removeLabeledBy(View)} instead.
+ *
* @param label The view that labels this node's source.
*/
+ @FlaggedApi(Flags.FLAG_SUPPORT_MULTIPLE_LABELEDBY)
+ @Deprecated
public void setLabeledBy(View label) {
setLabeledBy(label, AccessibilityNodeProvider.HOST_VIEW_ID);
}
@@ -4030,9 +4066,14 @@
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
+ * @deprecated Use {@link #addLabeledBy(View, int)} or {@link #removeLabeledBy(View, int)}
+ * instead.
+ *
* @param root The root whose virtual descendant labels this node's source.
* @param virtualDescendantId The id of the virtual descendant.
*/
+ @FlaggedApi(Flags.FLAG_SUPPORT_MULTIPLE_LABELEDBY)
+ @Deprecated
public void setLabeledBy(View root, int virtualDescendantId) {
enforceNotSealed();
final int rootAccessibilityViewId = (root != null)
@@ -4054,8 +4095,12 @@
* Gets the node info which serves as the label of the view represented by
* this info for accessibility purposes.
*
+ * @deprecated Use {@link #getLabeledByList()} instead.
+ *
* @return The label.
*/
+ @FlaggedApi(Flags.FLAG_SUPPORT_MULTIPLE_LABELEDBY)
+ @Deprecated
public AccessibilityNodeInfo getLabeledBy() {
enforceSealed();
return getNodeForAccessibilityId(mConnectionId, mWindowId, mLabeledById);
@@ -5460,26 +5505,6 @@
}
}
- private static String getExpandedStateSymbolicName(int state) {
- if (Flags.a11yExpansionStateApi()) {
- switch (state) {
- case EXPANDED_STATE_UNDEFINED:
- return "EXPANDED_STATE_UNDEFINED";
- case EXPANDED_STATE_COLLAPSED:
- return "EXPANDED_STATE_COLLAPSED";
- case EXPANDED_STATE_PARTIAL:
- return "EXPANDED_STATE_PARTIAL";
- case EXPANDED_STATE_FULL:
- return "EXPANDED_STATE_FULL";
- default:
- throw new IllegalArgumentException("Unknown expanded state: " + state);
- }
- } else {
- // TODO(b/362782158) Remove when flag is removed.
- return "";
- }
- }
-
private static boolean canPerformRequestOverConnection(int connectionId,
int windowId, long accessibilityNodeId) {
final boolean hasWindowId = windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
@@ -5573,20 +5598,12 @@
builder.append("; maxTextLength: ").append(mMaxTextLength);
builder.append("; stateDescription: ").append(mStateDescription);
builder.append("; contentDescription: ").append(mContentDescription);
- if (Flags.supplementalDescription()) {
- builder.append("; supplementalDescription: ").append(mSupplementalDescription);
- }
builder.append("; tooltipText: ").append(mTooltipText);
builder.append("; containerTitle: ").append(mContainerTitle);
builder.append("; viewIdResName: ").append(mViewIdResourceName);
builder.append("; uniqueId: ").append(mUniqueId);
- builder.append("; expandedState: ").append(getExpandedStateSymbolicName(mExpandedState));
-
builder.append("; checkable: ").append(isCheckable());
builder.append("; checked: ").append(isChecked());
- if (Flags.a11yIsRequiredApi()) {
- builder.append("; required: ").append(isFieldRequired());
- }
builder.append("; focusable: ").append(isFocusable());
builder.append("; focused: ").append(isFocused());
builder.append("; selected: ").append(isSelected());
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 7dc77b1..73f9d9f 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -3667,6 +3667,14 @@
}
/**
+ * Returns the ImeOnBackInvokedDispatcher.
+ * @hide
+ */
+ public ImeOnBackInvokedDispatcher getImeOnBackInvokedDispatcher() {
+ return mImeDispatcher;
+ }
+
+ /**
* Check the next served view if needs to start input.
*/
@GuardedBy("mH")
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index be91cfb..a67ae7c 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -17,8 +17,10 @@
package android.view.inputmethod;
import android.annotation.AnyThread;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.StringRes;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
@@ -87,8 +89,17 @@
private final boolean mIsAsciiCapable;
private final int mSubtypeHashCode;
private final int mSubtypeIconResId;
+ /** The subtype name resource identifier. */
private final int mSubtypeNameResId;
+ /** The untranslatable name of the subtype. */
+ @NonNull
private final CharSequence mSubtypeNameOverride;
+ /** The layout label string resource identifier. */
+ @StringRes
+ private final int mLayoutLabelResId;
+ /** The non-localized layout label. */
+ @NonNull
+ private final CharSequence mLayoutLabelNonLocalized;
private final String mPkLanguageTag;
private final String mPkLayoutType;
private final int mSubtypeId;
@@ -176,6 +187,7 @@
mSubtypeNameResId = subtypeNameResId;
return this;
}
+ /** The subtype name resource identifier. */
private int mSubtypeNameResId = 0;
/**
@@ -191,9 +203,56 @@
mSubtypeNameOverride = nameOverride;
return this;
}
+ /** The untranslatable name of the subtype. */
+ @NonNull
private CharSequence mSubtypeNameOverride = "";
/**
+ * Sets the layout label string resource identifier.
+ *
+ * @param layoutLabelResId the layout label string resource identifier.
+ *
+ * @see #getLayoutDisplayName
+ */
+ @FlaggedApi(Flags.FLAG_IME_SWITCHER_REVAMP_API)
+ @NonNull
+ public InputMethodSubtypeBuilder setLayoutLabelResource(
+ @StringRes int layoutLabelResId) {
+ if (!Flags.imeSwitcherRevampApi()) {
+ return this;
+ }
+ mLayoutLabelResId = layoutLabelResId;
+ return this;
+ }
+ /** The layout label string resource identifier. */
+ @StringRes
+ private int mLayoutLabelResId = 0;
+
+ /**
+ * Sets the non-localized layout label. This is used as the layout display name if the
+ * {@link #getLayoutLabelResource layoutLabelResource} is not set ({@code 0}).
+ *
+ * @param layoutLabelNonLocalized the non-localized layout label.
+ *
+ * @see #getLayoutDisplayName
+ */
+ @FlaggedApi(Flags.FLAG_IME_SWITCHER_REVAMP_API)
+ @NonNull
+ public InputMethodSubtypeBuilder setLayoutLabelNonLocalized(
+ @NonNull CharSequence layoutLabelNonLocalized) {
+ if (!Flags.imeSwitcherRevampApi()) {
+ return this;
+ }
+ Objects.requireNonNull(layoutLabelNonLocalized,
+ "layoutLabelNonLocalized cannot be null");
+ mLayoutLabelNonLocalized = layoutLabelNonLocalized;
+ return this;
+ }
+ /** The non-localized layout label. */
+ @NonNull
+ private CharSequence mLayoutLabelNonLocalized = "";
+
+ /**
* Sets the physical keyboard hint information, such as language and layout.
*
* The system can use the hint information to automatically configure the physical keyboard
@@ -350,6 +409,8 @@
private InputMethodSubtype(InputMethodSubtypeBuilder builder) {
mSubtypeNameResId = builder.mSubtypeNameResId;
mSubtypeNameOverride = builder.mSubtypeNameOverride;
+ mLayoutLabelResId = builder.mLayoutLabelResId;
+ mLayoutLabelNonLocalized = builder.mLayoutLabelNonLocalized;
mPkLanguageTag = builder.mPkLanguageTag;
mPkLayoutType = builder.mPkLayoutType;
mSubtypeIconResId = builder.mSubtypeIconResId;
@@ -376,6 +437,9 @@
mSubtypeNameResId = source.readInt();
CharSequence cs = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
mSubtypeNameOverride = cs != null ? cs : "";
+ mLayoutLabelResId = source.readInt();
+ cs = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ mLayoutLabelNonLocalized = cs != null ? cs : "";
s = source.readString8();
mPkLanguageTag = s != null ? s : "";
s = source.readString8();
@@ -412,6 +476,24 @@
}
/**
+ * Returns the layout label string resource identifier.
+ */
+ @FlaggedApi(Flags.FLAG_IME_SWITCHER_REVAMP_API)
+ @StringRes
+ public int getLayoutLabelResource() {
+ return mLayoutLabelResId;
+ }
+
+ /**
+ * Returns the non-localized layout label.
+ */
+ @FlaggedApi(Flags.FLAG_IME_SWITCHER_REVAMP_API)
+ @NonNull
+ public CharSequence getLayoutLabelNonLocalized() {
+ return mLayoutLabelNonLocalized;
+ }
+
+ /**
* Returns the physical keyboard BCP-47 language tag.
*
* @attr ref android.R.styleable#InputMethod_Subtype_physicalKeyboardHintLanguageTag
@@ -643,11 +725,49 @@
try {
return String.format(subtypeNameString, replacementString);
} catch (IllegalFormatException e) {
- Slog.w(TAG, "Found illegal format in subtype name("+ subtypeName + "): " + e);
+ Slog.w(TAG, "Found illegal format in subtype name(" + subtypeName + "): " + e);
return "";
}
}
+ /**
+ * Returns the layout display name.
+ *
+ * <p>If {@code layoutLabelResource} is non-zero (specified through
+ * {@link InputMethodSubtypeBuilder#setLayoutLabelResource setLayoutLabelResource}), the
+ * text generated from that resource will be returned. The localized string resource of the
+ * label should be capitalized for inclusion in UI lists.
+ *
+ * <p>If {@code layoutLabelResource} is zero, the framework returns the non-localized
+ * layout label, if specified through
+ * {@link InputMethodSubtypeBuilder#setLayoutLabelNonLocalized setLayoutLabelNonLocalized}.
+ *
+ * @param context The context used for getting the
+ * {@link android.content.pm.PackageManager PackageManager}.
+ * @param imeAppInfo The {@link ApplicationInfo} of the input method.
+ * @return the layout display name.
+ */
+ @NonNull
+ @FlaggedApi(Flags.FLAG_IME_SWITCHER_REVAMP_API)
+ public CharSequence getLayoutDisplayName(@NonNull Context context,
+ @NonNull ApplicationInfo imeAppInfo) {
+ if (!Flags.imeSwitcherRevampApi()) {
+ return "";
+ }
+ Objects.requireNonNull(context, "context cannot be null");
+ Objects.requireNonNull(imeAppInfo, "imeAppInfo cannot be null");
+ if (mLayoutLabelResId == 0) {
+ return mLayoutLabelNonLocalized;
+ }
+
+ final CharSequence subtypeLayoutName = context.getPackageManager().getText(
+ imeAppInfo.packageName, mLayoutLabelResId, imeAppInfo);
+ if (TextUtils.isEmpty(subtypeLayoutName)) {
+ return "";
+ }
+ return subtypeLayoutName;
+ }
+
@Nullable
private static Locale getLocaleFromContext(@Nullable final Context context) {
if (context == null) {
@@ -778,6 +898,8 @@
public void writeToParcel(Parcel dest, int parcelableFlags) {
dest.writeInt(mSubtypeNameResId);
TextUtils.writeToParcel(mSubtypeNameOverride, dest, parcelableFlags);
+ dest.writeInt(mLayoutLabelResId);
+ TextUtils.writeToParcel(mLayoutLabelNonLocalized, dest, parcelableFlags);
dest.writeString8(mPkLanguageTag);
dest.writeString8(mPkLayoutType);
dest.writeInt(mSubtypeIconResId);
@@ -794,6 +916,7 @@
void dump(@NonNull Printer pw, @NonNull String prefix) {
pw.println(prefix + "mSubtypeNameOverride=" + mSubtypeNameOverride
+ + " mLayoutLabelNonLocalized=" + mLayoutLabelNonLocalized
+ " mPkLanguageTag=" + mPkLanguageTag
+ " mPkLayoutType=" + mPkLayoutType
+ " mSubtypeId=" + mSubtypeId
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index ef941da..d7750bd 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -26,6 +26,9 @@
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH;
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX;
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY;
+import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_IN_WINDOW_KEY;
+import static android.view.accessibility.Flags.FLAG_A11Y_CHARACTER_IN_WINDOW_API;
+import static android.view.accessibility.Flags.a11yCharacterInWindowApi;
import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
import static android.view.inputmethod.EditorInfo.STYLUS_HANDWRITING_ENABLED_ANDROIDX_EXTRAS_KEY;
import static android.view.inputmethod.Flags.initiationWithoutInputConnection;
@@ -492,6 +495,20 @@
/** Accessibility action start id for "smart" actions. @hide */
static final int ACCESSIBILITY_ACTION_SMART_START_ID = 0x10001000;
+ // Stable extra data keys supported by TextView.
+ private static final List<String> ACCESSIBILITY_EXTRA_DATA_KEYS = List.of(
+ EXTRA_DATA_RENDERING_INFO_KEY,
+ EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
+ );
+
+ // Flagged and stable extra data keys supported by TextView.
+ @FlaggedApi(FLAG_A11Y_CHARACTER_IN_WINDOW_API)
+ private static final List<String> ACCESSIBILITY_EXTRA_DATA_KEYS_FLAGGED = List.of(
+ EXTRA_DATA_RENDERING_INFO_KEY,
+ EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY,
+ EXTRA_DATA_TEXT_CHARACTER_LOCATION_IN_WINDOW_KEY
+ );
+
/**
* @hide
*/
@@ -14207,10 +14224,11 @@
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
- info.setAvailableExtraData(Arrays.asList(
- EXTRA_DATA_RENDERING_INFO_KEY,
- EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
- ));
+ if (a11yCharacterInWindowApi()) {
+ info.setAvailableExtraData(ACCESSIBILITY_EXTRA_DATA_KEYS_FLAGGED);
+ } else {
+ info.setAvailableExtraData(ACCESSIBILITY_EXTRA_DATA_KEYS);
+ }
info.setTextSelectable(isTextSelectable() || isTextEditable());
} else {
info.setAvailableExtraData(Arrays.asList(
@@ -14275,7 +14293,11 @@
@Override
public void addExtraDataToAccessibilityNodeInfo(
AccessibilityNodeInfo info, String extraDataKey, Bundle arguments) {
- if (arguments != null && extraDataKey.equals(EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY)) {
+ boolean isCharacterLocationKey = extraDataKey.equals(
+ EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY);
+ boolean isCharacterLocationInWindowKey = (a11yCharacterInWindowApi() && extraDataKey.equals(
+ EXTRA_DATA_TEXT_CHARACTER_LOCATION_IN_WINDOW_KEY));
+ if (arguments != null && (isCharacterLocationKey || isCharacterLocationInWindowKey)) {
int positionInfoStartIndex = arguments.getInt(
EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX, -1);
int positionInfoLength = arguments.getInt(
@@ -14297,7 +14319,11 @@
RectF bounds = cursorAnchorInfo
.getCharacterBounds(positionInfoStartIndex + i);
if (bounds != null) {
- mapRectFromViewToScreenCoords(bounds, true);
+ if (isCharacterLocationKey) {
+ mapRectFromViewToScreenCoords(bounds, true);
+ } else if (isCharacterLocationInWindowKey) {
+ mapRectFromViewToWindowCoords(bounds, true);
+ }
boundingRects[i] = bounds;
}
}
diff --git a/core/java/android/window/BackProgressAnimator.java b/core/java/android/window/BackProgressAnimator.java
index a5be58b..16eb437 100644
--- a/core/java/android/window/BackProgressAnimator.java
+++ b/core/java/android/window/BackProgressAnimator.java
@@ -16,8 +16,11 @@
package android.window;
+import static android.window.BackEvent.EDGE_NONE;
+
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.window.flags.Flags.predictiveBackTimestampApi;
+import static com.android.window.flags.Flags.predictiveBackSwipeEdgeNoneApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -60,6 +63,12 @@
@Nullable
private Runnable mBackInvokedFinishRunnable;
private FlingAnimation mBackInvokedFlingAnim;
+ private final SpringForce mGestureSpringForce = new SpringForce()
+ .setStiffness(SpringForce.STIFFNESS_MEDIUM)
+ .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY);
+ private final SpringForce mButtonSpringForce = new SpringForce()
+ .setStiffness(500)
+ .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY);
private final DynamicAnimation.OnAnimationEndListener mOnAnimationEndListener =
(animation, canceled, value, velocity) -> {
if (mBackCancelledFinishRunnable != null) invokeBackCancelledRunnable();
@@ -109,9 +118,7 @@
public BackProgressAnimator() {
mSpring = new SpringAnimation(this, PROGRESS_PROP);
mSpring.addUpdateListener(this);
- mSpring.setSpring(new SpringForce()
- .setStiffness(SpringForce.STIFFNESS_MEDIUM)
- .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY));
+ mSpring.setSpring(mGestureSpringForce);
}
/**
@@ -123,6 +130,11 @@
if (!mBackAnimationInProgress) {
return;
}
+ if (predictiveBackSwipeEdgeNoneApi()) {
+ if (event.getSwipeEdge() == EDGE_NONE) {
+ return;
+ }
+ }
mLastBackEvent = event;
if (mSpring == null) {
return;
@@ -143,7 +155,17 @@
mBackAnimationInProgress = true;
updateProgressValue(/* progress */ 0, /* velocity */ 0,
/* frameTime */ System.nanoTime() / TimeUtils.NANOS_PER_MS);
- onBackProgressed(event);
+ if (predictiveBackSwipeEdgeNoneApi()) {
+ if (event.getSwipeEdge() == EDGE_NONE) {
+ mSpring.setSpring(mButtonSpringForce);
+ mSpring.animateToFinalPosition(SCALE_FACTOR);
+ } else {
+ mSpring.setSpring(mGestureSpringForce);
+ onBackProgressed(event);
+ }
+ } else {
+ onBackProgressed(event);
+ }
}
/**
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index bd01899..c67b9ca 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -203,6 +203,34 @@
mImeCallbacks.remove(callback);
}
+ /**
+ * Unregisters all callbacks on the receiving dispatcher but keeps a reference of the callbacks
+ * in case the clearance is reverted in
+ * {@link ImeOnBackInvokedDispatcher#undoPreliminaryClear()}.
+ */
+ public void preliminaryClear() {
+ // Unregister previously registered callbacks if there's any.
+ if (getReceivingDispatcher() != null) {
+ for (ImeOnBackInvokedCallback callback : mImeCallbacks) {
+ getReceivingDispatcher().unregisterOnBackInvokedCallback(callback);
+ }
+ }
+ }
+
+ /**
+ * Reregisters all callbacks on the receiving dispatcher that have previously been cleared by
+ * calling {@link ImeOnBackInvokedDispatcher#preliminaryClear()}. This can happen if an IME hide
+ * animation is interrupted causing the IME to reappear.
+ */
+ public void undoPreliminaryClear() {
+ if (getReceivingDispatcher() != null) {
+ for (ImeOnBackInvokedCallback callback : mImeCallbacks) {
+ getReceivingDispatcher().registerOnBackInvokedCallbackUnchecked(callback,
+ callback.mPriority);
+ }
+ }
+ }
+
/** Clears all registered callbacks on the instance. */
public void clear() {
// Unregister previously registered callbacks if there's any.
diff --git a/core/java/android/window/TransitionFilter.java b/core/java/android/window/TransitionFilter.java
index 8bb4c52..61fc622 100644
--- a/core/java/android/window/TransitionFilter.java
+++ b/core/java/android/window/TransitionFilter.java
@@ -17,6 +17,7 @@
package android.window;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.WindowManager.TransitionType;
import android.annotation.IntDef;
@@ -189,6 +190,8 @@
public Boolean mCustomAnimation = null;
public IBinder mTaskFragmentToken = null;
+ public int mWindowingMode = WINDOWING_MODE_UNDEFINED;
+
public Requirement() {
}
@@ -206,6 +209,7 @@
final int customAnimRaw = in.readInt();
mCustomAnimation = customAnimRaw == 0 ? null : Boolean.valueOf(customAnimRaw == 2);
mTaskFragmentToken = in.readStrongBinder();
+ mWindowingMode = in.readInt();
}
/** Go through changes and find if at-least one change matches this filter */
@@ -270,6 +274,12 @@
continue;
}
}
+ if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
+ if (change.getTaskInfo() == null
+ || change.getTaskInfo().getWindowingMode() != mWindowingMode) {
+ continue;
+ }
+ }
return true;
}
return false;
@@ -322,6 +332,7 @@
int customAnimRaw = mCustomAnimation == null ? 0 : (mCustomAnimation ? 2 : 1);
dest.writeInt(customAnimRaw);
dest.writeStrongBinder(mTaskFragmentToken);
+ dest.writeInt(mWindowingMode);
}
@NonNull
@@ -369,6 +380,8 @@
if (mTaskFragmentToken != null) {
out.append(" taskFragmentToken=").append(mTaskFragmentToken);
}
+ out.append(" windowingMode="
+ + WindowConfiguration.windowingModeToString(mWindowingMode));
out.append("}");
return out.toString();
}
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 14505f5..0f2dd10 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -169,8 +169,11 @@
/** This change represents its start configuration for the duration of the animation. */
public static final int FLAG_CONFIG_AT_END = 1 << 22;
+ /** This change represents one of a Task Display Area. */
+ public static final int FLAG_IS_TASK_DISPLAY_AREA = 1 << 23;
+
/** The first unused bit. This can be used by remotes to attach custom flags to this change. */
- public static final int FLAG_FIRST_CUSTOM = 1 << 23;
+ public static final int FLAG_FIRST_CUSTOM = 1 << 24;
/** The change belongs to a window that won't contain activities. */
public static final int FLAGS_IS_NON_APP_WINDOW =
@@ -205,6 +208,7 @@
FLAG_MOVED_TO_TOP,
FLAG_SYNC,
FLAG_CONFIG_AT_END,
+ FLAG_IS_TASK_DISPLAY_AREA,
FLAG_FIRST_CUSTOM
}, flag = true)
public @interface ChangeFlags {}
@@ -553,6 +557,9 @@
if ((flags & FLAG_MOVED_TO_TOP) != 0) {
sb.append(sb.length() == 0 ? "" : "|").append("MOVE_TO_TOP");
}
+ if ((flags & FLAG_IS_TASK_DISPLAY_AREA) != 0) {
+ sb.append(sb.length() == 0 ? "" : "|").append("FLAG_IS_TASK_DISPLAY_AREA");
+ }
return sb.toString();
}
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 731d100..d39ecab 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -96,6 +96,16 @@
}
flag {
+ name: "enable_accessible_custom_headers"
+ namespace: "lse_desktop_experience"
+ description: "Enables a11y-friendly custom header input handling"
+ bug: "339302584"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_app_header_with_task_density"
namespace: "lse_desktop_experience"
description: "Matches the App Header density to that of the app window, instead of SysUI's"
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 11f6849..68e78fe 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -76,6 +76,14 @@
}
flag {
+ name: "disable_opt_out_edge_to_edge"
+ namespace: "windowing_frontend"
+ description: "Deprecate and disable windowOptOutEdgeToEdgeEnforcement"
+ bug: "377864165"
+ is_fixed_read_only: true
+}
+
+flag {
name: "keyguard_going_away_timeout"
namespace: "windowing_frontend"
description: "Allow a maximum of 10 seconds with keyguardGoingAway=true before force-resetting"
@@ -388,4 +396,11 @@
description: "Provide pre-make predictive back API extension"
is_fixed_read_only: true
bug: "362938401"
-}
\ No newline at end of file
+}
+
+flag {
+ name: "predictive_back_three_button_nav"
+ namespace: "systemui"
+ description: "Enable Predictive Back Animation for 3-button-nav"
+ bug: "373544911"
+}
diff --git a/core/java/com/android/internal/compat/AndroidBuildClassifier.java b/core/java/com/android/internal/compat/AndroidBuildClassifier.java
index 364db06..19f8889 100644
--- a/core/java/com/android/internal/compat/AndroidBuildClassifier.java
+++ b/core/java/com/android/internal/compat/AndroidBuildClassifier.java
@@ -22,6 +22,7 @@
* Platform private class for determining the type of Android build installed.
*
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class AndroidBuildClassifier {
public boolean isDebuggableBuild() {
diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java
index f611571..f714098 100644
--- a/core/java/com/android/internal/compat/ChangeReporter.java
+++ b/core/java/com/android/internal/compat/ChangeReporter.java
@@ -42,6 +42,7 @@
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class ChangeReporter {
private static final String TAG = "CompatChangeReporter";
private static final Function<Integer, Set<ChangeReport>> NEW_CHANGE_REPORT_SET =
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
index 182dba7..8fd914ae 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
@@ -28,6 +28,7 @@
* Parcelable containing compat config overrides for a given application.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityChangeConfig implements Parcelable {
private final ChangeConfig mChangeConfig;
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
index 03fe455..505fd23 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
@@ -25,6 +25,7 @@
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class CompatibilityChangeInfo implements Parcelable {
private final long mChangeId;
private final @Nullable String mName;
diff --git a/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java b/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
index 9a02b7b..32206c9 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
@@ -28,6 +28,7 @@
* Parcelable containing compat config overrides for a given application.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityOverrideConfig implements Parcelable {
public final Map<Long, PackageOverride> overrides;
diff --git a/core/java/com/android/internal/compat/CompatibilityOverridesByPackageConfig.java b/core/java/com/android/internal/compat/CompatibilityOverridesByPackageConfig.java
index 8652bb6..998b48a 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverridesByPackageConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverridesByPackageConfig.java
@@ -26,6 +26,7 @@
* Parcelable containing compat config overrides by application.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityOverridesByPackageConfig implements Parcelable {
public final Map<String, CompatibilityOverrideConfig> packageNameToOverrides;
diff --git a/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveByPackageConfig.java b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveByPackageConfig.java
index b408d64..c0e2217 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveByPackageConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveByPackageConfig.java
@@ -29,6 +29,7 @@
* IDs.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityOverridesToRemoveByPackageConfig implements Parcelable {
public final Map<String, CompatibilityOverridesToRemoveConfig> packageNameToOverridesToRemove;
diff --git a/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java
index e85afef..10461ec 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java
@@ -30,6 +30,7 @@
* <p>This class is separate from CompatibilityOverrideConfig since we only need change IDs.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityOverridesToRemoveConfig implements Parcelable {
public final Set<Long> changeIds;
diff --git a/core/java/com/android/internal/compat/OverrideAllowedState.java b/core/java/com/android/internal/compat/OverrideAllowedState.java
index e408be2..f018c3a 100644
--- a/core/java/com/android/internal/compat/OverrideAllowedState.java
+++ b/core/java/com/android/internal/compat/OverrideAllowedState.java
@@ -27,6 +27,7 @@
/**
* This class contains all the possible override allowed states.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class OverrideAllowedState implements Parcelable {
@IntDef({
ALLOWED,
diff --git a/core/java/com/android/internal/display/BrightnessSynchronizer.java b/core/java/com/android/internal/display/BrightnessSynchronizer.java
index 21fbf9d..a50dbb0 100644
--- a/core/java/com/android/internal/display/BrightnessSynchronizer.java
+++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java
@@ -600,8 +600,8 @@
final ContentResolver cr = mContext.getContentResolver();
cr.registerContentObserver(BRIGHTNESS_URI, false,
createBrightnessContentObserver(handler), UserHandle.USER_ALL);
- mDisplayManager.registerDisplayListener(mListener, handler,
- DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS);
+ mDisplayManager.registerDisplayListener(mListener, handler, /* eventFlags */ 0,
+ DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS);
mIsObserving = true;
}
}
diff --git a/core/java/com/android/internal/jank/DisplayResolutionTracker.java b/core/java/com/android/internal/jank/DisplayResolutionTracker.java
index ca6c54d..0c2fd4b 100644
--- a/core/java/com/android/internal/jank/DisplayResolutionTracker.java
+++ b/core/java/com/android/internal/jank/DisplayResolutionTracker.java
@@ -147,8 +147,9 @@
@Override
public void registerDisplayListener(DisplayManager.DisplayListener listener) {
manager.registerDisplayListener(listener, handler,
- DisplayManager.EVENT_FLAG_DISPLAY_ADDED
- | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED,
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
+ | DisplayManagerGlobal
+ .INTERNAL_EVENT_FLAG_DISPLAY_CHANGED,
ActivityThread.currentPackageName());
}
diff --git a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
index a69d2e4..3303d87 100644
--- a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
+++ b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
@@ -15,6 +15,12 @@
*/
package com.android.internal.ravenwood;
+import static android.os.Build.VERSION_CODES.S;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
+import android.compat.annotation.EnabledAfter;
import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.ravenwood.annotation.RavenwoodRedirect;
import android.ravenwood.annotation.RavenwoodRedirectionClass;
@@ -78,4 +84,20 @@
public String getRavenwoodRuntimePath() {
throw notSupportedOnDevice();
}
+
+ /** @hide */
+ public static class CompatIdsForTest {
+ // Enabled by default
+ @ChangeId
+ public static final long TEST_COMPAT_ID_1 = 368131859L;
+
+ @Disabled
+ @ChangeId public static final long TEST_COMPAT_ID_2 = 368131701L;
+
+ @EnabledAfter(targetSdkVersion = S)
+ @ChangeId public static final long TEST_COMPAT_ID_3 = 368131659L;
+
+ @EnabledAfter(targetSdkVersion = UPSIDE_DOWN_CAKE)
+ @ChangeId public static final long TEST_COMPAT_ID_4 = 368132057L;
+ }
}
diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java
index 1938cdb..40161023 100644
--- a/core/java/com/android/internal/statusbar/StatusBarIcon.java
+++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java
@@ -40,9 +40,6 @@
public enum Type {
// Notification: the sender avatar for important conversations
PeopleAvatar,
- // Notification: the monochrome version of the app icon if available; otherwise fall back to
- // the small icon
- MaybeMonochromeAppIcon,
// Notification: the small icon from the notification
NotifSmallIcon,
// The wi-fi, cellular or battery icon.
diff --git a/core/java/com/android/internal/widget/NotificationRowIconView.java b/core/java/com/android/internal/widget/NotificationRowIconView.java
index adcc0f6..5fc61b0 100644
--- a/core/java/com/android/internal/widget/NotificationRowIconView.java
+++ b/core/java/com/android/internal/widget/NotificationRowIconView.java
@@ -22,11 +22,7 @@
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -35,8 +31,6 @@
import android.view.RemotableViewMethod;
import android.widget.RemoteViews;
-import com.android.internal.R;
-
/**
* An image view that holds the icon displayed at the start of a notification row.
* This can generally either display the "small icon" of a notification set via
@@ -48,7 +42,6 @@
private NotificationIconProvider mIconProvider;
private boolean mApplyCircularCrop = false;
- private boolean mShouldShowAppIcon = false;
private Drawable mAppIcon = null;
// Padding, background and colors set on the view prior to being overridden when showing the app
@@ -77,17 +70,6 @@
super(context, attrs, defStyleAttr, defStyleRes);
}
- @Override
- protected void onFinishInflate() {
- // If showing the app icon, we don't need background or padding.
- if (Flags.notificationsUseAppIcon()) {
- setPadding(0, 0, 0, 0);
- setBackground(null);
- }
-
- super.onFinishInflate();
- }
-
/**
* Sets the icon provider for this view. This is used to determine whether we should show the
* app icon instead of the small icon, and to fetch the app icon if needed.
@@ -153,37 +135,12 @@
return super.setImageIconAsync(icon);
}
- /** Whether the icon represents the app icon (instead of the small icon). */
- @RemotableViewMethod
- public void setShouldShowAppIcon(boolean shouldShowAppIcon) {
- if (Flags.notificationsUseAppIconInRow()) {
- if (mShouldShowAppIcon == shouldShowAppIcon) {
- return; // no change
- }
-
- mShouldShowAppIcon = shouldShowAppIcon;
- if (mShouldShowAppIcon) {
- adjustViewForAppIcon();
- } else {
- // Restore original padding and background if needed
- restoreViewForSmallIcon();
- }
- }
- }
-
/**
* Override padding and background from the view to display the app icon.
*/
private void adjustViewForAppIcon() {
removePadding();
-
- if (Flags.notificationsUseAppIconInRow()) {
- addWhiteBackground();
- } else {
- // No need to set the background for notification redesign, since the icon
- // factory already does that for us.
- removeBackground();
- }
+ removeBackground();
}
/**
@@ -221,21 +178,6 @@
setBackground(null);
}
- private void addWhiteBackground() {
- if (mOriginalBackground == null) {
- mOriginalBackground = getBackground();
- }
-
- // Make the background white in case the icon itself doesn't have one.
- ColorFilter colorFilter = new PorterDuffColorFilter(Color.WHITE,
- PorterDuff.Mode.SRC_ATOP);
-
- if (mOriginalBackground == null) {
- setBackground(getContext().getDrawable(R.drawable.notification_icon_circle));
- }
- getBackground().mutate().setColorFilter(colorFilter);
- }
-
private void restoreBackground() {
// NOTE: This will not work if the original background was null, but that's better than
// accidentally clearing the background. We expect that there's generally going to be one
diff --git a/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
index b6383d9..38685b6 100644
--- a/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
+++ b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
@@ -530,8 +530,26 @@
int rootViewTopOnWindow = mTmpCoords[1];
int windowLeftOnScreen = rootViewLeftOnScreen - rootViewLeftOnWindow;
int windowTopOnScreen = rootViewTopOnScreen - rootViewTopOnWindow;
- mCoordsOnWindow.set(
- Math.max(0, x - windowLeftOnScreen), Math.max(0, y - windowTopOnScreen));
+ // In some cases, app can have specific Window for Android UI components such as EditText.
+ // In this case, Window bounds != App bounds. Hence, instead of ensuring non-negative
+ // PopupWindow coords, app bounds should be used to limit the coords. For instance,
+ // ____ <- |
+ // | | |W1 & App bounds
+ // |___| |
+ // |W2 | | W2 has smaller bounds and contain EditText where PopupWindow will be opened.
+ // ---- <-|
+ // Here, we'll open PopupWindow upwards, but as PopupWindow is anchored based on W2, it
+ // will have negative Y coords. This negative Y is safe to use because it's still within app
+ // bounds. However, if it gets out of app bounds, we should clamp it to 0.
+ Rect appBounds = mContext
+ .getResources().getConfiguration().windowConfiguration.getAppBounds();
+ mCoordsOnWindow.set(x - windowLeftOnScreen, y - windowTopOnScreen);
+ if (rootViewLeftOnScreen + mCoordsOnWindow.x < appBounds.left) {
+ mCoordsOnWindow.x = 0;
+ }
+ if (rootViewTopOnScreen + mCoordsOnWindow.y < appBounds.top) {
+ mCoordsOnWindow.y = 0;
+ }
}
/**
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 212df02..0761a24 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -15,12 +15,14 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.operations.ComponentValue;
import com.android.internal.widget.remotecompose.core.operations.IntegerExpression;
import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
import com.android.internal.widget.remotecompose.core.operations.Theme;
-import com.android.internal.widget.remotecompose.core.operations.layout.ClickModifierEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.ClickModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd;
@@ -28,7 +30,11 @@
import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.OperationsListEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.TouchCancelModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.TouchDownModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.TouchUpModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
@@ -49,12 +55,12 @@
ArrayList<Operation> mOperations;
- RootLayoutComponent mRootLayoutComponent = null;
+ @Nullable RootLayoutComponent mRootLayoutComponent = null;
RemoteComposeState mRemoteComposeState = new RemoteComposeState();
- TimeVariables mTimeVariables = new TimeVariables();
+ @NonNull TimeVariables mTimeVariables = new TimeVariables();
// Semantic version of the document
- Version mVersion = new Version(0, 1, 0);
+ @NonNull Version mVersion = new Version(0, 1, 0);
String mContentDescription; // text description of the document (used for accessibility)
@@ -72,6 +78,8 @@
private final HashMap<Long, IntegerExpression> mIntegerExpressions = new HashMap<>();
+ private HashSet<Component> mAppliedTouchOperations = new HashSet<>();
+
private int mLastId = 1; // last component id when inflating the file
public String getContentDescription() {
@@ -272,6 +280,7 @@
*
* @return list of click areas in document coordinates
*/
+ @NonNull
public Set<ClickAreaRepresentation> getClickAreas() {
return mClickAreas;
}
@@ -281,6 +290,7 @@
*
* @return returns the root component if it exists, null otherwise
*/
+ @Nullable
public RootLayoutComponent getRootLayoutComponent() {
return mRootLayoutComponent;
}
@@ -298,6 +308,7 @@
* @param id component id
* @return the component if it exists, null otherwise
*/
+ @Nullable
public Component getComponent(int id) {
if (mRootLayoutComponent != null) {
return mRootLayoutComponent.getComponent(id);
@@ -310,6 +321,7 @@
*
* @return a standardized string representation of the component hierarchy
*/
+ @NonNull
public String displayHierarchy() {
StringSerializer serializer = new StringSerializer();
for (Operation op : mOperations) {
@@ -329,7 +341,8 @@
* @param targetId the id of the value to update with the expression
* @param context the current context
*/
- public void evaluateIntExpression(long expressionId, int targetId, RemoteContext context) {
+ public void evaluateIntExpression(
+ long expressionId, int targetId, @NonNull RemoteContext context) {
IntegerExpression expression = mIntegerExpressions.get(expressionId);
if (expression != null) {
int v = expression.evaluate(context);
@@ -337,22 +350,46 @@
}
}
- /** Callback interface for host actions */
- public interface ActionCallback {
- // TODO: add payload support
- void onAction(String name);
+ // ============== Haptic support ==================
+ public interface HapticEngine {
+ void haptic(int type);
}
- HashSet<ActionCallback> mActionListeners = new HashSet<ActionCallback>();
+ HapticEngine mHapticEngine;
+
+ public void setHapticEngine(HapticEngine engine) {
+ mHapticEngine = engine;
+ }
+
+ public void haptic(int type) {
+ if (mHapticEngine != null) {
+ mHapticEngine.haptic(type);
+ }
+ }
+
+ // ============== Haptic support ==================
+
+ public void appliedTouchOperation(Component operation) {
+ mAppliedTouchOperations.add(operation);
+ }
+
+ /** Callback interface for host actions */
+ public interface ActionCallback {
+ void onAction(String name, Object value);
+ }
+
+ @NonNull HashSet<ActionCallback> mActionListeners = new HashSet<ActionCallback>();
/**
* Warn action listeners for the given named action
*
* @param name the action name
+ * @param value a parameter to the action
*/
- public void runNamedAction(String name) {
+ public void runNamedAction(String name, Object value) {
+ // TODO: we might add an interface to group all valid parameter types
for (ActionCallback callback : mActionListeners) {
- callback.onAction(name);
+ callback.onAction(name, value);
}
}
@@ -374,8 +411,9 @@
void click(int id, String metadata);
}
- HashSet<ClickCallbacks> mClickListeners = new HashSet<>();
- HashSet<ClickAreaRepresentation> mClickAreas = new HashSet<>();
+ @NonNull HashSet<ClickCallbacks> mClickListeners = new HashSet<>();
+ @NonNull HashSet<TouchListener> mTouchListeners = new HashSet<>();
+ @NonNull HashSet<ClickAreaRepresentation> mClickAreas = new HashSet<>();
static class Version {
public final int major;
@@ -456,7 +494,7 @@
}
/** Load operations from the given buffer */
- public void initFromBuffer(RemoteComposeBuffer buffer) {
+ public void initFromBuffer(@NonNull RemoteComposeBuffer buffer) {
mOperations = new ArrayList<Operation>();
buffer.inflateFromBuffer(mOperations);
for (Operation op : mOperations) {
@@ -484,12 +522,16 @@
* @param operations flat list of operations
* @return nested list of operations / components
*/
- private ArrayList<Operation> inflateComponents(ArrayList<Operation> operations) {
+ @NonNull
+ private ArrayList<Operation> inflateComponents(@NonNull ArrayList<Operation> operations) {
Component currentComponent = null;
ArrayList<Component> components = new ArrayList<>();
ArrayList<Operation> finalOperationsList = new ArrayList<>();
ArrayList<Operation> ops = finalOperationsList;
ClickModifierOperation currentClickModifier = null;
+ TouchDownModifierOperation currentTouchDownModifier = null;
+ TouchUpModifierOperation currentTouchUpModifier = null;
+ TouchCancelModifierOperation currentTouchCancelModifier = null;
LoopOperation currentLoop = null;
mLastId = -1;
@@ -519,10 +561,30 @@
// TODO: refactor to add container <- component...
currentClickModifier = (ClickModifierOperation) o;
ops = currentClickModifier.getList();
- } else if (o instanceof ClickModifierEnd) {
+ } else if (o instanceof TouchDownModifierOperation) {
+ currentTouchDownModifier = (TouchDownModifierOperation) o;
+ ops = currentTouchDownModifier.getList();
+ } else if (o instanceof TouchUpModifierOperation) {
+ currentTouchUpModifier = (TouchUpModifierOperation) o;
+ ops = currentTouchUpModifier.getList();
+ } else if (o instanceof TouchCancelModifierOperation) {
+ currentTouchCancelModifier = (TouchCancelModifierOperation) o;
+ ops = currentTouchCancelModifier.getList();
+ } else if (o instanceof OperationsListEnd) {
ops = currentComponent.getList();
- ops.add(currentClickModifier);
- currentClickModifier = null;
+ if (currentClickModifier != null) {
+ ops.add(currentClickModifier);
+ currentClickModifier = null;
+ } else if (currentTouchDownModifier != null) {
+ ops.add(currentTouchDownModifier);
+ currentTouchDownModifier = null;
+ } else if (currentTouchUpModifier != null) {
+ ops.add(currentTouchUpModifier);
+ currentTouchUpModifier = null;
+ } else if (currentTouchCancelModifier != null) {
+ ops.add(currentTouchCancelModifier);
+ currentTouchCancelModifier = null;
+ }
} else if (o instanceof LoopOperation) {
currentLoop = (LoopOperation) o;
ops = currentLoop.getList();
@@ -541,9 +603,9 @@
return ops;
}
- private HashMap<Integer, Component> mComponentMap = new HashMap<Integer, Component>();
+ @NonNull private HashMap<Integer, Component> mComponentMap = new HashMap<Integer, Component>();
- private void registerVariables(RemoteContext context, ArrayList<Operation> list) {
+ private void registerVariables(RemoteContext context, @NonNull ArrayList<Operation> list) {
for (Operation op : list) {
if (op instanceof VariableSupport) {
((VariableSupport) op).updateVariables(context);
@@ -578,7 +640,7 @@
* Called when an initialization is needed, allowing the document to eg load resources / cache
* them.
*/
- public void initializeContext(RemoteContext context) {
+ public void initializeContext(@NonNull RemoteContext context) {
mRemoteComposeState.reset();
mRemoteComposeState.setContext(context);
mClickAreas.clear();
@@ -651,6 +713,15 @@
}
/**
+ * Called by commands to listen to touch events
+ *
+ * @param listener
+ */
+ public void addTouchListener(TouchListener listener) {
+ mTouchListeners.add(listener);
+ }
+
+ /**
* Add a click listener. This will get called when a click is detected on the document
*
* @param callback called when a click area has been hit, passing the click are id and metadata.
@@ -664,6 +735,7 @@
*
* @return set of click listeners
*/
+ @NonNull
public HashSet<CoreDocument.ClickCallbacks> getClickListeners() {
return mClickListeners;
}
@@ -700,12 +772,98 @@
}
/** Warn click listeners when a click area is activated */
- private void warnClickListeners(ClickAreaRepresentation clickArea) {
+ private void warnClickListeners(@NonNull ClickAreaRepresentation clickArea) {
for (ClickCallbacks listener : mClickListeners) {
listener.click(clickArea.mId, clickArea.mMetadata);
}
}
+ /**
+ * Returns true if the document has touch listeners
+ *
+ * @return true if the document needs to react to touch events
+ */
+ public boolean hasTouchListener() {
+ boolean hasComponentsTouchListeners =
+ mRootLayoutComponent != null && mRootLayoutComponent.hasTouchListeners();
+ return hasComponentsTouchListeners || !mTouchListeners.isEmpty();
+ }
+
+ // TODO support velocity estimate support, support regions
+ /**
+ * Support touch drag events on commands supporting touch
+ *
+ * @param x position of touch
+ * @param y position of touch
+ */
+ public boolean touchDrag(RemoteContext context, float x, float y) {
+ context.loadFloat(RemoteContext.ID_TOUCH_POS_X, x);
+ context.loadFloat(RemoteContext.ID_TOUCH_POS_Y, y);
+ for (TouchListener clickArea : mTouchListeners) {
+ clickArea.touchDrag(context, x, y);
+ }
+ if (!mTouchListeners.isEmpty()) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Support touch down events on commands supporting touch
+ *
+ * @param x position of touch
+ * @param y position of touch
+ */
+ public void touchDown(RemoteContext context, float x, float y) {
+ context.loadFloat(RemoteContext.ID_TOUCH_POS_X, x);
+ context.loadFloat(RemoteContext.ID_TOUCH_POS_Y, y);
+ for (TouchListener clickArea : mTouchListeners) {
+ clickArea.touchDown(context, x, y);
+ }
+ if (mRootLayoutComponent != null) {
+ mRootLayoutComponent.onTouchDown(context, this, x, y);
+ }
+ mRepaintNext = 1;
+ }
+
+ /**
+ * Support touch up events on commands supporting touch
+ *
+ * @param x position of touch
+ * @param y position of touch
+ */
+ public void touchUp(RemoteContext context, float x, float y, float dx, float dy) {
+ context.loadFloat(RemoteContext.ID_TOUCH_POS_X, x);
+ context.loadFloat(RemoteContext.ID_TOUCH_POS_Y, y);
+ for (TouchListener clickArea : mTouchListeners) {
+ clickArea.touchUp(context, x, y, dx, dy);
+ }
+ if (mRootLayoutComponent != null) {
+ for (Component component : mAppliedTouchOperations) {
+ component.onTouchUp(context, this, x, y, true);
+ }
+ mAppliedTouchOperations.clear();
+ }
+ mRepaintNext = 1;
+ }
+
+ /**
+ * Support touch cancel events on commands supporting touch
+ *
+ * @param x position of touch
+ * @param y position of touch
+ */
+ public void touchCancel(RemoteContext context, float x, float y, float dx, float dy) {
+ if (mRootLayoutComponent != null) {
+ for (Component component : mAppliedTouchOperations) {
+ component.onTouchCancel(context, this, x, y, true);
+ }
+ mAppliedTouchOperations.clear();
+ }
+ mRepaintNext = 1;
+ }
+
+ @NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
@@ -721,12 +879,22 @@
*
* @return array of named colors or null
*/
+ @Nullable
public String[] getNamedColors() {
+ return getNamedVariables(NamedVariable.COLOR_TYPE);
+ }
+
+ /**
+ * Gets the names of all named Variables.
+ *
+ * @return array of named variables or null
+ */
+ public String[] getNamedVariables(int type) {
int count = 0;
for (Operation op : mOperations) {
if (op instanceof NamedVariable) {
NamedVariable n = (NamedVariable) op;
- if (n.mVarType == NamedVariable.COLOR_TYPE) {
+ if (n.mVarType == type) {
count++;
}
}
@@ -739,7 +907,7 @@
for (Operation op : mOperations) {
if (op instanceof NamedVariable) {
NamedVariable n = (NamedVariable) op;
- if (n.mVarType == NamedVariable.COLOR_TYPE) {
+ if (n.mVarType == type) {
ret[i++] = n.mVarName;
}
}
@@ -770,10 +938,9 @@
* @param context the provided PaintContext
* @param theme the theme we want to use for this document.
*/
- public void paint(RemoteContext context, int theme) {
+ public void paint(@NonNull RemoteContext context, int theme) {
context.getPaintContext().clearNeedsRepaint();
context.mMode = RemoteContext.ContextMode.UNSET;
-
// current theme starts as UNSPECIFIED, until a Theme setter
// operation gets executed and modify it.
context.setTheme(Theme.UNSPECIFIED);
@@ -807,6 +974,7 @@
}
// TODO -- this should be specifically about applying animation, not paint
mRootLayoutComponent.paint(context.getPaintContext());
+ context.mPaintContext.reset();
// TODO -- should be able to remove this
mRootLayoutComponent.updateVariables(context);
if (DEBUG) {
@@ -843,6 +1011,7 @@
}
}
+ @NonNull
public String[] getStats() {
ArrayList<String> ret = new ArrayList<>();
WireBuffer buffer = new WireBuffer();
@@ -875,7 +1044,7 @@
return ret.toArray(new String[0]);
}
- private int sizeOfComponent(Operation com, WireBuffer tmp) {
+ private int sizeOfComponent(@NonNull Operation com, @NonNull WireBuffer tmp) {
tmp.reset(100);
com.write(tmp);
int size = tmp.getSize();
@@ -883,7 +1052,8 @@
return size;
}
- private int addChildren(Component base, HashMap<String, int[]> map, WireBuffer tmp) {
+ private int addChildren(
+ @NonNull Component base, @NonNull HashMap<String, int[]> map, @NonNull WireBuffer tmp) {
int count = base.mList.size();
for (Operation mOperation : base.mList) {
Class<? extends Operation> c = mOperation.getClass();
@@ -903,6 +1073,7 @@
return count;
}
+ @NonNull
public String toNestedString() {
StringBuilder ret = new StringBuilder();
for (Operation mOperation : mOperations) {
@@ -915,7 +1086,8 @@
return ret.toString();
}
- private void toNestedString(Component base, StringBuilder ret, String indent) {
+ private void toNestedString(
+ @NonNull Component base, @NonNull StringBuilder ret, String indent) {
for (Operation mOperation : base.mList) {
ret.append(mOperation.toString());
ret.append("\n");
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operation.java b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
index 9f565a2..f1885f9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.Nullable;
+
/** Base interface for RemoteCompose operations */
public interface Operation {
@@ -29,5 +31,6 @@
void apply(RemoteContext context);
/** Debug utility to display an operation + indentation */
+ @Nullable
String deepToString(String indent);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index acebe07..53c45fa 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.operations.BitmapData;
import com.android.internal.widget.remotecompose.core.operations.ClickArea;
import com.android.internal.widget.remotecompose.core.operations.ClipPath;
@@ -65,15 +67,19 @@
import com.android.internal.widget.remotecompose.core.operations.TextMeasure;
import com.android.internal.widget.remotecompose.core.operations.TextMerge;
import com.android.internal.widget.remotecompose.core.operations.Theme;
+import com.android.internal.widget.remotecompose.core.operations.TouchExpression;
import com.android.internal.widget.remotecompose.core.operations.layout.CanvasContent;
-import com.android.internal.widget.remotecompose.core.operations.layout.ClickModifierEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.ClickModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStart;
import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponentContent;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.OperationsListEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.TouchCancelModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.TouchDownModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.TouchUpModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.animation.AnimationSpec;
import com.android.internal.widget.remotecompose.core.operations.layout.managers.BoxLayout;
import com.android.internal.widget.remotecompose.core.operations.layout.managers.CanvasLayout;
@@ -85,15 +91,19 @@
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BorderModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ClipRectModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentVisibilityOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.GraphicsLayerModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HeightModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HostActionOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HostNamedActionOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.OffsetModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RoundedClipRectModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueFloatChangeActionOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueIntegerChangeActionOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueIntegerExpressionChangeActionOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueStringChangeActionOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.WidthModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ZIndexModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.utilities.IntMap;
import com.android.internal.widget.remotecompose.core.types.BooleanConstant;
import com.android.internal.widget.remotecompose.core.types.IntegerConstant;
@@ -165,6 +175,7 @@
public static final int DATA_MAP_LOOKUP = 154;
public static final int TEXT_MEASURE = 155;
public static final int TEXT_LENGTH = 156;
+ public static final int TOUCH_EXPRESSION = 157;
///////////////////////////////////////// ======================
@@ -194,8 +205,16 @@
public static final int MODIFIER_ROUNDED_CLIP_RECT = 54;
public static final int MODIFIER_CLICK = 59;
+ public static final int MODIFIER_TOUCH_DOWN = 219;
+ public static final int MODIFIER_TOUCH_UP = 220;
+ public static final int MODIFIER_TOUCH_CANCEL = 225;
- public static final int MODIFIER_CLICK_END = 214;
+ public static final int OPERATIONS_LIST_END = 214;
+
+ public static final int MODIFIER_OFFSET = 221;
+ public static final int MODIFIER_ZINDEX = 223;
+ public static final int MODIFIER_GRAPHICS_LAYER = 224;
+
public static final int LOOP_START = 215;
public static final int LOOP_END = 216;
@@ -206,12 +225,13 @@
public static final int VALUE_INTEGER_CHANGE_ACTION = 212;
public static final int VALUE_STRING_CHANGE_ACTION = 213;
public static final int VALUE_INTEGER_EXPRESSION_CHANGE_ACTION = 218;
+ public static final int VALUE_FLOAT_CHANGE_ACTION = 222;
public static final int ANIMATION_SPEC = 14;
public static final int COMPONENT_VALUE = 150;
- public static UniqueIntMap<CompanionOperation> map = new UniqueIntMap<>();
+ @NonNull public static UniqueIntMap<CompanionOperation> map = new UniqueIntMap<>();
static class UniqueIntMap<T> extends IntMap<T> {
@Override
@@ -289,8 +309,16 @@
map.put(MODIFIER_ROUNDED_CLIP_RECT, RoundedClipRectModifierOperation::read);
map.put(MODIFIER_CLIP_RECT, ClipRectModifierOperation::read);
map.put(MODIFIER_CLICK, ClickModifierOperation::read);
- map.put(MODIFIER_CLICK_END, ClickModifierEnd::read);
+ map.put(MODIFIER_TOUCH_DOWN, TouchDownModifierOperation::read);
+ map.put(MODIFIER_TOUCH_UP, TouchUpModifierOperation::read);
+ map.put(MODIFIER_TOUCH_CANCEL, TouchCancelModifierOperation::read);
map.put(MODIFIER_VISIBILITY, ComponentVisibilityOperation::read);
+ map.put(MODIFIER_OFFSET, OffsetModifierOperation::read);
+ map.put(MODIFIER_ZINDEX, ZIndexModifierOperation::read);
+ map.put(MODIFIER_GRAPHICS_LAYER, GraphicsLayerModifierOperation::read);
+
+ map.put(OPERATIONS_LIST_END, OperationsListEnd::read);
+
map.put(HOST_ACTION, HostActionOperation::read);
map.put(HOST_NAMED_ACTION, HostNamedActionOperation::read);
map.put(VALUE_INTEGER_CHANGE_ACTION, ValueIntegerChangeActionOperation::read);
@@ -298,6 +326,7 @@
VALUE_INTEGER_EXPRESSION_CHANGE_ACTION,
ValueIntegerExpressionChangeActionOperation::read);
map.put(VALUE_STRING_CHANGE_ACTION, ValueStringChangeActionOperation::read);
+ map.put(VALUE_FLOAT_CHANGE_ACTION, ValueFloatChangeActionOperation::read);
map.put(LAYOUT_ROOT, RootLayoutComponent::read);
map.put(LAYOUT_CONTENT, LayoutComponentContent::read);
@@ -315,5 +344,6 @@
map.put(DATA_MAP_LOOKUP, DataMapLookup::read);
map.put(TEXT_MEASURE, TextMeasure::read);
map.put(TEXT_LENGTH, TextLength::read);
+ map.put(TOUCH_EXPRESSION, TouchExpression::read);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
index 13d6f78..1a71afe 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
@@ -271,4 +271,24 @@
public void needsRepaint() {
mNeedsRepaint = true;
}
+
+ public abstract void startGraphicsLayer(int w, int h);
+
+ public abstract void setGraphicsLayer(
+ float scaleX,
+ float scaleY,
+ float rotationX,
+ float rotationY,
+ float rotationZ,
+ float shadowElevation,
+ float transformOriginX,
+ float transformOriginY,
+ float alpha,
+ int renderEffectId);
+
+ public abstract void endGraphicsLayer();
+
+ public boolean isVisualDebug() {
+ return mContext.isVisualDebug();
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
index 9b7b50f..049e477 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+
/**
* PaintOperation interface, used for operations aimed at painting (while any operation _can_ paint,
* this make it a little more explicit)
@@ -22,7 +24,7 @@
public abstract class PaintOperation implements Operation {
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
if (context.getMode() == RemoteContext.ContextMode.PAINT) {
PaintContext paintContext = context.getPaintContext();
if (paintContext != null) {
@@ -31,6 +33,7 @@
}
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Platform.java b/core/java/com/android/internal/widget/remotecompose/core/Platform.java
index 6725e7e..7fbcfae 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Platform.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Platform.java
@@ -15,16 +15,30 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.Nullable;
+
/** Services that are needed to be provided by the platform during encoding. */
public interface Platform {
+ @Nullable
byte[] imageToByteArray(Object image);
int getImageWidth(Object image);
int getImageHeight(Object image);
+ @Nullable
float[] pathToFloatArray(Object path);
+ enum LogCategory {
+ DEBUG,
+ INFO,
+ WARN,
+ ERROR,
+ TODO,
+ }
+
+ void log(LogCategory category, String message);
+
Platform None =
new Platform() {
@Override
@@ -46,5 +60,8 @@
public float[] pathToFloatArray(Object path) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public void log(LogCategory category, String message) {}
};
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index 5b5adc2..7d9439d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.operations.BitmapData;
import com.android.internal.widget.remotecompose.core.operations.ClickArea;
import com.android.internal.widget.remotecompose.core.operations.ClipPath;
@@ -64,6 +67,7 @@
import com.android.internal.widget.remotecompose.core.operations.TextMeasure;
import com.android.internal.widget.remotecompose.core.operations.TextMerge;
import com.android.internal.widget.remotecompose.core.operations.Theme;
+import com.android.internal.widget.remotecompose.core.operations.TouchExpression;
import com.android.internal.widget.remotecompose.core.operations.Utils;
import com.android.internal.widget.remotecompose.core.operations.layout.CanvasContent;
import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd;
@@ -81,8 +85,11 @@
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BackgroundModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BorderModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ClipRectModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.GraphicsLayerModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.OffsetModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RoundedClipRectModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ZIndexModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap;
import com.android.internal.widget.remotecompose.core.operations.utilities.easing.FloatAnimation;
@@ -111,7 +118,7 @@
public static final int EASING_EASE_OUT_BOUNCE = FloatAnimation.EASE_OUT_BOUNCE;
public static final int EASING_EASE_OUT_ELASTIC = FloatAnimation.EASE_OUT_ELASTIC;
WireBuffer mBuffer = new WireBuffer();
- Platform mPlatform = null;
+ @Nullable Platform mPlatform = null;
RemoteComposeState mRemoteComposeState;
private static final boolean DEBUG = false;
@@ -143,6 +150,7 @@
return mLastComponentId;
}
+ @Nullable
public Platform getPlatform() {
return mPlatform;
}
@@ -172,7 +180,11 @@
* @param capabilities bitmask indicating needed capabilities (unused for now)
*/
public void header(
- int width, int height, String contentDescription, float density, long capabilities) {
+ int width,
+ int height,
+ @Nullable String contentDescription,
+ float density,
+ long capabilities) {
Header.apply(mBuffer, width, height, density, capabilities);
int contentDescriptionId = 0;
if (contentDescription != null) {
@@ -219,7 +231,7 @@
int dstTop,
int dstRight,
int dstBottom,
- String contentDescription) {
+ @Nullable String contentDescription) {
int imageId = mRemoteComposeState.dataGetId(image);
if (imageId == -1) {
imageId = mRemoteComposeState.cacheData(image);
@@ -267,7 +279,7 @@
*
* @param text the string to inject in the buffer
*/
- public int addText(String text) {
+ public int addText(@NonNull String text) {
int id = mRemoteComposeState.dataGetId(text);
if (id == -1) {
id = mRemoteComposeState.cacheData(text);
@@ -289,12 +301,12 @@
*/
public void addClickArea(
int id,
- String contentDescription,
+ @Nullable String contentDescription,
float left,
float top,
float right,
float bottom,
- String metadata) {
+ @Nullable String metadata) {
int contentDescriptionId = 0;
if (contentDescription != null) {
contentDescriptionId = addText(contentDescription);
@@ -380,7 +392,7 @@
float top,
float right,
float bottom,
- String contentDescription) {
+ @Nullable String contentDescription) {
int imageId = mRemoteComposeState.dataGetId(image);
if (imageId == -1) {
imageId = mRemoteComposeState.cacheData(image);
@@ -411,7 +423,7 @@
float top,
float right,
float bottom,
- String contentDescription) {
+ @Nullable String contentDescription) {
int contentDescriptionId = 0;
if (contentDescription != null) {
contentDescriptionId = addText(contentDescription);
@@ -445,7 +457,7 @@
float dstBottom,
int scaleType,
float scaleFactor,
- String contentDescription) {
+ @Nullable String contentDescription) {
int imageId = mRemoteComposeState.dataGetId(image);
if (imageId == -1) {
imageId = mRemoteComposeState.cacheData(image);
@@ -500,7 +512,7 @@
* @param image drawScaledBitmap
* @return id of the image useful with
*/
- public int addBitmap(Object image, String name) {
+ public int addBitmap(Object image, @NonNull String name) {
int imageId = mRemoteComposeState.dataGetId(image);
if (imageId == -1) {
imageId = mRemoteComposeState.cacheData(image);
@@ -521,7 +533,7 @@
* @param id of the Bitmap
* @param name Name of the color
*/
- public void setBitmapName(int id, String name) {
+ public void setBitmapName(int id, @NonNull String name) {
NamedVariable.apply(mBuffer, id, NamedVariable.IMAGE_TYPE, name);
}
@@ -551,7 +563,7 @@
float dstBottom,
int scaleType,
float scaleFactor,
- String contentDescription) {
+ @Nullable String contentDescription) {
int contentDescriptionId = 0;
if (contentDescription != null) {
contentDescriptionId = addText(contentDescription);
@@ -669,7 +681,7 @@
* @param hOffset The distance along the path to add to the text's starting position
* @param vOffset The distance above(-) or below(+) the path to position the text
*/
- public void addDrawTextOnPath(String text, Object path, float hOffset, float vOffset) {
+ public void addDrawTextOnPath(@NonNull String text, Object path, float hOffset, float vOffset) {
int pathId = mRemoteComposeState.dataGetId(path);
if (pathId == -1) { // never been seen before
pathId = addPathData(path);
@@ -692,7 +704,7 @@
* @param rtl Draw RTTL
*/
public void addDrawTextRun(
- String text,
+ @NonNull String text,
int start,
int end,
int contextStart,
@@ -749,7 +761,8 @@
* @param panY position text -1.0=above, 0.0=center, 1.0=below, Nan=baseline
* @param flags 1 = RTL
*/
- public void drawTextAnchored(String text, float x, float y, float panX, float panY, int flags) {
+ public void drawTextAnchored(
+ @NonNull String text, float x, float y, float panX, float panY, int flags) {
int textId = addText(text);
DrawTextAnchored.apply(mBuffer, textId, x, y, panX, panY, flags);
}
@@ -760,7 +773,7 @@
* @param text
* @return
*/
- public int createTextId(String text) {
+ public int createTextId(@NonNull String text) {
return addText(text);
}
@@ -891,7 +904,7 @@
*
* @param paint
*/
- public void addPaint(PaintBundle paint) {
+ public void addPaint(@NonNull PaintBundle paint) {
PaintData.apply(mBuffer, paint);
}
@@ -912,7 +925,8 @@
}
}
- public static void readNextOperation(WireBuffer buffer, ArrayList<Operation> operations) {
+ public static void readNextOperation(
+ @NonNull WireBuffer buffer, ArrayList<Operation> operations) {
int opId = buffer.readByte();
if (DEBUG) {
Utils.log(">> " + opId);
@@ -924,6 +938,7 @@
operation.read(buffer, operations);
}
+ @NonNull
RemoteComposeBuffer copy() {
ArrayList<Operation> operations = new ArrayList<>();
inflateFromBuffer(operations);
@@ -935,33 +950,38 @@
Theme.apply(mBuffer, theme);
}
+ @NonNull
static String version() {
return "v1.0";
}
- public static RemoteComposeBuffer fromFile(String path, RemoteComposeState remoteComposeState)
- throws IOException {
+ @NonNull
+ public static RemoteComposeBuffer fromFile(
+ @NonNull String path, RemoteComposeState remoteComposeState) throws IOException {
RemoteComposeBuffer buffer = new RemoteComposeBuffer(remoteComposeState);
read(new File(path), buffer);
return buffer;
}
- public RemoteComposeBuffer fromFile(File file, RemoteComposeState remoteComposeState)
+ @NonNull
+ public RemoteComposeBuffer fromFile(@NonNull File file, RemoteComposeState remoteComposeState)
throws IOException {
RemoteComposeBuffer buffer = new RemoteComposeBuffer(remoteComposeState);
read(file, buffer);
return buffer;
}
+ @NonNull
public static RemoteComposeBuffer fromInputStream(
- InputStream inputStream, RemoteComposeState remoteComposeState) {
+ @NonNull InputStream inputStream, RemoteComposeState remoteComposeState) {
RemoteComposeBuffer buffer = new RemoteComposeBuffer(remoteComposeState);
read(inputStream, buffer);
return buffer;
}
+ @NonNull
RemoteComposeBuffer copyFromOperations(
- ArrayList<Operation> operations, RemoteComposeBuffer buffer) {
+ @NonNull ArrayList<Operation> operations, @NonNull RemoteComposeBuffer buffer) {
for (Operation operation : operations) {
operation.write(buffer.mBuffer);
@@ -975,7 +995,7 @@
* @param buffer a RemoteComposeBuffer
* @param file a target file
*/
- public void write(RemoteComposeBuffer buffer, File file) {
+ public void write(@NonNull RemoteComposeBuffer buffer, @NonNull File file) {
try {
FileOutputStream fd = new FileOutputStream(file);
fd.write(buffer.mBuffer.getBuffer(), 0, buffer.mBuffer.getSize());
@@ -986,12 +1006,12 @@
}
}
- static void read(File file, RemoteComposeBuffer buffer) throws IOException {
+ static void read(@NonNull File file, @NonNull RemoteComposeBuffer buffer) throws IOException {
FileInputStream fd = new FileInputStream(file);
read(fd, buffer);
}
- public static void read(InputStream fd, RemoteComposeBuffer buffer) {
+ public static void read(@NonNull InputStream fd, @NonNull RemoteComposeBuffer buffer) {
try {
byte[] bytes = readAllBytes(fd);
buffer.reset(bytes.length);
@@ -1002,7 +1022,7 @@
}
}
- private static byte[] readAllBytes(InputStream is) throws IOException {
+ private static byte[] readAllBytes(@NonNull InputStream is) throws IOException {
byte[] buff = new byte[32 * 1024]; // moderate size buff to start
int red = 0;
while (true) {
@@ -1176,20 +1196,59 @@
* @param value A RPN style float operation i.e. "4, 3, ADD" outputs 7
* @return NaN id of the result of the calculation
*/
- public float addAnimatedFloat(float... value) {
+ public float addAnimatedFloat(@NonNull float... value) {
int id = mRemoteComposeState.cacheData(value);
FloatExpression.apply(mBuffer, id, value, null);
return Utils.asNan(id);
}
/**
+ * Add a touch handle system
+ *
+ * @param value the default value
+ * @param min the minimum value
+ * @param max the maximum value
+ * @param velocityId the id for the velocity TODO support in v2
+ * @param exp The Float Expression
+ * @param touchMode the touch up handling behaviour
+ * @param touchSpec the touch up handling parameters
+ * @param easingSpec the easing parameter TODO support in v2
+ * @return id of the variable to be used controlled by touch handling
+ */
+ public float addTouchExpression(
+ float value,
+ float min,
+ float max,
+ float velocityId,
+ int touchEffects,
+ float[] exp,
+ int touchMode,
+ float[] touchSpec,
+ float[] easingSpec) {
+ int id = mRemoteComposeState.nextId();
+ TouchExpression.apply(
+ mBuffer,
+ id,
+ value,
+ min,
+ max,
+ velocityId,
+ touchEffects,
+ exp,
+ touchMode,
+ touchSpec,
+ easingSpec);
+ return Utils.asNan(id);
+ }
+
+ /**
* Add a float that is a computation based on variables. see packAnimation
*
* @param value A RPN style float operation i.e. "4, 3, ADD" outputs 7
* @param animation Array of floats that represents animation
* @return NaN id of the result of the calculation
*/
- public float addAnimatedFloat(float[] value, float[] animation) {
+ public float addAnimatedFloat(@NonNull float[] value, float[] animation) {
int id = mRemoteComposeState.cacheData(value);
FloatExpression.apply(mBuffer, id, value, animation);
return Utils.asNan(id);
@@ -1228,7 +1287,7 @@
* @param values
* @return the id of the array, encoded as a float NaN
*/
- public float addFloatArray(float[] values) {
+ public float addFloatArray(@NonNull float[] values) {
int id = mRemoteComposeState.cacheData(values, NanMap.TYPE_ARRAY);
DataListFloat.apply(mBuffer, id, values);
return Utils.asNan(id);
@@ -1240,7 +1299,7 @@
* @param values array of floats to be individually stored
* @return id of the list
*/
- public float addFloatList(float[] values) {
+ public float addFloatList(@NonNull float[] values) {
int[] listId = new int[values.length];
for (int i = 0; i < listId.length; i++) {
listId[i] = mRemoteComposeState.cacheFloat(values[i]);
@@ -1255,7 +1314,7 @@
* @param listId array id to be stored
* @return id of the list
*/
- public float addList(int[] listId) {
+ public float addList(@NonNull int[] listId) {
int id = mRemoteComposeState.cacheData(listId, NanMap.TYPE_ARRAY);
DataListIds.apply(mBuffer, id, listId);
return Utils.asNan(id);
@@ -1268,7 +1327,7 @@
* @param values
* @return the id of the map, encoded as a float NaN
*/
- public float addFloatMap(String[] keys, float[] values) {
+ public float addFloatMap(@NonNull String[] keys, @NonNull float[] values) {
int[] listId = new int[values.length];
byte[] type = new byte[values.length];
for (int i = 0; i < listId.length; i++) {
@@ -1286,7 +1345,7 @@
* @param listId
* @return the id of the map, encoded as a float NaN
*/
- public int addMap(String[] keys, byte[] types, int[] listId) {
+ public int addMap(@NonNull String[] keys, byte[] types, int[] listId) {
int id = mRemoteComposeState.cacheData(listId, NanMap.TYPE_ARRAY);
DataMapIds.apply(mBuffer, id, keys, types, listId);
return id;
@@ -1331,7 +1390,7 @@
* @param value array of values to calculate maximum 32
* @return the id as an integer
*/
- public int addIntegerExpression(int mask, int[] value) {
+ public int addIntegerExpression(int mask, @NonNull int[] value) {
int id = mRemoteComposeState.cacheData(value);
IntegerExpression.apply(mBuffer, id, mask, value);
return id;
@@ -1474,7 +1533,7 @@
* @param id of the color
* @param name Name of the color
*/
- public void setColorName(int id, String name) {
+ public void setColorName(int id, @NonNull String name) {
NamedVariable.apply(mBuffer, id, NamedVariable.COLOR_TYPE, name);
}
@@ -1484,7 +1543,7 @@
* @param id of the string
* @param name name of the string
*/
- public void setStringName(int id, String name) {
+ public void setStringName(int id, @NonNull String name) {
NamedVariable.apply(mBuffer, id, NamedVariable.STRING_TYPE, name);
}
@@ -1576,6 +1635,72 @@
}
/**
+ * Add an offset modifier
+ *
+ * @param x x offset
+ * @param y y offset
+ */
+ public void addModifierOffset(float x, float y) {
+ OffsetModifierOperation.apply(mBuffer, x, y);
+ }
+
+ /**
+ * Add a zIndex modifier
+ *
+ * @param value z-Index value
+ */
+ public void addModifierZIndex(float value) {
+ ZIndexModifierOperation.apply(mBuffer, value);
+ }
+
+ /**
+ * Add a graphics layer
+ *
+ * @param scaleX
+ * @param scaleY
+ * @param rotationX
+ * @param rotationY
+ * @param rotationZ
+ * @param shadowElevation
+ * @param transformOriginX
+ * @param transformOriginY
+ */
+ public void addModifierGraphicsLayer(
+ float scaleX,
+ float scaleY,
+ float rotationX,
+ float rotationY,
+ float rotationZ,
+ float shadowElevation,
+ float transformOriginX,
+ float transformOriginY,
+ float alpha,
+ float cameraDistance,
+ int blendMode,
+ int spotShadowColorId,
+ int ambientShadowColorId,
+ int colorFilterId,
+ int renderEffectId) {
+ GraphicsLayerModifierOperation.apply(
+ mBuffer,
+ scaleX,
+ scaleY,
+ rotationX,
+ rotationY,
+ rotationZ,
+ shadowElevation,
+ transformOriginX,
+ transformOriginY,
+ alpha,
+ cameraDistance,
+ blendMode,
+ spotShadowColorId,
+ ambientShadowColorId,
+ colorFilterId,
+ renderEffectId);
+ }
+
+ /**
* Sets the clip based on rounded clip rect
*
* @param topStart
@@ -1721,7 +1846,8 @@
float fontSize,
int fontStyle,
float fontWeight,
- String fontFamily) {
+ @Nullable String fontFamily,
+ int textAlign) {
mLastComponentId = getComponentId(componentId);
int fontFamilyId = -1;
if (fontFamily != null) {
@@ -1736,6 +1862,11 @@
fontSize,
fontStyle,
fontWeight,
- fontFamilyId);
+ fontFamilyId,
+ textAlign);
+ }
+
+ public int createID(int type) {
+ return mRemoteComposeState.nextId(type);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
index 51445f2..3039328 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.operations.utilities.ArrayAccess;
import com.android.internal.widget.remotecompose.core.operations.utilities.CollectionsAccess;
import com.android.internal.widget.remotecompose.core.operations.utilities.DataMap;
@@ -50,10 +53,11 @@
private final boolean[] mDataOverride = new boolean[MAX_DATA];
private final boolean[] mIntegerOverride = new boolean[MAX_DATA];
+ private final boolean[] mFloatOverride = new boolean[MAX_DATA];
private int mNextId = START_ID;
- private int[] mIdMaps = new int[] {START_ID, NanMap.START_VAR, NanMap.START_ARRAY};
- private RemoteContext mRemoteContext = null;
+ @NonNull private int[] mIdMaps = new int[] {START_ID, NanMap.START_VAR, NanMap.START_ARRAY};
+ @Nullable private RemoteContext mRemoteContext = null;
/**
* Get Object based on id. The system will cache things like bitmaps Paths etc. They can be
@@ -62,6 +66,7 @@
* @param id
* @return
*/
+ @Nullable
public Object getFromId(int id) {
return mIntDataMap.get(id);
}
@@ -158,10 +163,28 @@
/** Insert an float item in the cache */
public void updateFloat(int id, float value) {
+ if (!mFloatOverride[id]) {
+ float previous = mFloatMap.get(id);
+ if (previous != value) {
+ mFloatMap.put(id, value);
+ mIntegerMap.put(id, (int) value);
+ updateListeners(id);
+ }
+ }
+ }
+
+ /**
+ * Adds a float Override.
+ *
+ * @param id
+ * @param value the new value
+ */
+ public void overrideFloat(int id, float value) {
float previous = mFloatMap.get(id);
if (previous != value) {
mFloatMap.put(id, value);
mIntegerMap.put(id, (int) value);
+ mFloatOverride[id] = true;
updateListeners(id);
}
}
@@ -294,6 +317,16 @@
}
/**
+ * Clear the float override
+ *
+ * @param id the float id to clear
+ */
+ public void clearFloatOverride(int id) {
+ mFloatOverride[id] = false;
+ updateListeners(id);
+ }
+
+ /**
* Method to determine if a cached value has been written to the documents WireBuffer based on
* its id.
*/
@@ -322,7 +355,8 @@
}
/**
- * Get the next available id
+ * Get the next available id 0 is normal (float,int,String,color) 1 is VARIABLES 2 is
+ * collections
*
* @return
*/
@@ -342,8 +376,8 @@
mNextId = id;
}
- IntMap<ArrayList<VariableSupport>> mVarListeners = new IntMap<>();
- ArrayList<VariableSupport> mAllVarListeners = new ArrayList<>();
+ @NonNull IntMap<ArrayList<VariableSupport>> mVarListeners = new IntMap<>();
+ @NonNull ArrayList<VariableSupport> mAllVarListeners = new ArrayList<>();
private void add(int id, VariableSupport variableSupport) {
ArrayList<VariableSupport> v = mVarListeners.get(id);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index 1066e7d..23cc5b8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.operations.FloatExpression;
import com.android.internal.widget.remotecompose.core.operations.ShaderData;
import com.android.internal.widget.remotecompose.core.operations.Theme;
@@ -40,10 +42,12 @@
protected CoreDocument mDocument;
public RemoteComposeState mRemoteComposeState;
long mStart = System.nanoTime(); // todo This should be set at a hi level
- protected PaintContext mPaintContext = null;
+ @Nullable protected PaintContext mPaintContext = null;
+ protected float mDensity = 2.75f;
+
ContextMode mMode = ContextMode.UNSET;
- boolean mDebug = false;
+ int mDebug = 0;
private int mTheme = Theme.UNSPECIFIED;
@@ -56,6 +60,14 @@
public Component lastComponent;
public long currentTime = 0L;
+ public float getDensity() {
+ return mDensity;
+ }
+
+ public void setDensity(float density) {
+ mDensity = density;
+ }
+
public boolean isAnimationEnabled() {
return mAnimate;
}
@@ -173,12 +185,22 @@
public abstract void runAction(int id, String metadata);
- public abstract void runNamedAction(int textId);
+ // TODO: we might add an interface to group all valid parameter types
+ public abstract void runNamedAction(int textId, Object value);
public abstract void putObject(int mId, Object command);
public abstract Object getObject(int mId);
+ public void addTouchListener(TouchListener touchExpression) {}
+
+ /**
+ * Vibrate the device
+ *
+ * @param type 0 = none, 1-21 ,see HapticFeedbackConstants
+ */
+ public abstract void hapticEffect(int type);
+
/**
* The context can be used in a few different mode, allowing operations to skip being executed:
* - UNSET : all operations will get executed - DATA : only operations dealing with DATA (eg
@@ -206,6 +228,7 @@
this.mMode = mode;
}
+ @Nullable
public PaintContext getPaintContext() {
return mPaintContext;
}
@@ -219,10 +242,14 @@
}
public boolean isDebug() {
- return mDebug;
+ return mDebug == 1;
}
- public void setDebug(boolean debug) {
+ public boolean isVisualDebug() {
+ return mDebug == 2;
+ }
+
+ public void setDebug(int debug) {
this.mDebug = debug;
}
@@ -314,6 +341,14 @@
public abstract void loadFloat(int id, float value);
/**
+ * Override an existing float value
+ *
+ * @param id
+ * @param value
+ */
+ public abstract void overrideFloat(int id, float value);
+
+ /**
* Load a integer
*
* @param id id of the integer
@@ -321,8 +356,20 @@
*/
public abstract void loadInteger(int id, int value);
+ /**
+ * Override an existing int value
+ *
+ * @param id
+ * @param value
+ */
public abstract void overrideInteger(int id, int value);
+ /**
+ * Override an existing text value
+ *
+ * @param id
+ * @param valueId
+ */
public abstract void overrideText(int id, int valueId);
/**
@@ -400,6 +447,25 @@
public static final int ID_OFFSET_TO_UTC = 10;
public static final int ID_WEEK_DAY = 11;
public static final int ID_DAY_OF_MONTH = 12;
+ public static final int ID_TOUCH_POS_X = 13;
+ public static final int ID_TOUCH_POS_Y = 14;
+
+ public static final int ID_TOUCH_VEL_X = 15;
+ public static final int ID_TOUCH_VEL_Y = 16;
+
+ public static final int ID_ACCELERATION_X = 17;
+ public static final int ID_ACCELERATION_Y = 18;
+ public static final int ID_ACCELERATION_Z = 19;
+
+ public static final int ID_GYRO_ROT_X = 20;
+ public static final int ID_GYRO_ROT_Y = 21;
+ public static final int ID_GYRO_ROT_Z = 22;
+
+ public static final int ID_MAGNETIC_X = 23;
+ public static final int ID_MAGNETIC_Y = 24;
+ public static final int ID_MAGNETIC_Z = 25;
+
+ public static final int ID_LIGHT = 26;
/** CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600 */
public static final float FLOAT_CONTINUOUS_SEC = Utils.asNan(ID_CONTINUOUS_SEC);
@@ -426,9 +492,52 @@
public static final float FLOAT_WINDOW_HEIGHT = Utils.asNan(ID_WINDOW_HEIGHT);
public static final float FLOAT_COMPONENT_WIDTH = Utils.asNan(ID_COMPONENT_WIDTH);
public static final float FLOAT_COMPONENT_HEIGHT = Utils.asNan(ID_COMPONENT_HEIGHT);
- // ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f)
+
+ /** ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f) */
public static final float FLOAT_OFFSET_TO_UTC = Utils.asNan(ID_OFFSET_TO_UTC);
+ /** TOUCH_POS_X is the x position of the touch */
+ public static final float FLOAT_TOUCH_POS_X = Utils.asNan(ID_TOUCH_POS_X);
+
+ /** TOUCH_POS_Y is the y position of the touch */
+ public static final float FLOAT_TOUCH_POS_Y = Utils.asNan(ID_TOUCH_POS_Y);
+
+ /** TOUCH_VEL_X is the x velocity of the touch */
+ public static final float FLOAT_TOUCH_VEL_X = Utils.asNan(ID_TOUCH_VEL_X);
+
+ /** TOUCH_VEL_Y is the x velocity of the touch */
+ public static final float FLOAT_TOUCH_VEL_Y = Utils.asNan(ID_TOUCH_VEL_Y);
+
+ /** X acceleration sensor value in M/s^2 */
+ public static final float FLOAT_ACCELERATION_X = Utils.asNan(ID_ACCELERATION_X);
+
+ /** Y acceleration sensor value in M/s^2 */
+ public static final float FLOAT_ACCELERATION_Y = Utils.asNan(ID_ACCELERATION_Y);
+
+ /** Z acceleration sensor value in M/s^2 */
+ public static final float FLOAT_ACCELERATION_Z = Utils.asNan(ID_ACCELERATION_Z);
+
+ /** X Gyroscope rotation rate sensor value in radians/second */
+ public static final float FLOAT_GYRO_ROT_X = Utils.asNan(ID_GYRO_ROT_X);
+
+ /** Y Gyroscope rotation rate sensor value in radians/second */
+ public static final float FLOAT_GYRO_ROT_Y = Utils.asNan(ID_GYRO_ROT_Y);
+
+ /** Z Gyroscope rotation rate sensor value in radians/second */
+ public static final float FLOAT_GYRO_ROT_Z = Utils.asNan(ID_GYRO_ROT_Z);
+
+ /** Ambient magnetic field in X. sensor value in micro-Tesla (uT) */
+ public static final float FLOAT_MAGNETIC_X = Utils.asNan(ID_MAGNETIC_X);
+
+ /** Ambient magnetic field in Y. sensor value in micro-Tesla (uT) */
+ public static final float FLOAT_MAGNETIC_Y = Utils.asNan(ID_MAGNETIC_Y);
+
+ /** Ambient magnetic field in Z. sensor value in micro-Tesla (uT) */
+ public static final float FLOAT_MAGNETIC_Z = Utils.asNan(ID_MAGNETIC_Z);
+
+ /** Ambient light level in SI lux */
+ public static final float FLOAT_LIGHT = Utils.asNan(ID_LIGHT);
+
///////////////////////////////////////////////////////////////////////////////////////////////
// Click handling
///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
index fa0cf3f..14aed2f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
@@ -27,7 +29,7 @@
*
* @param context
*/
- public void updateTime(RemoteContext context) {
+ public void updateTime(@NonNull RemoteContext context) {
LocalDateTime dateTime =
LocalDateTime.now(ZoneId.systemDefault()); // TODO, pass in a timezone explicitly?
// This define the time in the format
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/core/java/com/android/internal/widget/remotecompose/core/TouchListener.java
similarity index 67%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to core/java/com/android/internal/widget/remotecompose/core/TouchListener.java
index e21bf8f..3dda678 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/core/java/com/android/internal/widget/remotecompose/core/TouchListener.java
@@ -13,7 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package com.android.internal.widget.remotecompose.core;
-package com.android.wm.shell.shared;
+public interface TouchListener {
+ void touchDown(RemoteContext context, float x, float y);
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+ void touchUp(RemoteContext context, float x, float y, float dx, float dy);
+
+ void touchDrag(RemoteContext context, float x, float y);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java
index c71b490..738e42b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+
import java.util.Arrays;
/** The base communication buffer capable of encoding and decoding various types */
@@ -184,11 +186,13 @@
return b;
}
+ @NonNull
public String readUTF8() {
byte[] stringBuffer = readBuffer();
return new String(stringBuffer);
}
+ @NonNull
public String readUTF8(int maxSize) {
byte[] stringBuffer = readBuffer(maxSize);
return new String(stringBuffer);
@@ -250,7 +254,7 @@
writeLong(Double.doubleToRawLongBits(value));
}
- public void writeBuffer(byte[] b) {
+ public void writeBuffer(@NonNull byte[] b) {
resize(b.length + 4);
writeInt(b.length);
for (int i = 0; i < b.length; i++) {
@@ -259,7 +263,7 @@
mSize += b.length;
}
- public void writeUTF8(String content) {
+ public void writeUTF8(@NonNull String content) {
byte[] buffer = content.getBytes();
writeBuffer(buffer);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java
index c33ae24..5edecaa 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.documentation;
+import android.annotation.NonNull;
+
import java.util.ArrayList;
public class DocumentedOperation {
@@ -40,12 +42,13 @@
boolean mWIP;
String mTextExamples;
- ArrayList<StringPair> mExamples = new ArrayList<>();
- ArrayList<OperationField> mFields = new ArrayList<>();
- String mVarSize = "";
+ @NonNull ArrayList<StringPair> mExamples = new ArrayList<>();
+ @NonNull ArrayList<OperationField> mFields = new ArrayList<>();
+ @NonNull String mVarSize = "";
int mExamplesWidth = 100;
int mExamplesHeight = 100;
+ @NonNull
public static String getType(int type) {
switch (type) {
case INT:
@@ -85,6 +88,7 @@
this(category, id, name, false);
}
+ @NonNull
public ArrayList<OperationField> getFields() {
return mFields;
}
@@ -105,6 +109,7 @@
return mWIP;
}
+ @NonNull
public String getVarSize() {
return mVarSize;
}
@@ -129,6 +134,7 @@
return mTextExamples;
}
+ @NonNull
public ArrayList<StringPair> getExamples() {
return mExamples;
}
@@ -141,16 +147,19 @@
return mExamplesHeight;
}
+ @NonNull
public DocumentedOperation field(int type, String name, String description) {
mFields.add(new OperationField(type, name, description));
return this;
}
+ @NonNull
public DocumentedOperation field(int type, String name, String varSize, String description) {
mFields.add(new OperationField(type, name, varSize, description));
return this;
}
+ @NonNull
public DocumentedOperation possibleValues(String name, int value) {
if (!mFields.isEmpty()) {
mFields.get(mFields.size() - 1).possibleValue(name, "" + value);
@@ -158,21 +167,25 @@
return this;
}
+ @NonNull
public DocumentedOperation description(String description) {
mDescription = description;
return this;
}
+ @NonNull
public DocumentedOperation examples(String examples) {
mTextExamples = examples;
return this;
}
+ @NonNull
public DocumentedOperation exampleImage(String name, String imagePath) {
mExamples.add(new StringPair(name, imagePath));
return this;
}
+ @NonNull
public DocumentedOperation examplesDimension(int width, int height) {
mExamplesWidth = width;
mExamplesHeight = height;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
index c770483..cbb5ca9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
@@ -15,15 +15,18 @@
*/
package com.android.internal.widget.remotecompose.core.documentation;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import java.util.ArrayList;
public class OperationField {
int mType;
String mName;
String mDescription;
- String mVarSize = null;
+ @Nullable String mVarSize = null;
- ArrayList<StringPair> mPossibleValues = new ArrayList<>();
+ @NonNull ArrayList<StringPair> mPossibleValues = new ArrayList<>();
public OperationField(int type, String name, String description) {
mType = type;
@@ -50,6 +53,7 @@
return mDescription;
}
+ @NonNull
public ArrayList<StringPair> getPossibleValues() {
return mPossibleValues;
}
@@ -62,6 +66,7 @@
return !mPossibleValues.isEmpty();
}
+ @Nullable
public String getVarSize() {
return mVarSize;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java
index 20ba8c31..8da0e18 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -58,15 +60,17 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mImageId, mImageWidth, mImageHeight, mBitmap);
}
+ @NonNull
@Override
public String toString() {
return "BITMAP DATA " + mImageId;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -75,7 +79,12 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, int imageId, int width, int height, byte[] bitmap) {
+ public static void apply(
+ @NonNull WireBuffer buffer,
+ int imageId,
+ int width,
+ int height,
+ @NonNull byte[] bitmap) {
buffer.start(OP_CODE);
buffer.writeInt(imageId);
buffer.writeInt(width);
@@ -83,7 +92,7 @@
buffer.writeBuffer(bitmap);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int imageId = buffer.readInt();
int width = buffer.readInt();
int height = buffer.readInt();
@@ -97,7 +106,7 @@
operations.add(new BitmapData(imageId, width, height, bitmap));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Bitmap data")
.field(DocumentedOperation.INT, "id", "id of bitmap data")
@@ -107,17 +116,18 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.loadBitmap(mImageId, mImageWidth, mImageHeight, mBitmap);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(
indent,
CLASS_NAME + " id " + mImageId + " (" + mImageWidth + "x" + mImageHeight + ")");
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java
index 8b9e5a8..83d0ac7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteComposeOperation;
@@ -67,10 +69,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mContentDescription, mLeft, mTop, mRight, mBottom, mMetadata);
}
+ @NonNull
@Override
public String toString() {
return "CLICK_AREA <"
@@ -97,18 +100,20 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
if (context.getMode() != RemoteContext.ContextMode.DATA) {
return;
}
context.addClickArea(mId, mContentDescription, mLeft, mTop, mRight, mBottom, mMetadata);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -118,7 +123,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int id,
int contentDescription,
float left,
@@ -136,7 +141,7 @@
buffer.writeInt(metadata);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int contentDescription = buffer.readInt();
float left = buffer.readFloat();
@@ -149,7 +154,7 @@
operations.add(clickArea);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Define a region you can click on")
.field(DocumentedOperation.FLOAT, "left", "The left side of the region")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java
index 96b600a..db93829 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipPath.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -57,16 +59,17 @@
public static final int UNDEFINED = PATH_CLIP_UNDEFINED;
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId);
}
+ @NonNull
@Override
public String toString() {
return "ClipPath " + mId + ";";
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int pack = buffer.readInt();
int id = pack & 0xFFFFF;
int regionOp = pack >> 24;
@@ -74,6 +77,7 @@
operations.add(op);
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -82,19 +86,19 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, int id) {
+ public static void apply(@NonNull WireBuffer buffer, int id) {
buffer.start(OP_CODE);
buffer.writeInt(id);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Intersect the current clip with the path")
.field(DocumentedOperation.INT, "id", "id of the path");
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.clipPath(mId, mRegionOp);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java
index b101bfb..df54fb1 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClipRect.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -29,7 +31,7 @@
public static final int OP_CODE = Operations.CLIP_RECT;
public static final String CLASS_NAME = "ClipRect";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = ClipRect::new;
read(m, buffer, operations);
}
@@ -38,16 +40,17 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2, float v3, float v4) {
apply(buffer, v1, v2, v3, v4);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("Intersect the current clip with rectangle")
.field(
@@ -74,7 +77,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.clipRect(mX1, mY1, mX2, mY2);
}
@@ -87,7 +90,7 @@
* @param x2 end x of the DrawOval
* @param y2 end y of the DrawOval
*/
- public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) {
+ public static void apply(@NonNull WireBuffer buffer, float x1, float y1, float x2, float y2) {
write(buffer, OP_CODE, x1, y1, x2, y2);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
index 19d80da..929c9a60 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -39,15 +41,17 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mColorId, mColor);
}
+ @NonNull
@Override
public String toString() {
return "ColorConstant[" + mColorId + "] = " + Utils.colorInt(mColor) + "";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -63,19 +67,19 @@
* @param colorId
* @param color
*/
- public static void apply(WireBuffer buffer, int colorId, int color) {
+ public static void apply(@NonNull WireBuffer buffer, int colorId, int color) {
buffer.start(OP_CODE);
buffer.writeInt(colorId);
buffer.writeInt(color);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int colorId = buffer.readInt();
int color = buffer.readInt();
operations.add(new ColorConstant(colorId, color));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("Define a Color")
.field(DocumentedOperation.INT, "id", "Id of the color")
@@ -83,10 +87,11 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.loadColor(mColorId, mColor);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java
index b6041ea..3d840c5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -94,7 +96,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
if (mMode == 4) {
if (Float.isNaN(mHue)) {
mOutHue = context.getFloat(Utils.idFromNan(mHue));
@@ -118,7 +120,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (mMode == 4) {
if (Float.isNaN(mHue)) {
context.listensTo(Utils.idFromNan(mHue), this);
@@ -143,7 +145,7 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
if (mMode == 4) {
context.loadColor(
mId, (mAlpha << 24) | (0xFFFFFF & Utils.hsvToRgb(mOutHue, mOutSat, mOutValue)));
@@ -164,11 +166,12 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
int mode = mMode | (mAlpha << 16);
apply(buffer, mId, mode, mColor1, mColor2, mTween);
}
+ @NonNull
@Override
public String toString() {
if (mMode == 4) {
@@ -196,6 +199,7 @@
+ ")";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -215,7 +219,7 @@
* @param tween
*/
public static void apply(
- WireBuffer buffer, int id, int mode, int color1, int color2, float tween) {
+ @NonNull WireBuffer buffer, int id, int mode, int color1, int color2, float tween) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeInt(mode);
@@ -224,7 +228,7 @@
buffer.writeFloat(tween);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int mode = buffer.readInt();
int color1 = buffer.readInt();
@@ -234,7 +238,7 @@
operations.add(new ColorExpression(id, mode, color1, color2, tween));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("A Color defined by an expression")
.field(DocumentedOperation.INT, "id", "Id of the color")
@@ -249,6 +253,7 @@
.field(FLOAT, "tween", "32 bit ARGB color");
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java
index 9929720..142c97b2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -43,10 +46,12 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
+ @NonNull
@Override
public String toString() {
return CLASS_NAME + "(" + mType + ", " + mComponentID + ", " + mValueId + ")";
@@ -65,7 +70,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mType, mComponentID, mValueId);
}
@@ -74,7 +79,7 @@
// Nothing
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int type = buffer.readInt();
int componentId = buffer.readInt();
int valueId = buffer.readInt();
@@ -82,7 +87,7 @@
operations.add(op);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("Encode a component-related value (eg its width, height etc.)")
.field(
@@ -111,20 +116,21 @@
* @param componentId component id to reference
* @param valueId remote float used to represent the component value
*/
- public static void apply(WireBuffer buffer, int type, int componentId, int valueId) {
+ public static void apply(@NonNull WireBuffer buffer, int type, int componentId, int valueId) {
buffer.start(OP_CODE);
buffer.writeInt(type);
buffer.writeInt(componentId);
buffer.writeInt(valueId);
}
+ @Nullable
@Override
public String deepToString(String indent) {
return null;
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
String type = "WIDTH";
if (mType == HEIGHT) {
type = "HEIGHT";
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java
index 0075869..ba02b91 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -48,7 +50,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
context.addCollection(mId, this);
for (float value : mValues) {
if (Utils.isVariable(value)) {
@@ -58,16 +60,17 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mValues);
}
+ @NonNull
@Override
public String toString() {
return "DataListFloat[" + Utils.idString(mId) + "] " + Arrays.toString(mValues);
}
- public static void apply(WireBuffer buffer, int id, float[] values) {
+ public static void apply(@NonNull WireBuffer buffer, int id, @NonNull float[] values) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeInt(values.length);
@@ -76,7 +79,7 @@
}
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int len = buffer.readInt();
if (len > MAX_FLOAT_ARRAY) {
@@ -90,7 +93,7 @@
operations.add(data);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("a list of Floats")
.field(DocumentedOperation.INT, "id", "id the array (2xxxxx)")
@@ -98,13 +101,14 @@
.field(FLOAT_ARRAY, "values", "length", "array of floats");
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.addCollection(mId, this);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java
index c43dab4..b9820f8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -49,16 +51,17 @@
public void registerListening(RemoteContext context) {}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mIds);
}
+ @NonNull
@Override
public String toString() {
return "map[" + Utils.idString(mId) + "] \"" + Arrays.toString(mIds) + "\"";
}
- public static void apply(WireBuffer buffer, int id, int[] ids) {
+ public static void apply(@NonNull WireBuffer buffer, int id, @NonNull int[] ids) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeInt(ids.length);
@@ -67,7 +70,7 @@
}
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int len = buffer.readInt();
if (len > MAX_LIST) {
@@ -81,7 +84,7 @@
operations.add(data);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("a list of id's")
.field(DocumentedOperation.INT, "id", "id the array")
@@ -89,13 +92,14 @@
.field(INT_ARRAY, "ids[n]", "length", "ids of other variables");
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.addCollection(mId, this);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java
index 75db29d..fb559bb 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.UTF8;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -64,10 +66,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mDataMap.mNames, mDataMap.mTypes, mDataMap.mIds);
}
+ @NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder("DataMapIds[" + Utils.idString(mId) + "] ");
@@ -84,7 +87,8 @@
return builder.toString();
}
- public static void apply(WireBuffer buffer, int id, String[] names, byte[] type, int[] ids) {
+ public static void apply(
+ @NonNull WireBuffer buffer, int id, @NonNull String[] names, byte[] type, int[] ids) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeInt(names.length);
@@ -95,7 +99,7 @@
}
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int len = buffer.readInt();
if (len > MAX_MAP) {
@@ -113,7 +117,7 @@
operations.add(data);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Encode a collection of name id pairs")
.field(INT, "id", "id the array")
@@ -122,13 +126,14 @@
.field(UTF8, "id[0]", "length", "path encoded as floats");
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.putDataMap(mId, mDataMap);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java
index e078307..629f786 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawArc.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -28,7 +30,7 @@
public static final int OP_CODE = Operations.DRAW_ARC;
private static final String CLASS_NAME = "DrawArc";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = DrawArc::new;
read(m, buffer, operations);
}
@@ -49,7 +51,13 @@
* @param v6 Sweep angle (in degrees) measured clockwise
*/
public static void apply(
- WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) {
+ @NonNull WireBuffer buffer,
+ float v1,
+ float v2,
+ float v3,
+ float v4,
+ float v5,
+ float v6) {
buffer.start(OP_CODE);
buffer.writeFloat(v1);
buffer.writeFloat(v2);
@@ -61,11 +69,17 @@
@Override
protected void write(
- WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) {
+ @NonNull WireBuffer buffer,
+ float v1,
+ float v2,
+ float v3,
+ float v4,
+ float v5,
+ float v6) {
apply(buffer, v1, v2, v3, v4, v5, v6);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description(
"Draw the specified arc"
@@ -90,7 +104,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawArc(mV1, mV2, mV3, mV4, mV5, mV6);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java
index c678cc4..984599e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.PaintOperation;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -27,7 +30,7 @@
/** Base class for commands that take 3 float */
public abstract class DrawBase2 extends PaintOperation implements VariableSupport {
- protected String mName = "DrawRectBase";
+ @NonNull protected String mName = "DrawRectBase";
float mV1;
float mV2;
float mValue1;
@@ -41,13 +44,13 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mV1 = Float.isNaN(mValue1) ? context.getFloat(Utils.idFromNan(mValue1)) : mValue1;
mV2 = Float.isNaN(mValue2) ? context.getFloat(Utils.idFromNan(mValue2)) : mValue2;
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mValue1)) {
context.listensTo(Utils.idFromNan(mValue1), this);
}
@@ -67,12 +70,14 @@
DrawBase2 create(float v1, float v2);
}
+ @NonNull
@Override
public String toString() {
return mName + " " + floatToString(mV1) + " " + floatToString(mV2);
}
- public static void read(Maker maker, WireBuffer buffer, List<Operation> operations) {
+ public static void read(
+ @NonNull Maker maker, @NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
float v1 = buffer.readFloat();
float v2 = buffer.readFloat();
@@ -87,6 +92,7 @@
* @param y1
* @return
*/
+ @Nullable
public Operation construct(float x1, float y1) {
return null;
}
@@ -99,7 +105,7 @@
* @param x1
* @param y1
*/
- protected static void write(WireBuffer buffer, int opCode, float x1, float y1) {
+ protected static void write(@NonNull WireBuffer buffer, int opCode, float x1, float y1) {
buffer.start(opCode);
buffer.writeFloat(x1);
buffer.writeFloat(y1);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java
index e1108e9..825da52 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.PaintOperation;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -28,7 +31,7 @@
/** Base class for commands that take 3 float */
public abstract class DrawBase3 extends PaintOperation implements VariableSupport {
- protected String mName = "DrawRectBase";
+ @NonNull protected String mName = "DrawRectBase";
float mV1;
float mV2;
float mV3;
@@ -47,14 +50,14 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mV1 = Utils.isVariable(mValue1) ? context.getFloat(Utils.idFromNan(mValue1)) : mValue1;
mV2 = Utils.isVariable(mValue2) ? context.getFloat(Utils.idFromNan(mValue2)) : mValue2;
mV3 = Utils.isVariable(mValue3) ? context.getFloat(Utils.idFromNan(mValue3)) : mValue3;
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Utils.isVariable(mValue1)) {
context.listensTo(Utils.idFromNan(mValue1), this);
}
@@ -77,6 +80,7 @@
DrawBase3 create(float v1, float v2, float v3);
}
+ @NonNull
@Override
public String toString() {
return mName
@@ -88,7 +92,8 @@
+ floatToString(mV3);
}
- public static void read(Maker maker, WireBuffer buffer, List<Operation> operations) {
+ public static void read(
+ @NonNull Maker maker, @NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
float v1 = buffer.readFloat();
float v2 = buffer.readFloat();
float v3 = buffer.readFloat();
@@ -104,6 +109,7 @@
* @param x2
* @return
*/
+ @Nullable
public Operation construct(float x1, float y1, float x2) {
return null;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java
index 09f0df9..a23bcb9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.PaintOperation;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -27,7 +30,7 @@
/** Base class for draw commands that take 4 floats */
public abstract class DrawBase4 extends PaintOperation implements VariableSupport {
- protected String mName = "DrawRectBase";
+ @NonNull protected String mName = "DrawRectBase";
protected float mX1;
protected float mY1;
protected float mX2;
@@ -50,7 +53,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mX1 = Float.isNaN(mX1Value) ? context.getFloat(Utils.idFromNan(mX1Value)) : mX1Value;
mY1 = Float.isNaN(mY1Value) ? context.getFloat(Utils.idFromNan(mY1Value)) : mY1Value;
mX2 = Float.isNaN(mX2Value) ? context.getFloat(Utils.idFromNan(mX2Value)) : mX2Value;
@@ -58,7 +61,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mX1Value)) {
context.listensTo(Utils.idFromNan(mX1Value), this);
}
@@ -84,6 +87,7 @@
DrawBase4 create(float v1, float v2, float v3, float v4);
}
+ @NonNull
@Override
public String toString() {
return mName
@@ -97,7 +101,8 @@
+ floatToString(mY2Value, mY2);
}
- public static void read(Maker maker, WireBuffer buffer, List<Operation> operations) {
+ public static void read(
+ @NonNull Maker maker, @NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
float v1 = buffer.readFloat();
float v2 = buffer.readFloat();
float v3 = buffer.readFloat();
@@ -116,6 +121,7 @@
* @param y2
* @return
*/
+ @Nullable
public Operation construct(float x1, float y1, float x2, float y2) {
return null;
}
@@ -131,7 +137,7 @@
* @param y2
*/
protected static void write(
- WireBuffer buffer, int opCode, float x1, float y1, float x2, float y2) {
+ @NonNull WireBuffer buffer, int opCode, float x1, float y1, float x2, float y2) {
buffer.start(opCode);
buffer.writeFloat(x1);
buffer.writeFloat(y1);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java
index e071d5f..68c9f8c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.PaintOperation;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -25,7 +28,7 @@
/** Base class for draw commands the take 6 floats */
public abstract class DrawBase6 extends PaintOperation implements VariableSupport {
- protected String mName = "DrawRectBase";
+ @NonNull protected String mName = "DrawRectBase";
float mV1;
float mV2;
float mV3;
@@ -56,7 +59,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mV1 = Float.isNaN(mValue1) ? context.getFloat(Utils.idFromNan(mValue1)) : mValue1;
mV2 = Float.isNaN(mValue2) ? context.getFloat(Utils.idFromNan(mValue2)) : mValue2;
mV3 = Float.isNaN(mValue3) ? context.getFloat(Utils.idFromNan(mValue3)) : mValue3;
@@ -66,7 +69,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mValue1)) {
context.listensTo(Utils.idFromNan(mValue1), this);
}
@@ -95,6 +98,7 @@
protected abstract void write(
WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6);
+ @NonNull
@Override
public String toString() {
return mName
@@ -112,7 +116,8 @@
DrawBase6 create(float v1, float v2, float v3, float v4, float v5, float v6);
}
- public static void read(Maker build, WireBuffer buffer, List<Operation> operations) {
+ public static void read(
+ @NonNull Maker build, @NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
float sv1 = buffer.readFloat();
float sv2 = buffer.readFloat();
float sv3 = buffer.readFloat();
@@ -135,10 +140,12 @@
* @param v6
* @return
*/
+ @Nullable
public Operation construct(float v1, float v2, float v3, float v4, float v5, float v6) {
return null;
}
+ @NonNull
public static String name() {
return "DrawBase6";
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java
index 0b43fd2..9c23c95 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmap.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -54,7 +56,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mOutputLeft = Float.isNaN(mLeft) ? context.getFloat(Utils.idFromNan(mLeft)) : mLeft;
mOutputTop = Float.isNaN(mTop) ? context.getFloat(Utils.idFromNan(mTop)) : mTop;
mOutputRight = Float.isNaN(mRight) ? context.getFloat(Utils.idFromNan(mRight)) : mRight;
@@ -62,7 +64,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mLeft)) {
context.listensTo(Utils.idFromNan(mLeft), this);
}
@@ -78,10 +80,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mLeft, mTop, mRight, mBottom, mDescriptionId);
}
+ @NonNull
@Override
public String toString() {
return "DrawBitmap (desc="
@@ -97,7 +100,7 @@
+ ";";
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
float sLeft = buffer.readFloat();
float srcTop = buffer.readFloat();
@@ -109,6 +112,7 @@
operations.add(op);
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -118,7 +122,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int id,
float left,
float top,
@@ -134,7 +138,7 @@
buffer.writeInt(descriptionId);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
.description("Draw a bitmap")
.field(INT, "id", "id of float")
@@ -146,7 +150,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawBitmap(mId, mOutputLeft, mOutputTop, mOutputRight, mOutputBottom);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java
index fc74827..da9fe24 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapInt.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -64,7 +66,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(
buffer,
mImageId,
@@ -79,6 +81,7 @@
mContentDescId);
}
+ @NonNull
@Override
public String toString() {
return "DRAW_BITMAP_INT "
@@ -103,6 +106,7 @@
+ ";";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -112,7 +116,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int imageId,
int srcLeft,
int srcTop,
@@ -136,7 +140,7 @@
buffer.writeInt(cdId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int imageId = buffer.readInt();
int sLeft = buffer.readInt();
int srcTop = buffer.readInt();
@@ -155,7 +159,7 @@
operations.add(op);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
.description("Draw a bitmap using integer coordinates")
.field(DocumentedOperation.INT, "id", "id of bitmap")
@@ -171,7 +175,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawBitmap(
mImageId,
mSrcLeft,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java
index 22742c6..e20bcd2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -45,7 +47,7 @@
float mScaleFactor, mOutScaleFactor;
int mScaleType;
- ImageScaling mScaling = new ImageScaling();
+ @NonNull ImageScaling mScaling = new ImageScaling();
public static final int SCALE_NONE = ImageScaling.SCALE_NONE;
public static final int SCALE_INSIDE = ImageScaling.SCALE_INSIDE;
public static final int SCALE_FILL_WIDTH = ImageScaling.SCALE_FILL_WIDTH;
@@ -83,7 +85,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mOutSrcLeft =
Float.isNaN(mSrcLeft) ? context.getFloat(Utils.idFromNan(mSrcLeft)) : mSrcLeft;
mOutSrcTop = Float.isNaN(mSrcTop) ? context.getFloat(Utils.idFromNan(mSrcTop)) : mSrcTop;
@@ -109,7 +111,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
register(context, mSrcLeft);
register(context, mSrcTop);
register(context, mSrcRight);
@@ -121,12 +123,13 @@
register(context, mScaleFactor);
}
- private void register(RemoteContext context, float value) {
+ private void register(@NonNull RemoteContext context, float value) {
if (Float.isNaN(value)) {
context.listensTo(Utils.idFromNan(value), this);
}
}
+ @NonNull
static String str(float v) {
String s = " " + (int) v;
return s.substring(s.length() - 3);
@@ -140,7 +143,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(
buffer,
mImageId,
@@ -157,6 +160,7 @@
mContentDescId);
}
+ @NonNull
@Override
public String toString() {
return "DrawBitmapScaled "
@@ -185,6 +189,7 @@
+ Utils.floatToString(mScaleFactor, mOutScaleFactor);
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -194,7 +199,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int imageId,
float srcLeft,
float srcTop,
@@ -225,7 +230,7 @@
buffer.writeInt(cdId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int imageId = buffer.readInt();
float sLeft = buffer.readFloat();
@@ -258,7 +263,7 @@
operations.add(op);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
.description("Draw a bitmap using integer coordinates")
.field(DocumentedOperation.INT, "id", "id of bitmap")
@@ -289,7 +294,7 @@
// }
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
mScaling.setup(
mOutSrcLeft,
mOutSrcTop,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java
index 04f095a..11bd49a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawCircle.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -28,7 +30,7 @@
private static final int OP_CODE = Operations.DRAW_CIRCLE;
private static final String CLASS_NAME = "DrawCircle";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = DrawCircle::new;
read(m, buffer, operations);
}
@@ -37,11 +39,12 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Draw a Circle")
.field(
@@ -56,7 +59,7 @@
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2, float v3) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2, float v3) {
apply(buffer, v1, v2, v3);
}
@@ -66,7 +69,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawCircle(mV1, mV2, mV3);
}
@@ -78,7 +81,7 @@
* @param y1
* @param x2
*/
- public static void apply(WireBuffer buffer, float x1, float y1, float x2) {
+ public static void apply(@NonNull WireBuffer buffer, float x1, float y1, float x2) {
buffer.start(OP_CODE);
buffer.writeFloat(x1);
buffer.writeFloat(y1);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java
index dacbb03..7310a9d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawLine.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -30,7 +32,7 @@
private static final int OP_CODE = Operations.DRAW_LINE;
private static final String CLASS_NAME = "DrawLine";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = DrawLine::new;
read(m, buffer, operations);
}
@@ -39,11 +41,12 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Draw a line segment")
.field(
@@ -65,7 +68,7 @@
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2, float v3, float v4) {
apply(buffer, v1, v2, v3, v4);
}
@@ -75,7 +78,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawLine(mX1, mY1, mX2, mY2);
}
@@ -88,12 +91,12 @@
* @param x2 end x of the line
* @param y2 end y of the line
*/
- public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) {
+ public static void apply(@NonNull WireBuffer buffer, float x1, float y1, float x2, float y2) {
write(buffer, OP_CODE, x1, y1, x2, y2);
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
String x1 = "" + mX1;
if (Float.isNaN(mX1Value)) {
x1 = "[" + Utils.idFromNan(mX1Value) + " = " + mX1 + "]";
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java
index 5d498e8..aa5116e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawOval.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -28,7 +30,7 @@
private static final int OP_CODE = Operations.DRAW_OVAL;
private static final String CLASS_NAME = "DrawOval";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = DrawOval::new;
read(m, buffer, operations);
}
@@ -37,11 +39,12 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Draw the specified oval")
.field(DocumentedOperation.FLOAT, "left", "The left side of the oval")
@@ -51,12 +54,12 @@
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2, float v3, float v4) {
apply(buffer, v1, v2, v3, v4);
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mX1, mY1, mX2, mY2);
}
@@ -66,7 +69,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawOval(mX1, mY1, mX2, mY2);
}
@@ -79,7 +82,7 @@
* @param x2 end x of the DrawOval
* @param y2 end y of the DrawOval
*/
- public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) {
+ public static void apply(@NonNull WireBuffer buffer, float x1, float y1, float x2, float y2) {
write(buffer, OP_CODE, x1, y1, x2, y2);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java
index ccbf3d9..d35094b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawPath.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -38,21 +40,23 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId);
}
+ @NonNull
@Override
public String toString() {
return "DrawPath " + "[" + mId + "]" + ", " + mStart + ", " + mEnd;
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
DrawPath op = new DrawPath(id);
operations.add(op);
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -61,19 +65,19 @@
return Operations.DRAW_PATH;
}
- public static void apply(WireBuffer buffer, int id) {
+ public static void apply(@NonNull WireBuffer buffer, int id) {
buffer.start(Operations.DRAW_PATH);
buffer.writeInt(id);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
.description("Draw a bitmap using integer coordinates")
.field(DocumentedOperation.INT, "id", "id of path");
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawPath(mId, mStart, mEnd);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java
index 644011b..db7633c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRect.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -29,7 +31,7 @@
private static final int OP_CODE = Operations.DRAW_RECT;
private static final String CLASS_NAME = "DrawRect";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = DrawRect::new;
read(m, buffer, operations);
}
@@ -38,11 +40,12 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Draw the specified rectangle")
.field(DocumentedOperation.FLOAT, "left", "The left side of the rectangle")
@@ -52,7 +55,7 @@
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2, float v3, float v4) {
apply(buffer, v1, v2, v3, v4);
}
@@ -62,7 +65,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawRect(mX1, mY1, mX2, mY2);
}
@@ -75,7 +78,7 @@
* @param x2 right x of the rect
* @param y2 bottom y of the rect
*/
- public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) {
+ public static void apply(@NonNull WireBuffer buffer, float x1, float y1, float x2, float y2) {
write(buffer, OP_CODE, x1, y1, x2, y2);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java
index 64a3b28..c306e2b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawRoundRect.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -29,7 +31,7 @@
private static final int OP_CODE = Operations.DRAW_ROUND_RECT;
private static final String CLASS_NAME = "DrawRoundRect";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = DrawRoundRect::new;
read(m, buffer, operations);
}
@@ -50,7 +52,13 @@
* @param v6 The y-radius of the oval used to round the corners
*/
public static void apply(
- WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) {
+ @NonNull WireBuffer buffer,
+ float v1,
+ float v2,
+ float v3,
+ float v4,
+ float v5,
+ float v6) {
buffer.start(OP_CODE);
buffer.writeFloat(v1);
buffer.writeFloat(v2);
@@ -62,11 +70,17 @@
@Override
protected void write(
- WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) {
+ @NonNull WireBuffer buffer,
+ float v1,
+ float v2,
+ float v3,
+ float v4,
+ float v5,
+ float v6) {
apply(buffer, v1, v2, v3, v4, v5, v6);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Draw the specified round-rect")
.field(DocumentedOperation.FLOAT, "left", "The left side of the rect")
@@ -89,7 +103,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawRoundRect(mV1, mV2, mV3, mV4, mV5, mV6);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java
index 3cb1916..3b60df7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawSector.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -28,7 +30,7 @@
public static final int OP_CODE = Operations.DRAW_SECTOR;
private static final String CLASS_NAME = "DrawSector";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = DrawSector::new;
read(m, buffer, operations);
}
@@ -49,7 +51,13 @@
* @param v6 Sweep angle (in degrees) measured clockwise
*/
public static void apply(
- WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) {
+ @NonNull WireBuffer buffer,
+ float v1,
+ float v2,
+ float v3,
+ float v4,
+ float v5,
+ float v6) {
buffer.start(OP_CODE);
buffer.writeFloat(v1);
buffer.writeFloat(v2);
@@ -61,11 +69,17 @@
@Override
protected void write(
- WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6) {
+ @NonNull WireBuffer buffer,
+ float v1,
+ float v2,
+ float v3,
+ float v4,
+ float v5,
+ float v6) {
apply(buffer, v1, v2, v3, v4, v5, v6);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description(
"Draw the specified sector (pie shape)"
@@ -90,7 +104,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawSector(mV1, mV2, mV3, mV4, mV5, mV6);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java
index bcb7852..9c587ab 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawText.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -64,13 +66,13 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mOutX = Float.isNaN(mX) ? context.getFloat(Utils.idFromNan(mX)) : mX;
mOutY = Float.isNaN(mY) ? context.getFloat(Utils.idFromNan(mY)) : mY;
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mX)) {
context.listensTo(Utils.idFromNan(mX), this);
}
@@ -80,10 +82,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTextID, mStart, mEnd, mContextStart, mContextEnd, mX, mY, mRtl);
}
+ @NonNull
@Override
public String toString() {
return "DrawTextRun ["
@@ -98,7 +101,7 @@
+ floatToString(mY, mOutY);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int text = buffer.readInt();
int start = buffer.readInt();
int end = buffer.readInt();
@@ -112,6 +115,7 @@
operations.add(op);
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -134,7 +138,7 @@
* @param rtl is it Right to Left text
*/
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int textID,
int start,
int end,
@@ -154,7 +158,7 @@
buffer.writeBoolean(rtl);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Draw Operations", id(), CLASS_NAME)
.description("Draw a run of text, all in a single direction")
.field(DocumentedOperation.INT, "textId", "id of bitmap")
@@ -177,7 +181,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawTextRun(mTextID, mStart, mEnd, mContextStart, mContextEnd, mOutX, mOutY, mRtl);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java
index 95a8766..8b70181 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextAnchored.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -57,7 +59,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mOutX = Float.isNaN(mX) ? context.getFloat(Utils.idFromNan(mX)) : mX;
mOutY = Float.isNaN(mY) ? context.getFloat(Utils.idFromNan(mY)) : mY;
mOutPanX = Float.isNaN(mPanX) ? context.getFloat(Utils.idFromNan(mPanX)) : mPanX;
@@ -65,7 +67,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mX)) {
context.listensTo(Utils.idFromNan(mX), this);
}
@@ -81,10 +83,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTextID, mX, mY, mPanX, mPanY, mFlags);
}
+ @NonNull
@Override
public String toString() {
return "DrawTextAnchored ["
@@ -108,7 +111,7 @@
return Float.toString(v);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int textID = buffer.readInt();
float x = buffer.readFloat();
float y = buffer.readFloat();
@@ -121,6 +124,7 @@
operations.add(op);
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -141,7 +145,13 @@
* @param flags Change the behaviour
*/
public static void apply(
- WireBuffer buffer, int textID, float x, float y, float panX, float panY, int flags) {
+ @NonNull WireBuffer buffer,
+ int textID,
+ float x,
+ float y,
+ float panX,
+ float panY,
+ int flags) {
buffer.start(OP_CODE);
buffer.writeInt(textID);
buffer.writeFloat(x);
@@ -151,7 +161,7 @@
buffer.writeInt(flags);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
.description("Draw text centered about an anchor point")
.field(DocumentedOperation.INT, "textId", "id of bitmap")
@@ -168,7 +178,7 @@
.field(DocumentedOperation.INT, "flags", "Change the behaviour");
}
- float[] mBounds = new float[4];
+ @NonNull float[] mBounds = new float[4];
private float getHorizontalOffset() {
// TODO scale TextSize / BaseTextSize;
@@ -188,7 +198,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
int flags =
((mFlags & ANCHOR_MONOSPACE_MEASURE) != 0)
? PaintContext.TEXT_MEASURE_MONOSPACE_WIDTH
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java
index aefd6f3..e90122b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTextOnPath.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -46,7 +48,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mOutHOffset =
Float.isNaN(mHOffset) ? context.getFloat(Utils.idFromNan(mHOffset)) : mHOffset;
mOutVOffset =
@@ -54,7 +56,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mHOffset)) {
context.listensTo(Utils.idFromNan(mHOffset), this);
}
@@ -64,10 +66,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTextId, mPathId, mHOffset, mVOffset);
}
+ @NonNull
@Override
public String toString() {
return "DrawTextOnPath ["
@@ -80,7 +83,7 @@
+ Utils.floatToString(mVOffset, mOutVOffset);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int textId = buffer.readInt();
int pathId = buffer.readInt();
float vOffset = buffer.readFloat();
@@ -89,6 +92,7 @@
operations.add(op);
}
+ @NonNull
public static String name() {
return "DrawTextOnPath";
}
@@ -98,7 +102,7 @@
}
public static void apply(
- WireBuffer buffer, int textId, int pathId, float hOffset, float vOffset) {
+ @NonNull WireBuffer buffer, int textId, int pathId, float hOffset, float vOffset) {
buffer.start(OP_CODE);
buffer.writeInt(textId);
buffer.writeInt(pathId);
@@ -106,7 +110,7 @@
buffer.writeFloat(hOffset);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
.description("Draw text along path object")
.field(DocumentedOperation.INT, "textId", "id of the text")
@@ -116,7 +120,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawTextOnPath(mTextId, mPathId, mOutHOffset, mOutVOffset);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java
index b6d45d9..0aaaf42 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawTweenPath.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.operations.Utils.floatToString;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -50,14 +52,14 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mOutTween = Float.isNaN(mTween) ? context.getFloat(Utils.idFromNan(mTween)) : mTween;
mOutStart = Float.isNaN(mStart) ? context.getFloat(Utils.idFromNan(mStart)) : mStart;
mOutStop = Float.isNaN(mStop) ? context.getFloat(Utils.idFromNan(mStop)) : mStop;
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mTween)) {
context.listensTo(Utils.idFromNan(mTween), this);
}
@@ -70,10 +72,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mPath1Id, mPath2Id, mTween, mStart, mStop);
}
+ @NonNull
@Override
public String toString() {
return "DrawTweenPath "
@@ -89,7 +92,7 @@
+ floatToString(mStop, mOutStop);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int path1Id = buffer.readInt();
int path2Id = buffer.readInt();
float tween = buffer.readFloat();
@@ -99,6 +102,7 @@
operations.add(op);
}
+ @NonNull
public static String name() {
return "DrawTweenPath";
}
@@ -108,7 +112,12 @@
}
public static void apply(
- WireBuffer buffer, int path1Id, int path2Id, float tween, float start, float stop) {
+ @NonNull WireBuffer buffer,
+ int path1Id,
+ int path2Id,
+ float tween,
+ float start,
+ float stop) {
buffer.start(OP_CODE);
buffer.writeInt(path1Id);
buffer.writeInt(path2Id);
@@ -117,7 +126,7 @@
buffer.writeFloat(stop);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Draw Operations", OP_CODE, CLASS_NAME)
.description("Draw text along path object")
.field(DocumentedOperation.INT, "pathId1", "id of path 1")
@@ -128,7 +137,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.drawTweenPath(mPath1Id, mPath2Id, mOutTween, mOutStart, mOutStop);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java
index 765e150..89390ac 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -39,15 +41,17 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTextId, mValue);
}
+ @NonNull
@Override
public String toString() {
return "FloatConstant[" + mTextId + "] = " + mValue;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -63,20 +67,20 @@
* @param id the id
* @param value the value of the float
*/
- public static void apply(WireBuffer buffer, int id, float value) {
+ public static void apply(@NonNull WireBuffer buffer, int id, float value) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeFloat(value);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int textId = buffer.readInt();
float value = buffer.readFloat();
operations.add(new FloatConstant(textId, value));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("A float and its associated id")
.field(DocumentedOperation.INT, "id", "id of float")
@@ -84,10 +88,11 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.loadFloat(mTextId, mValue);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
index d717933..e1c6c25 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
@@ -20,6 +20,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.SHORT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -48,7 +51,7 @@
public float[] mPreCalcValue;
private float mLastChange = Float.NaN;
private float mLastCalculatedValue = Float.NaN;
- AnimatedFloatExpression mExp = new AnimatedFloatExpression();
+ @NonNull AnimatedFloatExpression mExp = new AnimatedFloatExpression();
public static final int MAX_EXPRESSION_SIZE = 32;
public FloatExpression(int id, float[] value, float[] animation) {
@@ -61,7 +64,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
if (mPreCalcValue == null || mPreCalcValue.length != mSrcValue.length) {
mPreCalcValue = new float[mSrcValue.length];
}
@@ -107,7 +110,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
for (float v : mSrcValue) {
if (Float.isNaN(v)
&& !AnimatedFloatExpression.isMathOperator(v)
@@ -118,7 +121,7 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
updateVariables(context);
float t = context.getAnimationTime();
if (Float.isNaN(mLastChange)) {
@@ -135,10 +138,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mSrcValue, mSrcAnimation);
}
+ @NonNull
@Override
public String toString() {
String[] labels = new String[mSrcValue.length];
@@ -161,6 +165,7 @@
+ ")";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -177,7 +182,11 @@
* @param value the float expression array
* @param animation the animation expression array
*/
- public static void apply(WireBuffer buffer, int id, float[] value, float[] animation) {
+ public static void apply(
+ @NonNull WireBuffer buffer,
+ int id,
+ @NonNull float[] value,
+ @Nullable float[] animation) {
buffer.start(OP_CODE);
buffer.writeInt(id);
@@ -197,7 +206,7 @@
}
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int len = buffer.readInt();
int valueLen = len & 0xFFFF;
@@ -222,7 +231,7 @@
operations.add(new FloatExpression(id, values, animation));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("A Float expression")
.field(DocumentedOperation.INT, "id", "The id of the Color")
@@ -245,6 +254,7 @@
.field(FLOAT, "wrapValue", "> [Wrap value] ");
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
index 4f8516f..1979bc5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.LONG;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteComposeOperation;
@@ -80,10 +82,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mWidth, mHeight, mDensity, mCapabilities);
}
+ @NonNull
@Override
public String toString() {
return "HEADER v"
@@ -102,15 +105,17 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.header(mMajorVersion, mMinorVersion, mPatchVersion, mWidth, mHeight, mCapabilities);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return toString();
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -120,7 +125,7 @@
}
public static void apply(
- WireBuffer buffer, int width, int height, float density, long capabilities) {
+ @NonNull WireBuffer buffer, int width, int height, float density, long capabilities) {
buffer.start(OP_CODE);
buffer.writeInt(MAJOR_VERSION); // major version number of the protocol
buffer.writeInt(MINOR_VERSION); // minor version number of the protocol
@@ -131,7 +136,7 @@
buffer.writeLong(capabilities);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int majorVersion = buffer.readInt();
int minorVersion = buffer.readInt();
int patchVersion = buffer.readInt();
@@ -152,7 +157,7 @@
operations.add(header);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Protocol Operations", OP_CODE, CLASS_NAME)
.description(
"Document metadata, containing the version,"
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java
index c9a8508..6375f00 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -45,7 +47,7 @@
public int[] mPreCalcValue;
private float mLastChange = Float.NaN;
public static final int MAX_SIZE = 320;
- IntegerExpressionEvaluator mExp = new IntegerExpressionEvaluator();
+ @NonNull IntegerExpressionEvaluator mExp = new IntegerExpressionEvaluator();
public IntegerExpression(int id, int mask, int[] value) {
this.mId = id;
@@ -54,7 +56,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
if (mPreCalcValue == null || mPreCalcValue.length != mSrcValue.length) {
mPreCalcValue = new int[mSrcValue.length];
}
@@ -70,7 +72,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
for (int i = 0; i < mSrcValue.length; i++) {
if (isId(mMask, i, mSrcValue[i])) {
context.listensTo(mSrcValue[i], this);
@@ -79,7 +81,7 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
updateVariables(context);
float t = context.getAnimationTime();
if (Float.isNaN(mLastChange)) {
@@ -95,7 +97,7 @@
* @param context current context
* @return the resulting value
*/
- public int evaluate(RemoteContext context) {
+ public int evaluate(@NonNull RemoteContext context) {
updateVariables(context);
float t = context.getAnimationTime();
if (Float.isNaN(mLastChange)) {
@@ -105,10 +107,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mMask, mSrcValue);
}
+ @NonNull
@Override
public String toString() {
StringBuilder s = new StringBuilder();
@@ -132,6 +135,7 @@
return "IntegerExpression[" + mId + "] = (" + s + ")";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -148,7 +152,7 @@
* @param mask the mask bits of ints & operators or variables
* @param value array of integers to be evaluated
*/
- public static void apply(WireBuffer buffer, int id, int mask, int[] value) {
+ public static void apply(@NonNull WireBuffer buffer, int id, int mask, @NonNull int[] value) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeInt(mask);
@@ -158,7 +162,7 @@
}
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int mask = buffer.readInt();
int len = buffer.readInt();
@@ -173,7 +177,7 @@
operations.add(new IntegerExpression(id, mask, values));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Expression that computes an integer")
.field(DocumentedOperation.INT, "id", "id of integer")
@@ -182,6 +186,7 @@
.field(INT_ARRAY, "values", "length", "Array of ints");
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java
index 04f8a50..6a620e5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -31,20 +33,22 @@
public MatrixRestore() {}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
MatrixRestore op = new MatrixRestore();
operations.add(op);
}
+ @NonNull
@Override
public String toString() {
return "MatrixRestore";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -53,17 +57,17 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer) {
+ public static void apply(@NonNull WireBuffer buffer) {
buffer.start(OP_CODE);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Restore the matrix and clip");
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.matrixRestore();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java
index df10f32..438a2aa 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRotate.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -28,9 +30,10 @@
public static final int OP_CODE = Operations.MATRIX_ROTATE;
private static final String CLASS_NAME = "MatrixRotate";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m =
new Maker() {
+ @NonNull
@Override
public DrawBase3 create(float v1, float v2, float v3) {
return new MatrixRotate(v1, v2, v3);
@@ -43,11 +46,12 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("apply rotation to matrix")
.field(DocumentedOperation.FLOAT, "rotate", "Angle to rotate")
@@ -56,7 +60,7 @@
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2, float v3) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2, float v3) {
apply(buffer, v1, v2, v3);
}
@@ -66,7 +70,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.matrixRotate(mV1, mV2, mV3);
}
@@ -78,7 +82,7 @@
* @param y1 X Pivot point
* @param x2 Y Pivot point
*/
- public static void apply(WireBuffer buffer, float x1, float y1, float x2) {
+ public static void apply(@NonNull WireBuffer buffer, float x1, float y1, float x2) {
buffer.start(OP_CODE);
buffer.writeFloat(x1);
buffer.writeFloat(y1);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java
index 67612c7..1880b19 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -29,20 +31,22 @@
private static final String CLASS_NAME = "MatrixSave";
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer);
}
+ @NonNull
@Override
public String toString() {
return "MatrixSave;";
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
MatrixSave op = new MatrixSave();
operations.add(op);
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -51,17 +55,17 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer) {
+ public static void apply(@NonNull WireBuffer buffer) {
buffer.start(Operations.MATRIX_SAVE);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Save the matrix and clip to a stack");
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.matrixSave();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java
index 26c898a..6304584 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixScale.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -28,7 +30,7 @@
public static final int OP_CODE = Operations.MATRIX_SCALE;
public static final String CLASS_NAME = "MatrixScale";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = MatrixScale::new;
read(m, buffer, operations);
}
@@ -37,16 +39,17 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2, float v3, float v4) {
apply(buffer, v1, v2, v3, v4);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Draw the specified Oval")
.field(DocumentedOperation.FLOAT, "scaleX", "The amount to scale in X")
@@ -61,7 +64,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.matrixScale(mX1, mY1, mX2, mY2);
}
@@ -74,7 +77,7 @@
* @param x2 end x of the DrawOval
* @param y2 end y of the DrawOval
*/
- public static void apply(WireBuffer buffer, float x1, float y1, float x2, float y2) {
+ public static void apply(@NonNull WireBuffer buffer, float x1, float y1, float x2, float y2) {
write(buffer, OP_CODE, x1, y1, x2, y2);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java
index d641178..675cf0d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSkew.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -29,7 +31,7 @@
public static final int OP_CODE = Operations.MATRIX_SKEW;
public static final String CLASS_NAME = "MatrixSkew";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = MatrixSkew::new;
read(m, buffer, operations);
}
@@ -38,16 +40,17 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2) {
apply(buffer, v1, v2);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Current matrix with the specified skew.")
.field(FLOAT, "skewX", "The amount to skew in X")
@@ -60,7 +63,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.matrixSkew(mV1, mV2);
}
@@ -71,7 +74,7 @@
* @param x1 start x of DrawOval
* @param y1 start y of the DrawOval
*/
- public static void apply(WireBuffer buffer, float x1, float y1) {
+ public static void apply(@NonNull WireBuffer buffer, float x1, float y1) {
write(buffer, OP_CODE, x1, y1);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java
index e008292..b0a7d35 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixTranslate.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -28,7 +30,7 @@
public static final int OP_CODE = Operations.MATRIX_TRANSLATE;
public static final String CLASS_NAME = "MatrixTranslate";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = MatrixTranslate::new;
read(m, buffer, operations);
}
@@ -37,16 +39,17 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2) {
apply(buffer, v1, v2);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, "MatrixTranslate")
.description("Preconcat the current matrix with the specified translation")
.field(DocumentedOperation.FLOAT, "dx", "The distance to translate in X")
@@ -59,7 +62,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.matrixTranslate(mV1, mV2);
}
@@ -70,7 +73,7 @@
* @param x1 start x of DrawOval
* @param y1 start y of the DrawOval
*/
- public static void apply(WireBuffer buffer, float x1, float y1) {
+ public static void apply(@NonNull WireBuffer buffer, float x1, float y1) {
write(buffer, OP_CODE, x1, y1);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
index fa6e271..6310521e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.UTF8;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -47,10 +49,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mVarId, mVarType, mVarName);
}
+ @NonNull
@Override
public String toString() {
return "VariableName["
@@ -61,6 +64,7 @@
+ mVarType;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -77,21 +81,22 @@
* @param varType The type of variable
* @param text String
*/
- public static void apply(WireBuffer buffer, int varId, int varType, String text) {
+ public static void apply(
+ @NonNull WireBuffer buffer, int varId, int varType, @NonNull String text) {
buffer.start(Operations.NAMED_VARIABLE);
buffer.writeInt(varId);
buffer.writeInt(varType);
buffer.writeUTF8(text);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int varId = buffer.readInt();
int varType = buffer.readInt();
String text = buffer.readUTF8(MAX_STRING_SIZE);
operations.add(new NamedVariable(varId, varType, text));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Add a string name for an ID")
.field(DocumentedOperation.INT, "varId", "id to label")
@@ -100,10 +105,11 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.loadVariableName(mVarName, mVarId, mVarType);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java
index 095a010..527d5610 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -33,31 +35,33 @@
public class PaintData extends PaintOperation implements VariableSupport {
private static final int OP_CODE = Operations.PAINT_VALUES;
private static final String CLASS_NAME = "PaintData";
- public PaintBundle mPaintData = new PaintBundle();
+ @NonNull public PaintBundle mPaintData = new PaintBundle();
public static final int MAX_STRING_SIZE = 4000;
public PaintData() {}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mPaintData.updateVariables(context);
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
mPaintData.registerVars(context, this);
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mPaintData);
}
+ @NonNull
@Override
public String toString() {
return "PaintData " + "\"" + mPaintData + "\"";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -66,31 +70,32 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, PaintBundle paintBundle) {
+ public static void apply(@NonNull WireBuffer buffer, @NonNull PaintBundle paintBundle) {
buffer.start(Operations.PAINT_VALUES);
paintBundle.writeBundle(buffer);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
PaintData data = new PaintData();
data.mPaintData.readBundle(buffer);
operations.add(data);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Encode a Paint ")
.field(INT, "length", "id string")
.field(INT_ARRAY, "paint", "length", "path encoded as floats");
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.applyPaint(mPaintData);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
index 13d5a49..06a1fec 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
@@ -18,6 +18,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -43,7 +46,7 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
for (int i = 0; i < mFloatPath.length; i++) {
float v = mFloatPath[i];
if (Utils.isVariable(v)) {
@@ -55,7 +58,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
for (float v : mFloatPath) {
if (Float.isNaN(v)) {
context.listensTo(Utils.idFromNan(v), this);
@@ -64,15 +67,17 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mInstanceId, mOutputPath);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return pathString(mFloatPath);
}
+ @NonNull
@Override
public String toString() {
return "PathData[" + mInstanceId + "] = " + "\"" + deepToString(" ") + "\"";
@@ -102,6 +107,7 @@
public static final float CLOSE_NAN = Utils.asNan(CLOSE);
public static final float DONE_NAN = Utils.asNan(DONE);
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -110,7 +116,7 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, int id, float[] data) {
+ public static void apply(@NonNull WireBuffer buffer, int id, @NonNull float[] data) {
buffer.start(Operations.DATA_PATH);
buffer.writeInt(id);
buffer.writeInt(data.length);
@@ -119,7 +125,7 @@
}
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int imageId = buffer.readInt();
int len = buffer.readInt();
float[] data = new float[len];
@@ -129,7 +135,7 @@
operations.add(new PathData(imageId, data));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Encode a Path ")
.field(DocumentedOperation.INT, "id", "id string")
@@ -137,7 +143,8 @@
.field(FLOAT_ARRAY, "pathData", "length", "path encoded as floats");
}
- public static String pathString(float[] path) {
+ @NonNull
+ public static String pathString(@Nullable float[] path) {
if (path == null) {
return "null";
}
@@ -186,7 +193,7 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.loadPathData(mInstanceId, mOutputPath);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
index 4a8f532..6ff9ad7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteComposeOperation;
@@ -172,10 +174,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mScroll, mAlignment, mSizing, mMode);
}
+ @NonNull
@Override
public String toString() {
return "ROOT_CONTENT_BEHAVIOR scroll: "
@@ -187,15 +190,17 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.setRootContentBehavior(mScroll, mAlignment, mSizing, mMode);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return toString();
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -204,7 +209,8 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, int scroll, int alignment, int sizing, int mode) {
+ public static void apply(
+ @NonNull WireBuffer buffer, int scroll, int alignment, int sizing, int mode) {
buffer.start(OP_CODE);
buffer.writeInt(scroll);
buffer.writeInt(alignment);
@@ -212,7 +218,7 @@
buffer.writeInt(mode);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int scroll = buffer.readInt();
int alignment = buffer.readInt();
int sizing = buffer.readInt();
@@ -222,7 +228,7 @@
operations.add(rootContentBehavior);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Protocol Operations", OP_CODE, CLASS_NAME)
.description("Describes the behaviour of the root")
.field(DocumentedOperation.INT, "scroll", "scroll")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
index bff9029..c2d62a7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteComposeOperation;
@@ -41,25 +43,28 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mContentDescription);
}
+ @NonNull
@Override
public String toString() {
return "RootContentDescription " + mContentDescription;
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.setDocumentContentDescription(mContentDescription);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return toString();
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -68,18 +73,18 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, int contentDescription) {
+ public static void apply(@NonNull WireBuffer buffer, int contentDescription) {
buffer.start(Operations.ROOT_CONTENT_DESCRIPTION);
buffer.writeInt(contentDescription);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int contentDescription = buffer.readInt();
RootContentDescription header = new RootContentDescription(contentDescription);
operations.add(header);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Protocol Operations", OP_CODE, CLASS_NAME)
.description("Content description of root")
.field(DocumentedOperation.INT, "id", "id of Int");
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java
index 7ec7879..ae61c3a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java
@@ -22,6 +22,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.SHORT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.UTF8;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -43,17 +46,17 @@
private static final String CLASS_NAME = "ShaderData";
int mShaderTextId; // the actual text of a shader
int mShaderID; // allows shaders to be referenced by number
- HashMap<String, float[]> mUniformRawFloatMap = null;
- HashMap<String, float[]> mUniformFloatMap = null;
- HashMap<String, int[]> mUniformIntMap = null;
- HashMap<String, Integer> mUniformBitmapMap = null;
+ @Nullable HashMap<String, float[]> mUniformRawFloatMap = null;
+ @Nullable HashMap<String, float[]> mUniformFloatMap = null;
+ @Nullable HashMap<String, int[]> mUniformIntMap = null;
+ @Nullable HashMap<String, Integer> mUniformBitmapMap = null;
public ShaderData(
int shaderID,
int shaderTextId,
- HashMap<String, float[]> floatMap,
- HashMap<String, int[]> intMap,
- HashMap<String, Integer> bitmapMap) {
+ @Nullable HashMap<String, float[]> floatMap,
+ @Nullable HashMap<String, int[]> intMap,
+ @Nullable HashMap<String, Integer> bitmapMap) {
mShaderID = shaderID;
mShaderTextId = shaderTextId;
if (floatMap != null) {
@@ -89,6 +92,7 @@
*
* @return Names of all uniform floats or empty array
*/
+ @NonNull
public String[] getUniformFloatNames() {
if (mUniformFloatMap == null) return new String[0];
return mUniformFloatMap.keySet().toArray(new String[0]);
@@ -109,6 +113,7 @@
*
* @return Name of all integer uniforms
*/
+ @NonNull
public String[] getUniformIntegerNames() {
if (mUniformIntMap == null) return new String[0];
return mUniformIntMap.keySet().toArray(new String[0]);
@@ -129,6 +134,7 @@
*
* @return Name of all bitmap uniforms
*/
+ @NonNull
public String[] getUniformBitmapNames() {
if (mUniformBitmapMap == null) return new String[0];
return mUniformBitmapMap.keySet().toArray(new String[0]);
@@ -145,7 +151,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(
buffer,
mShaderID,
@@ -155,13 +161,14 @@
mUniformBitmapMap);
}
+ @NonNull
@Override
public String toString() {
return "SHADER DATA " + mShaderID;
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
for (String name : mUniformRawFloatMap.keySet()) {
float[] value = mUniformRawFloatMap.get(name);
float[] out = null;
@@ -178,7 +185,7 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
for (String name : mUniformRawFloatMap.keySet()) {
float[] value = mUniformRawFloatMap.get(name);
for (float v : value) {
@@ -189,6 +196,7 @@
}
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -208,12 +216,12 @@
* @param bitmapMap the map of bitmap uniforms
*/
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int shaderID,
int shaderTextId,
- HashMap<String, float[]> floatMap,
- HashMap<String, int[]> intMap,
- HashMap<String, Integer> bitmapMap) {
+ @Nullable HashMap<String, float[]> floatMap,
+ @Nullable HashMap<String, int[]> intMap,
+ @Nullable HashMap<String, Integer> bitmapMap) {
buffer.start(OP_CODE);
buffer.writeInt(shaderID);
@@ -256,7 +264,7 @@
}
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int shaderID = buffer.readInt();
int shaderTextId = buffer.readInt();
HashMap<String, float[]> floatMap = null;
@@ -308,7 +316,7 @@
operations.add(new ShaderData(shaderID, shaderTextId, floatMap, intMap, bitmapMap));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Shader")
.field(DocumentedOperation.INT, "shaderID", "id of shader")
@@ -326,10 +334,11 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.loadShader(mShaderID, this);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java
index 6383249..dbaef7e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.UTF8;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -42,15 +44,17 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTextId, mText);
}
+ @NonNull
@Override
public String toString() {
return "TextData[" + mTextId + "] = \"" + Utils.trimString(mText, 10) + "\"";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -59,20 +63,20 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, int textId, String text) {
+ public static void apply(@NonNull WireBuffer buffer, int textId, @NonNull String text) {
buffer.start(OP_CODE);
buffer.writeInt(textId);
buffer.writeUTF8(text);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int textId = buffer.readInt();
String text = buffer.readUTF8(MAX_STRING_SIZE);
operations.add(new TextData(textId, text));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Encode a string ")
.field(DocumentedOperation.INT, "id", "id string")
@@ -80,20 +84,22 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.loadText(mTextId, mText);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(indent, getSerializedName() + "<" + mTextId + "> = \"" + mText + "\"");
}
+ @NonNull
private String getSerializedName() {
return "DATA_TEXT";
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java
index 0d966d1..fb5087f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.SHORT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -87,10 +89,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTextId, mValue, mDigitsBefore, mDigitsAfter, mFlags);
}
+ @NonNull
@Override
public String toString() {
return "TextFromFloat["
@@ -106,19 +109,20 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
if (Float.isNaN(mValue)) {
mOutValue = context.getFloat(Utils.idFromNan(mValue));
}
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mValue)) {
context.listensTo(Utils.idFromNan(mValue), this);
}
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -138,7 +142,7 @@
* @param flags flags that control if and how to fill the empty spots
*/
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int textId,
float value,
short digitsBefore,
@@ -151,7 +155,7 @@
buffer.writeInt(flags);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int textId = buffer.readInt();
float value = buffer.readFloat();
int tmp = buffer.readInt();
@@ -162,7 +166,7 @@
operations.add(new TextFromFloat(textId, value, pre, post, flags));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("Draw text along path object")
.field(DocumentedOperation.INT, "textId", "id of the text generated")
@@ -173,12 +177,13 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
float v = mOutValue;
String s = StringUtils.floatToString(v, mDigitsBefore, mDigitsAfter, mPre, mAfter);
context.loadText(mTextId, s);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java
index b04d698..2129edd 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -48,10 +50,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTextId, mDataSetId, mIndex);
}
+ @NonNull
@Override
public String toString() {
return "TextLookup["
@@ -63,19 +66,20 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
if (Float.isNaN(mIndex)) {
mOutIndex = context.getFloat(Utils.idFromNan(mIndex));
}
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (Float.isNaN(mIndex)) {
context.listensTo(Utils.idFromNan(mIndex), this);
}
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -92,21 +96,21 @@
* @param dataSet float pointer to the array/list to turn int a string
* @param index index of element to return
*/
- public static void apply(WireBuffer buffer, int textId, int dataSet, float index) {
+ public static void apply(@NonNull WireBuffer buffer, int textId, int dataSet, float index) {
buffer.start(OP_CODE);
buffer.writeInt(textId);
buffer.writeInt(dataSet);
buffer.writeFloat(index);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int textId = buffer.readInt();
int dataSetId = buffer.readInt();
float index = buffer.readFloat();
operations.add(new TextLookup(textId, dataSetId, index));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("Look an array and turn into a text object")
.field(INT, "textId", "id of the text generated")
@@ -115,11 +119,12 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
int id = context.getCollectionsAccess().getId(mDataSetId, (int) mOutIndex);
context.loadText(mTextId, context.getText(id));
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java
index 171bea2..ea550cb 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -45,10 +47,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTextId, mDataSetId, mIndex);
}
+ @NonNull
@Override
public String toString() {
return "TextLookupInt["
@@ -60,15 +63,16 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mOutIndex = context.getInteger(mIndex);
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
context.listensTo(mIndex, this);
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -85,21 +89,21 @@
* @param dataSet float pointer to the array/list to turn int a string
* @param indexId index of element to return
*/
- public static void apply(WireBuffer buffer, int textId, int dataSet, int indexId) {
+ public static void apply(@NonNull WireBuffer buffer, int textId, int dataSet, int indexId) {
buffer.start(OP_CODE);
buffer.writeInt(textId);
buffer.writeInt(dataSet);
buffer.writeInt(indexId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int textId = buffer.readInt();
int dataSetId = buffer.readInt();
int indexId = buffer.readInt();
operations.add(new TextLookupInt(textId, dataSetId, indexId));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("Look up an array and turn into a text object")
.field(DocumentedOperation.INT, "textId", "id of the text generated")
@@ -108,11 +112,12 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
int id = context.getCollectionsAccess().getId(mDataSetId, (int) mOutIndex);
context.loadText(mTextId, context.getText(id));
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java
index 78cc674..fa18b4d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -41,15 +43,17 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTextId, mSrcId1, mSrcId2);
}
+ @NonNull
@Override
public String toString() {
return "TextMerge[" + mTextId + "] = [" + mSrcId1 + " ] + [ " + mSrcId2 + "]";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -66,14 +70,14 @@
* @param srcId1 source text 1
* @param srcId2 source text 2
*/
- public static void apply(WireBuffer buffer, int textId, int srcId1, int srcId2) {
+ public static void apply(@NonNull WireBuffer buffer, int textId, int srcId1, int srcId2) {
buffer.start(OP_CODE);
buffer.writeInt(textId);
buffer.writeInt(srcId1);
buffer.writeInt(srcId2);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int textId = buffer.readInt();
int srcId1 = buffer.readInt();
int srcId2 = buffer.readInt();
@@ -81,7 +85,7 @@
operations.add(new TextMerge(textId, srcId1, srcId2));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Merge two string into one")
.field(DocumentedOperation.INT, "textId", "id of the text")
@@ -90,12 +94,13 @@
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
String str1 = context.getText(mSrcId1);
String str2 = context.getText(mSrcId2);
context.loadText(mTextId, str1 + str2);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
index 845f25d..1e90ab1 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteComposeOperation;
@@ -49,25 +51,28 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mTheme);
}
+ @NonNull
@Override
public String toString() {
return "SET_THEME " + mTheme;
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.setTheme(mTheme);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return indent + toString();
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -76,17 +81,17 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, int theme) {
+ public static void apply(@NonNull WireBuffer buffer, int theme) {
buffer.start(OP_CODE);
buffer.writeInt(theme);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int theme = buffer.readInt();
operations.add(new Theme(theme));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Protocol Operations", OP_CODE, CLASS_NAME)
.description("Set a theme")
.field(INT, "THEME", "theme id")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
new file mode 100644
index 0000000..b25a7f6
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
@@ -0,0 +1,599 @@
+/*
+ * 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.widget.remotecompose.core.operations;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY;
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.SHORT;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.TouchListener;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression;
+import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap;
+import com.android.internal.widget.remotecompose.core.operations.utilities.touch.VelocityEasing;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Operation to deal with Touch handling (typically on canvas) This support handling of many typical
+ * touch behaviours. Including animating to Notched, positions. and tweaking the dynamics of the
+ * animation.
+ */
+public class TouchExpression implements Operation, VariableSupport, TouchListener {
+ private static final int OP_CODE = Operations.TOUCH_EXPRESSION;
+ private static final String CLASS_NAME = "TouchExpression";
+ private float mDefValue;
+ private float mOutDefValue;
+ public int mId;
+ public float[] mSrcExp;
+ int mMode = 1; // 0 = delta, 1 = absolute
+ float mMax = 1;
+ float mMin = 1;
+ float mOutMax = 1;
+ float mOutMin = 1;
+ float mValue = 0;
+ boolean mUnmodified = true;
+ public float[] mPreCalcValue;
+ private float mLastChange = Float.NaN;
+ private float mLastCalculatedValue = Float.NaN;
+ AnimatedFloatExpression mExp = new AnimatedFloatExpression();
+ public static final int MAX_EXPRESSION_SIZE = 32;
+ private VelocityEasing mEasyTouch = new VelocityEasing();
+ private boolean mEasingToStop = false;
+ private float mTouchUpTime = 0;
+ private float mCurrentValue = Float.NaN;
+ private boolean mTouchDown = false;
+ float mMaxTime = 1;
+ float mMaxAcceleration = 5;
+ float mMaxVelocity = 7;
+ int mStopMode = 0;
+ boolean mWrapMode = false;
+ float[] mNotches;
+ float[] mStopSpec;
+ int mTouchEffects;
+ float mVelocityId;
+
+ public static final int STOP_GENTLY = 0;
+ public static final int STOP_ENDS = 2;
+ public static final int STOP_INSTANTLY = 1;
+ public static final int STOP_NOTCHES_EVEN = 3;
+ public static final int STOP_NOTCHES_PERCENTS = 4;
+ public static final int STOP_NOTCHES_ABSOLUTE = 5;
+ public static final int STOP_ABSOLUTE_POS = 6;
+
+ public TouchExpression(
+ int id,
+ float[] exp,
+ float defValue,
+ float min,
+ float max,
+ int touchEffects,
+ float velocityId,
+ int stopMode,
+ float[] stopSpec,
+ float[] easingSpec) {
+ this.mId = id;
+ this.mSrcExp = exp;
+ mOutDefValue = mDefValue = defValue;
+ mMode = STOP_ABSOLUTE_POS == stopMode ? 1 : 0;
+ mOutMax = mMax = max;
+ mTouchEffects = touchEffects;
+ mVelocityId = velocityId;
+ if (Float.isNaN(min) && Utils.idFromNan(min) == 0) {
+ mWrapMode = true;
+ } else {
+ mOutMin = mMin = min;
+ }
+ mStopMode = stopMode;
+ mStopSpec = stopSpec;
+ if (easingSpec != null) {
+ Utils.log("easingSpec " + Arrays.toString(easingSpec));
+ if (easingSpec.length >= 4) {
+ if (Float.floatToRawIntBits(easingSpec[0]) == 0) {
+ Utils.log("easingSpec[2] " + easingSpec[2]);
+ mMaxTime = easingSpec[1];
+ mMaxAcceleration = easingSpec[2];
+ mMaxVelocity = easingSpec[3];
+ }
+ }
+ }
+ }
+
+ @Override
+ public void updateVariables(RemoteContext context) {
+
+ if (mPreCalcValue == null || mPreCalcValue.length != mSrcExp.length) {
+ mPreCalcValue = new float[mSrcExp.length];
+ }
+ if (Float.isNaN(mMax)) {
+ mOutMax = context.getFloat(Utils.idFromNan(mMax));
+ }
+ if (Float.isNaN(mMin)) {
+ mOutMin = context.getFloat(Utils.idFromNan(mMin));
+ }
+ if (Float.isNaN(mDefValue)) {
+ mOutDefValue = context.getFloat(Utils.idFromNan(mDefValue));
+ }
+
+ boolean value_changed = false;
+ for (int i = 0; i < mSrcExp.length; i++) {
+ float v = mSrcExp[i];
+ if (Float.isNaN(v)
+ && !AnimatedFloatExpression.isMathOperator(v)
+ && !NanMap.isDataVariable(v)) {
+ float newValue = context.getFloat(Utils.idFromNan(v));
+
+ mPreCalcValue[i] = newValue;
+
+ } else {
+ mPreCalcValue[i] = mSrcExp[i];
+ }
+ }
+ float v = mLastCalculatedValue;
+ if (value_changed) { // inputs changed check if output changed
+ v = mExp.eval(mPreCalcValue, mPreCalcValue.length);
+ if (v != mLastCalculatedValue) {
+ mLastChange = context.getAnimationTime();
+ mLastCalculatedValue = v;
+ } else {
+ value_changed = false;
+ }
+ }
+ }
+
+ @Override
+ public void registerListening(RemoteContext context) {
+ if (Float.isNaN(mMax)) {
+ context.listensTo(Utils.idFromNan(mMax), this);
+ }
+ if (Float.isNaN(mMin)) {
+ context.listensTo(Utils.idFromNan(mMin), this);
+ }
+ if (Float.isNaN(mDefValue)) {
+ context.listensTo(Utils.idFromNan(mDefValue), this);
+ }
+ context.addTouchListener(this);
+ for (float v : mSrcExp) {
+ if (Float.isNaN(v)
+ && !AnimatedFloatExpression.isMathOperator(v)
+ && !NanMap.isDataVariable(v)) {
+ context.listensTo(Utils.idFromNan(v), this);
+ }
+ }
+ }
+
+ private float wrap(float pos) {
+ if (!mWrapMode) {
+ return pos;
+ }
+ pos = pos % mOutMax;
+ if (pos < 0) {
+ pos += mOutMax;
+ }
+ return pos;
+ }
+
+ private float getStopPosition(float pos, float slope) {
+ float target = pos + slope / mMaxAcceleration;
+ if (mWrapMode) {
+ pos = wrap(pos);
+ target = pos += +slope / mMaxAcceleration;
+ } else {
+ target = Math.max(Math.min(target, mOutMax), mOutMin);
+ }
+ float[] positions = new float[mStopSpec.length];
+ float min = (mWrapMode) ? 0 : mOutMin;
+
+ switch (mStopMode) {
+ case STOP_ENDS:
+ return ((pos + slope) > (mOutMax + min) / 2) ? mOutMax : min;
+ case STOP_INSTANTLY:
+ return pos;
+ case STOP_NOTCHES_EVEN:
+ int evenSpacing = (int) mStopSpec[0];
+ float step = (mOutMax - min) / evenSpacing;
+
+ float notch = min + step * (int) (0.5f + (target - mOutMin) / step);
+
+ notch = Math.max(Math.min(notch, mOutMax), min);
+ return notch;
+ case STOP_NOTCHES_PERCENTS:
+ positions = new float[mStopSpec.length];
+ float minPos = min;
+ float minPosDist = Math.abs(mOutMin - target);
+ for (int i = 0; i < positions.length; i++) {
+ float p = mOutMin + mStopSpec[i] * (mOutMax - mOutMin);
+ float dist = Math.abs(p - target);
+ if (minPosDist > dist) {
+ minPosDist = dist;
+ minPos = p;
+ }
+ }
+ return minPos;
+ case STOP_NOTCHES_ABSOLUTE:
+ positions = mStopSpec;
+ minPos = mOutMin;
+ minPosDist = Math.abs(mOutMin - target);
+ for (int i = 0; i < positions.length; i++) {
+ float dist = Math.abs(positions[i] - target);
+ if (minPosDist > dist) {
+ minPosDist = dist;
+ minPos = positions[i];
+ }
+ }
+ return minPos;
+ case STOP_GENTLY:
+ default:
+ return target;
+ }
+ }
+
+ void haptic(RemoteContext context) {
+ int touch = ((mTouchEffects) & 0xFF);
+ if ((mTouchEffects & (1 << 15)) != 0) {
+ touch = context.getInteger(mTouchEffects & 0x7FFF);
+ }
+
+ context.hapticEffect(touch);
+ }
+
+ float mLastValue = 0;
+
+ void crossNotchCheck(RemoteContext context) {
+ float prev = mLastValue;
+ float next = mCurrentValue;
+ mLastValue = next;
+
+ // System.out.println(mStopMode + " " + prev + " -> " + next);
+ float min = (mWrapMode) ? 0 : mOutMin;
+ float max = mOutMax;
+
+ switch (mStopMode) {
+ case STOP_ENDS:
+ if (((min - prev) * (max - prev) < 0) ^ ((min - next) * (max - next)) < 0) {
+ haptic(context);
+ }
+ break;
+ case STOP_INSTANTLY:
+ haptic(context);
+ break;
+ case STOP_NOTCHES_EVEN:
+ int evenSpacing = (int) mStopSpec[0];
+ float step = (max - min) / evenSpacing;
+ if ((int) ((prev - min) / step) != (int) ((next - min) / step)) {
+ haptic(context);
+ }
+ break;
+ case STOP_NOTCHES_PERCENTS:
+ for (int i = 0; i < mStopSpec.length; i++) {
+ float p = mOutMin + mStopSpec[i] * (mOutMax - mOutMin);
+ if ((prev - p) * (next - p) < 0) {
+ haptic(context);
+ }
+ }
+ break;
+ case STOP_NOTCHES_ABSOLUTE:
+ for (int i = 0; i < mStopSpec.length; i++) {
+ float p = mStopSpec[i];
+ if ((prev - p) * (next - p) < 0) {
+ haptic(context);
+ }
+ }
+ break;
+ case STOP_GENTLY:
+ }
+ }
+
+ float mScrLeft, mScrRight, mScrTop, mScrBottom;
+
+ @Override
+ public void apply(RemoteContext context) {
+ Component comp = context.lastComponent;
+ if (comp != null) {
+ float x = comp.getX();
+ float y = comp.getY();
+ float w = comp.getWidth();
+ float h = comp.getHeight();
+ comp = comp.getParent();
+ while (comp != null) {
+ x += comp.getX();
+ y += comp.getY();
+ comp = comp.getParent();
+ }
+ mScrLeft = x;
+ mScrTop = y;
+ mScrRight = w + x;
+ mScrBottom = h + y;
+ }
+ updateVariables(context);
+ if (mUnmodified) {
+ mCurrentValue = mOutDefValue;
+
+ context.loadFloat(mId, wrap(mCurrentValue));
+ return;
+ }
+ if (mEasingToStop) {
+ float time = context.getAnimationTime() - mTouchUpTime;
+ float value = mEasyTouch.getPos(time);
+ mCurrentValue = value;
+ value = wrap(value);
+ context.loadFloat(mId, value);
+ if (mEasyTouch.getDuration() < time) {
+ mEasingToStop = false;
+ }
+ crossNotchCheck(context);
+ return;
+ }
+ if (mTouchDown) {
+ float value =
+ mExp.eval(context.getCollectionsAccess(), mPreCalcValue, mPreCalcValue.length);
+ if (mMode == 0) {
+ value = mValueAtDown + (value - mDownTouchValue);
+ }
+ if (mWrapMode) {
+ value = wrap(value);
+ } else {
+ value = Math.min(Math.max(value, mOutMin), mOutMax);
+ }
+ mCurrentValue = value;
+ }
+ crossNotchCheck(context);
+ context.loadFloat(mId, wrap(mCurrentValue));
+ }
+
+ float mValueAtDown; // The currently "displayed" value at down
+ float mDownTouchValue; // The calculated value at down
+
+ @Override
+ public void touchDown(RemoteContext context, float x, float y) {
+
+ if (!(x >= mScrLeft && x <= mScrRight && y >= mScrTop && y <= mScrBottom)) {
+ Utils.log("NOT IN WINDOW " + x + ", " + y + " " + mScrLeft + ", " + mScrTop);
+ return;
+ }
+ mTouchDown = true;
+ mUnmodified = false;
+ if (mMode == 0) {
+ mValueAtDown = context.getFloat(mId);
+ mDownTouchValue =
+ mExp.eval(context.getCollectionsAccess(), mPreCalcValue, mPreCalcValue.length);
+ }
+ }
+
+ @Override
+ public void touchUp(RemoteContext context, float x, float y, float dx, float dy) {
+ // calculate the slope (using small changes)
+ if (!mTouchDown) {
+ return;
+ }
+ mTouchDown = false;
+ float dt = 0.0001f;
+ if (mStopMode == STOP_INSTANTLY) {
+ return;
+ }
+ float v = mExp.eval(context.getCollectionsAccess(), mPreCalcValue, mPreCalcValue.length);
+ for (int i = 0; i < mSrcExp.length; i++) {
+ if (Float.isNaN(mSrcExp[i])) {
+ int id = Utils.idFromNan(mSrcExp[i]);
+ if (id == RemoteContext.ID_TOUCH_POS_X) {
+ mPreCalcValue[i] = x + dx * dt;
+ } else if (id == RemoteContext.ID_TOUCH_POS_Y) {
+ mPreCalcValue[i] = y + dy * dt;
+ }
+ }
+ }
+ float vdt = mExp.eval(context.getCollectionsAccess(), mPreCalcValue, mPreCalcValue.length);
+ float slope = (vdt - v) / dt; // the rate of change with respect to the dx,dy movement
+ float value = context.getFloat(mId);
+
+ mTouchUpTime = context.getAnimationTime();
+
+ float dest = getStopPosition(value, slope);
+ mEasyTouch.config(value, dest, slope, mMaxTime, mMaxAcceleration, mMaxVelocity, null);
+ mEasingToStop = true;
+ }
+
+ @Override
+ public void touchDrag(RemoteContext context, float x, float y) {
+ if (!mTouchDown) {
+ return;
+ }
+ apply(context);
+ context.getDocument().getRootLayoutComponent().needsRepaint();
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ apply(
+ buffer,
+ mId,
+ mValue,
+ mMin,
+ mMax,
+ mVelocityId,
+ mTouchEffects,
+ mSrcExp,
+ mStopMode,
+ mNotches,
+ null);
+ }
+
+ @Override
+ public String toString() {
+ String[] labels = new String[mSrcExp.length];
+ for (int i = 0; i < mSrcExp.length; i++) {
+ if (Float.isNaN(mSrcExp[i])) {
+ labels[i] = "[" + Utils.idStringFromNan(mSrcExp[i]) + "]";
+ }
+ }
+ if (mPreCalcValue == null) {
+ return CLASS_NAME
+ + "["
+ + mId
+ + "] = ("
+ + AnimatedFloatExpression.toString(mSrcExp, labels)
+ + ")";
+ }
+ return CLASS_NAME
+ + "["
+ + mId
+ + "] = ("
+ + AnimatedFloatExpression.toString(mPreCalcValue, labels)
+ + ")";
+ }
+
+ // ===================== static ======================
+
+ public static String name() {
+ return CLASS_NAME;
+ }
+
+ public static int id() {
+ return OP_CODE;
+ }
+
+ /**
+ * Writes out the operation to the buffer
+ *
+ * @param buffer The buffer to write to
+ * @param id the id of the resulting float
+ * @param value the float expression array
+ */
+ public static void apply(
+ WireBuffer buffer,
+ int id,
+ float value,
+ float min,
+ float max,
+ float velocityId,
+ int touchEffects,
+ float[] exp,
+ int touchMode,
+ float[] touchSpec,
+ float[] easingSpec) {
+ buffer.start(OP_CODE);
+ buffer.writeInt(id);
+ buffer.writeFloat(value);
+ buffer.writeFloat(min);
+ buffer.writeFloat(max);
+ buffer.writeFloat(velocityId);
+ buffer.writeInt(touchEffects);
+ buffer.writeInt(exp.length);
+ for (float v : exp) {
+ buffer.writeFloat(v);
+ }
+ int len = 0;
+ if (touchSpec != null) {
+ len = touchSpec.length;
+ }
+ buffer.writeInt((touchMode << 16) | len);
+ for (int i = 0; i < len; i++) {
+ buffer.writeFloat(touchSpec[i]);
+ }
+
+ if (easingSpec != null) {
+ len = easingSpec.length;
+ } else {
+ len = 0;
+ }
+ buffer.writeInt(len);
+ for (int i = 0; i < len; i++) {
+ buffer.writeFloat(easingSpec[i]);
+ }
+ }
+
+ public static void read(WireBuffer buffer, List<Operation> operations) {
+ int id = buffer.readInt();
+ float startValue = buffer.readFloat();
+ float min = buffer.readFloat();
+ float max = buffer.readFloat();
+ float velocityId = buffer.readFloat(); // TODO future support
+ int touchEffects = buffer.readInt();
+ int len = buffer.readInt();
+ int valueLen = len & 0xFFFF;
+ if (valueLen > MAX_EXPRESSION_SIZE) {
+ throw new RuntimeException("Float expression to long");
+ }
+ float[] exp = new float[valueLen];
+ for (int i = 0; i < exp.length; i++) {
+ exp[i] = buffer.readFloat();
+ }
+ int stopLogic = buffer.readInt();
+ int stopLen = stopLogic & 0xFFFF;
+ int stopMode = stopLogic >> 16;
+
+ Utils.log("stopMode " + stopMode + " stopLen " + stopLen);
+ float[] stopsData = new float[stopLen];
+ for (int i = 0; i < stopsData.length; i++) {
+ stopsData[i] = buffer.readFloat();
+ }
+ int easingLen = buffer.readInt();
+
+ float[] easingData = new float[easingLen];
+ for (int i = 0; i < easingData.length; i++) {
+ easingData[i] = buffer.readFloat();
+ }
+
+ operations.add(
+ new TouchExpression(
+ id,
+ exp,
+ startValue,
+ min,
+ max,
+ touchEffects,
+ velocityId,
+ stopMode,
+ stopsData,
+ easingData));
+ }
+
+ public static void documentation(DocumentationBuilder doc) {
+ doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
+ .description("A Float expression")
+ .field(INT, "id", "The id of the Color")
+ .field(SHORT, "expression_length", "expression length")
+ .field(SHORT, "animation_length", "animation description length")
+ .field(
+ FLOAT_ARRAY,
+ "expression",
+ "expression_length",
+ "Sequence of Floats representing and expression")
+ .field(
+ FLOAT_ARRAY,
+ "AnimationSpec",
+ "animation_length",
+ "Sequence of Floats representing animation curve")
+ .field(FLOAT, "duration", "> time in sec")
+ .field(INT, "bits", "> WRAP|INITALVALUE | TYPE ")
+ .field(FLOAT_ARRAY, "spec", "> [SPEC PARAMETERS] ")
+ .field(FLOAT, "initialValue", "> [Initial value] ")
+ .field(FLOAT, "wrapValue", "> [Wrap value] ");
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return indent + toString();
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
index 8ebb40c..03f7e05 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations;
+import android.annotation.NonNull;
+
/** Utilities to be used across all core operations */
public class Utils {
public static float asNan(int v) {
@@ -30,11 +32,13 @@
return v - 0x100000000L;
}
+ @NonNull
public static String idStringFromNan(float value) {
int b = Float.floatToRawIntBits(value) & 0x3FFFFF;
return idString(b);
}
+ @NonNull
public static String idString(int b) {
return (b > 0xFFFFF) ? "A_" + (b & 0xFFFFF) : "" + b;
}
@@ -50,7 +54,8 @@
* @param n
* @return
*/
- public static String trimString(String str, int n) {
+ @NonNull
+ public static String trimString(@NonNull String str, int n) {
if (str.length() > n) {
str = str.substring(0, n - 3) + "...";
}
@@ -145,6 +150,7 @@
* @param color
* @return
*/
+ @NonNull
public static String colorInt(int color) {
String str = "000000000000" + Integer.toHexString(color);
return "0x" + str.substring(str.length() - 8);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/AnimatableValue.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/AnimatableValue.java
new file mode 100644
index 0000000..e789710
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/AnimatableValue.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.operations.Utils;
+import com.android.internal.widget.remotecompose.core.operations.utilities.easing.FloatAnimation;
+import com.android.internal.widget.remotecompose.core.operations.utilities.easing.GeneralEasing;
+
+public class AnimatableValue {
+ boolean mIsVariable = false;
+ int mId = 0;
+ float mValue = 0f;
+
+ boolean mAnimate = false;
+ long mAnimateTargetTime = 0;
+ float mAnimateDuration = 300f;
+ float mTargetRotationX;
+ float mStartRotationX;
+
+ int mMotionEasingType = GeneralEasing.CUBIC_STANDARD;
+ FloatAnimation mMotionEasing;
+
+ public AnimatableValue(float value) {
+ if (Utils.isVariable(value)) {
+ mId = Utils.idFromNan(value);
+ mIsVariable = true;
+ } else {
+ mValue = value;
+ }
+ }
+
+ public float getValue() {
+ return mValue;
+ }
+
+ public float evaluate(PaintContext context) {
+ if (!mIsVariable) {
+ return mValue;
+ }
+ float value = context.getContext().mRemoteComposeState.getFloat(mId);
+
+ if (value != mValue && !mAnimate) {
+ // animate
+ mStartRotationX = mValue;
+ mTargetRotationX = value;
+ mAnimate = true;
+ mAnimateTargetTime = System.currentTimeMillis();
+ mMotionEasing =
+ new FloatAnimation(
+ mMotionEasingType, mAnimateDuration / 1000f, null, 0f, Float.NaN);
+ mMotionEasing.setTargetValue(1f);
+ }
+ if (mAnimate) {
+ float elapsed = System.currentTimeMillis() - mAnimateTargetTime;
+ float p = mMotionEasing.get(elapsed / mAnimateDuration);
+ mValue = (1 - p) * mStartRotationX + p * mTargetRotationX;
+ if (p >= 1f) {
+ mAnimate = false;
+ }
+ } else {
+ mValue = mTargetRotationX;
+ }
+
+ return mValue;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
index 9d80d3c..9886518 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.WireBuffer;
@@ -38,6 +40,7 @@
super(parent, componentId, animationId, x, y, width, height);
}
+ @NonNull
public static String name() {
return "CanvasContent";
}
@@ -46,29 +49,30 @@
return Operations.LAYOUT_CANVAS_CONTENT;
}
+ @NonNull
@Override
protected String getSerializedName() {
return "CANVAS_CONTENT";
}
- public static void apply(WireBuffer buffer, int componentId) {
+ public static void apply(@NonNull WireBuffer buffer, int componentId) {
buffer.start(Operations.LAYOUT_CANVAS_CONTENT);
buffer.writeInt(componentId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int componentId = buffer.readInt();
operations.add(new CanvasContent(componentId, 0, 0, 0, 0, null, -1));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.field(INT, "COMPONENT_ID", "unique id for this component")
.description("Container for canvas commands.");
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mComponentId);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickHandler.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickHandler.java
new file mode 100644
index 0000000..0ca72fa
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickHandler.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+
+/** Interface to represent operations that can handle click events */
+public interface ClickHandler {
+
+ /**
+ * callback for a click event
+ *
+ * @param context the current context
+ * @param document the current document
+ * @param component the component on which the click has been received
+ * @param x the x position of the click in document coordinates
+ * @param y the y position of the click in document coordinates
+ */
+ void onClick(
+ RemoteContext context, CoreDocument document, Component component, float x, float y);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
index d5ff07d..b567538 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -37,7 +40,7 @@
/** Represents a click modifier + actions */
public class ClickModifierOperation extends PaintOperation
- implements ModifierOperation, DecoratorComponent {
+ implements ModifierOperation, DecoratorComponent, ClickHandler {
private static final int OP_CODE = Operations.MODIFIER_CLICK;
long mAnimateRippleStart = 0;
@@ -48,9 +51,9 @@
float mWidth = 0;
float mHeight = 0;
- public float[] locationInWindow = new float[2];
+ @NonNull public float[] locationInWindow = new float[2];
- PaintBundle mPaint = new PaintBundle();
+ @NonNull PaintBundle mPaint = new PaintBundle();
public void animateRipple(float x, float y) {
mAnimateRippleStart = System.currentTimeMillis();
@@ -58,17 +61,19 @@
mAnimateRippleY = y;
}
- public ArrayList<Operation> mList = new ArrayList<>();
+ @NonNull public ArrayList<Operation> mList = new ArrayList<>();
+ @NonNull
public ArrayList<Operation> getList() {
return mList;
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer);
}
+ @NonNull
@Override
public String toString() {
return "ClickModifier";
@@ -83,13 +88,14 @@
}
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
if (mAnimateRippleStart == 0) {
return;
}
@@ -137,7 +143,7 @@
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(indent, "CLICK_MODIFIER");
for (Operation o : mList) {
if (o instanceof ActionOperation) {
@@ -148,7 +154,11 @@
@Override
public void onClick(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ RemoteContext context,
+ CoreDocument document,
+ @NonNull Component component,
+ float x,
+ float y) {
if (!component.isVisible()) {
return;
}
@@ -163,19 +173,20 @@
}
}
+ @NonNull
public static String name() {
return "ClickModifier";
}
- public static void apply(WireBuffer buffer) {
+ public static void apply(@NonNull WireBuffer buffer) {
buffer.start(OP_CODE);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
operations.add(new ClickModifierOperation());
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", OP_CODE, name())
.description(
"Click modifier. This operation contains"
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
index 96dffca..f4f4ee2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -31,7 +34,6 @@
import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
import com.android.internal.widget.remotecompose.core.operations.layout.measure.Measurable;
import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
-import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers;
import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
@@ -52,16 +54,23 @@
protected int mAnimationId = -1;
public Visibility mVisibility = Visibility.VISIBLE;
public Visibility mScheduledVisibility = Visibility.VISIBLE;
- public ArrayList<Operation> mList = new ArrayList<>();
+ @NonNull public ArrayList<Operation> mList = new ArrayList<>();
public PaintOperation mPreTranslate;
public boolean mNeedsMeasure = true;
public boolean mNeedsRepaint = false;
- public AnimateMeasure mAnimateMeasure;
- public AnimationSpec mAnimationSpec = new AnimationSpec();
+ @Nullable public AnimateMeasure mAnimateMeasure;
+ @NonNull public AnimationSpec mAnimationSpec = new AnimationSpec();
public boolean mFirstLayout = true;
- PaintBundle mPaint = new PaintBundle();
- protected HashSet<ComponentValue> mComponentValues = new HashSet<>();
+ @NonNull PaintBundle mPaint = new PaintBundle();
+ @NonNull protected HashSet<ComponentValue> mComponentValues = new HashSet<>();
+ protected float mZIndex = 0f;
+
+ public float getZIndex() {
+ return mZIndex;
+ }
+
+ @NonNull
public ArrayList<Operation> getList() {
return mList;
}
@@ -115,7 +124,7 @@
*
* @param context the current context
*/
- private void updateComponentValues(RemoteContext context) {
+ private void updateComponentValues(@NonNull RemoteContext context) {
if (DEBUG) {
System.out.println(
"UPDATE COMPONENT VALUES ("
@@ -172,7 +181,7 @@
this(parent, componentId, -1, x, y, width, height);
}
- public Component(Component component) {
+ public Component(@NonNull Component component) {
this(
component.mParent,
component.mComponentId,
@@ -212,7 +221,10 @@
*
* @param context the current context
*/
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
+ Component prev = context.lastComponent;
+ context.lastComponent = this;
+
if (!mComponentValues.isEmpty()) {
updateComponentValues(context);
}
@@ -224,6 +236,7 @@
o.apply(context);
}
}
+ context.lastComponent = prev;
}
public void addComponentValue(ComponentValue v) {
@@ -283,14 +296,14 @@
float maxWidth,
float minHeight,
float maxHeight,
- MeasurePass measure) {
+ @NonNull MeasurePass measure) {
ComponentMeasure m = measure.get(this);
m.setW(mWidth);
m.setH(mHeight);
}
@Override
- public void layout(RemoteContext context, MeasurePass measure) {
+ public void layout(@NonNull RemoteContext context, @NonNull MeasurePass measure) {
ComponentMeasure m = measure.get(this);
if (!mFirstLayout
&& context.isAnimationEnabled()
@@ -332,7 +345,7 @@
mFirstLayout = false;
}
- public float[] locationInWindow = new float[2];
+ @NonNull public float[] locationInWindow = new float[2];
public boolean contains(float x, float y) {
locationInWindow[0] = 0f;
@@ -353,13 +366,57 @@
if (op instanceof Component) {
((Component) op).onClick(context, document, x, y);
}
- if (op instanceof ComponentModifiers) {
- ((ComponentModifiers) op).onClick(context, document, this, x, y);
+ if (op instanceof ClickHandler) {
+ ((ClickHandler) op).onClick(context, document, this, x, y);
}
}
}
- public void getLocationInWindow(float[] value) {
+ public void onTouchDown(RemoteContext context, CoreDocument document, float x, float y) {
+ if (!contains(x, y)) {
+ return;
+ }
+ for (Operation op : mList) {
+ if (op instanceof Component) {
+ ((Component) op).onTouchDown(context, document, x, y);
+ }
+ if (op instanceof TouchHandler) {
+ ((TouchHandler) op).onTouchDown(context, document, this, x, y);
+ }
+ }
+ }
+
+ public void onTouchUp(
+ RemoteContext context, CoreDocument document, float x, float y, boolean force) {
+ if (!force && !contains(x, y)) {
+ return;
+ }
+ for (Operation op : mList) {
+ if (op instanceof Component) {
+ ((Component) op).onTouchUp(context, document, x, y, force);
+ }
+ if (op instanceof TouchHandler) {
+ ((TouchHandler) op).onTouchUp(context, document, this, x, y);
+ }
+ }
+ }
+
+ public void onTouchCancel(
+ RemoteContext context, CoreDocument document, float x, float y, boolean force) {
+ if (!force && !contains(x, y)) {
+ return;
+ }
+ for (Operation op : mList) {
+ if (op instanceof Component) {
+ ((Component) op).onTouchCancel(context, document, x, y, force);
+ }
+ if (op instanceof TouchHandler) {
+ ((TouchHandler) op).onTouchCancel(context, document, this, x, y);
+ }
+ }
+ }
+
+ public void getLocationInWindow(@NonNull float[] value) {
value[0] += mX;
value[1] += mY;
if (mParent != null) {
@@ -372,6 +429,7 @@
}
}
+ @NonNull
@Override
public String toString() {
return "COMPONENT(<"
@@ -393,14 +451,14 @@
+ ") ";
}
+ @NonNull
protected String getSerializedName() {
return "COMPONENT";
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
- serializer.append(
- indent,
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
+ String content =
getSerializedName()
+ " ["
+ mComponentId
@@ -416,9 +474,9 @@
+ ", "
+ mHeight
+ "] "
- + mVisibility
- // + " [" + mNeedsMeasure + ", " + mNeedsRepaint + "]"
- );
+ + mVisibility;
+ // + " [" + mNeedsMeasure + ", " + mNeedsRepaint + "]"
+ serializer.append(indent, content);
}
@Override
@@ -427,6 +485,7 @@
}
/** Returns the top-level RootLayoutComponent */
+ @NonNull
public RootLayoutComponent getRoot() throws Exception {
if (this instanceof RootLayoutComponent) {
return (RootLayoutComponent) this;
@@ -441,6 +500,7 @@
return (RootLayoutComponent) p;
}
+ @NonNull
@Override
public String deepToString(String indent) {
StringBuilder builder = new StringBuilder();
@@ -477,6 +537,7 @@
}
}
+ @NonNull
public String content() {
StringBuilder builder = new StringBuilder();
for (Operation op : mList) {
@@ -487,6 +548,7 @@
return builder.toString();
}
+ @NonNull
public String textContent() {
StringBuilder builder = new StringBuilder();
for (Operation ignored : mList) {
@@ -499,7 +561,7 @@
return builder.toString();
}
- public void debugBox(Component component, PaintContext context) {
+ public void debugBox(@NonNull Component component, @NonNull PaintContext context) {
float width = component.mWidth;
float height = component.mHeight;
@@ -536,13 +598,15 @@
return 0f;
}
- public void paintingComponent(PaintContext context) {
+ public void paintingComponent(@NonNull PaintContext context) {
if (mPreTranslate != null) {
mPreTranslate.paint(context);
}
+ Component prev = context.getContext().lastComponent;
+ context.getContext().lastComponent = this;
context.save();
context.translate(mX, mY);
- if (context.isDebug()) {
+ if (context.isVisualDebug()) {
debugBox(this, context);
}
for (Operation op : mList) {
@@ -554,9 +618,10 @@
}
}
context.restore();
+ context.getContext().lastComponent = prev;
}
- public boolean applyAnimationAsNeeded(PaintContext context) {
+ public boolean applyAnimationAsNeeded(@NonNull PaintContext context) {
if (context.isAnimationEnabled() && mAnimateMeasure != null) {
mAnimateMeasure.apply(context);
needsRepaint();
@@ -566,8 +631,8 @@
}
@Override
- public void paint(PaintContext context) {
- if (context.isDebug()) {
+ public void paint(@NonNull PaintContext context) {
+ if (context.isVisualDebug()) {
context.save();
context.translate(mX, mY);
context.savePaint();
@@ -594,7 +659,7 @@
paintingComponent(context);
}
- public void getComponents(ArrayList<Component> components) {
+ public void getComponents(@NonNull ArrayList<Component> components) {
for (Operation op : mList) {
if (op instanceof Component) {
components.add((Component) op);
@@ -602,7 +667,7 @@
}
}
- public void getData(ArrayList<TextData> data) {
+ public void getData(@NonNull ArrayList<TextData> data) {
for (Operation op : mList) {
if (op instanceof TextData) {
data.add((TextData) op);
@@ -631,6 +696,7 @@
return mNeedsRepaint;
}
+ @Nullable
public Component getComponent(int cid) {
if (mComponentId == cid || mAnimationId == cid) {
return this;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
index c83ee487..f370e20 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -26,10 +29,11 @@
public class ComponentEnd implements Operation {
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer);
}
+ @NonNull
@Override
public String toString() {
return "COMPONENT_END";
@@ -40,11 +44,13 @@
// nothing
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
+ @NonNull
public static String name() {
return "ComponentEnd";
}
@@ -53,7 +59,7 @@
return Operations.COMPONENT_END;
}
- public static void apply(WireBuffer buffer) {
+ public static void apply(@NonNull WireBuffer buffer) {
buffer.start(Operations.COMPONENT_END);
}
@@ -61,11 +67,11 @@
return 1 + 4 + 4 + 4;
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
operations.add(new ComponentEnd());
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.description(
"End tag for components / layouts. This operation marks the end"
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
index 72cc9b6..f250d9a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
@@ -18,6 +18,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -69,10 +72,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mType, mComponentId, mWidth, mHeight);
}
+ @NonNull
@Override
public String toString() {
return "COMPONENT_START (type "
@@ -90,8 +94,9 @@
+ ")";
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -119,6 +124,7 @@
public static final int LAYOUT_ROW = 15;
public static final int LAYOUT_COLUMN = 16;
+ @NonNull
public static String typeDescription(int type) {
switch (type) {
case DEFAULT:
@@ -152,6 +158,7 @@
}
}
+ @NonNull
public static String name() {
return "ComponentStart";
}
@@ -161,7 +168,7 @@
}
public static void apply(
- WireBuffer buffer, int type, int componentId, float width, float height) {
+ @NonNull WireBuffer buffer, int type, int componentId, float width, float height) {
buffer.start(Operations.COMPONENT_START);
buffer.writeInt(type);
buffer.writeInt(componentId);
@@ -173,7 +180,7 @@
return 1 + 4 + 4 + 4;
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int type = buffer.readInt();
int componentId = buffer.readInt();
float width = buffer.readFloat();
@@ -181,7 +188,7 @@
operations.add(new ComponentStart(type, componentId, width, height));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.description(
"Basic component encapsulating draw commands." + "This is not resizable.")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java
index 314650f..bb43119 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java
@@ -15,7 +15,6 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
-import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.RemoteContext;
/**
@@ -24,7 +23,4 @@
*/
public interface DecoratorComponent {
void layout(RemoteContext context, float width, float height);
-
- void onClick(
- RemoteContext context, CoreDocument document, Component component, float x, float y);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
index 8172502..e0923dfb 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.operations.BitmapData;
@@ -25,18 +28,22 @@
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentVisibilityOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.DimensionModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.GraphicsLayerModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HeightModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.WidthModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ZIndexModifierOperation;
import java.util.ArrayList;
/** Component with modifiers and children */
public class LayoutComponent extends Component {
- protected WidthModifierOperation mWidthModifier = null;
- protected HeightModifierOperation mHeightModifier = null;
+ @Nullable protected WidthModifierOperation mWidthModifier = null;
+ @Nullable protected HeightModifierOperation mHeightModifier = null;
+ @Nullable protected ZIndexModifierOperation mZIndexModifier = null;
+ @Nullable protected GraphicsLayerModifierOperation mGraphicsLayerModifier = null;
// Margins
protected float mMarginLeft = 0f;
@@ -49,8 +56,10 @@
protected float mPaddingTop = 0f;
protected float mPaddingBottom = 0f;
- protected ComponentModifiers mComponentModifiers = new ComponentModifiers();
- protected ArrayList<Component> mChildrenComponents = new ArrayList<>();
+ @NonNull protected ComponentModifiers mComponentModifiers = new ComponentModifiers();
+ @NonNull protected ArrayList<Component> mChildrenComponents = new ArrayList<>();
+
+ protected boolean mChildrenHaveZIndex = false;
public LayoutComponent(
Component parent,
@@ -95,15 +104,25 @@
return mPaddingBottom;
}
+ @Nullable
public WidthModifierOperation getWidthModifier() {
return mWidthModifier;
}
+ @Nullable
public HeightModifierOperation getHeightModifier() {
return mHeightModifier;
}
- protected LayoutComponentContent mContent = null;
+ @Override
+ public float getZIndex() {
+ if (mZIndexModifier != null) {
+ return mZIndexModifier.getValue();
+ }
+ return mZIndex;
+ }
+
+ @Nullable protected LayoutComponentContent mContent = null;
// Should be removed after ImageLayout is in
private static final boolean USE_IMAGE_TEMP_FIX = true;
@@ -164,6 +183,9 @@
for (Component c : mChildrenComponents) {
c.mParent = this;
mList.add(c);
+ if (c instanceof LayoutComponent && ((LayoutComponent) c).mZIndexModifier != null) {
+ mChildrenHaveZIndex = true;
+ }
}
mX = 0f;
@@ -209,6 +231,12 @@
mHeightModifier = (HeightModifierOperation) op;
applyVerticalMargin = false;
}
+ if (op instanceof ZIndexModifierOperation) {
+ mZIndexModifier = (ZIndexModifierOperation) op;
+ }
+ if (op instanceof GraphicsLayerModifierOperation) {
+ mGraphicsLayerModifier = (GraphicsLayerModifierOperation) op;
+ }
}
if (mWidthModifier == null) {
mWidthModifier = new WidthModifierOperation(DimensionModifierOperation.Type.WRAP);
@@ -220,24 +248,64 @@
setHeight(computeModifierDefinedHeight());
}
+ @NonNull
@Override
public String toString() {
return "UNKNOWN LAYOUT_COMPONENT";
}
@Override
- public void paintingComponent(PaintContext context) {
+ public void paintingComponent(@NonNull PaintContext context) {
+ Component prev = context.getContext().lastComponent;
+ context.getContext().lastComponent = this;
context.save();
context.translate(mX, mY);
+ if (mGraphicsLayerModifier != null) {
+ context.startGraphicsLayer((int) getWidth(), (int) getHeight());
+ float scaleX = mGraphicsLayerModifier.getScaleX();
+ float scaleY = mGraphicsLayerModifier.getScaleY();
+ float rotationX = mGraphicsLayerModifier.getRotationX();
+ float rotationY = mGraphicsLayerModifier.getRotationY();
+ float rotationZ = mGraphicsLayerModifier.getRotationZ();
+ float shadowElevation = mGraphicsLayerModifier.getShadowElevation();
+ float transformOriginX = mGraphicsLayerModifier.getTransformOriginX();
+ float transformOriginY = mGraphicsLayerModifier.getTransformOriginY();
+ float alpha = mGraphicsLayerModifier.getAlpha();
+ int renderEffectId = mGraphicsLayerModifier.getRenderEffectId();
+ context.setGraphicsLayer(
+ scaleX,
+ scaleY,
+ rotationX,
+ rotationY,
+ rotationZ,
+ shadowElevation,
+ transformOriginX,
+ transformOriginY,
+ alpha,
+ renderEffectId);
+ }
mComponentModifiers.paint(context);
float tx = mPaddingLeft;
float ty = mPaddingTop;
context.translate(tx, ty);
- for (Component child : mChildrenComponents) {
- child.paint(context);
+ if (mChildrenHaveZIndex) {
+ // TODO -- should only sort when something has changed
+ ArrayList<Component> sorted = new ArrayList<Component>(mChildrenComponents);
+ sorted.sort((a, b) -> (int) (a.getZIndex() - b.getZIndex()));
+ for (Component child : sorted) {
+ child.paint(context);
+ }
+ } else {
+ for (Component child : mChildrenComponents) {
+ child.paint(context);
+ }
+ }
+ if (mGraphicsLayerModifier != null) {
+ context.endGraphicsLayer();
}
context.translate(-tx, -ty);
context.restore();
+ context.getContext().lastComponent = prev;
}
/** Traverse the modifiers to compute indicated dimension */
@@ -248,7 +316,8 @@
for (Operation c : mComponentModifiers.getList()) {
if (c instanceof WidthModifierOperation) {
WidthModifierOperation o = (WidthModifierOperation) c;
- if (o.getType() == DimensionModifierOperation.Type.EXACT) {
+ if (o.getType() == DimensionModifierOperation.Type.EXACT
+ || o.getType() == DimensionModifierOperation.Type.EXACT_DP) {
w = o.getValue();
}
break;
@@ -291,7 +360,8 @@
for (Operation c : mComponentModifiers.getList()) {
if (c instanceof HeightModifierOperation) {
HeightModifierOperation o = (HeightModifierOperation) c;
- if (o.getType() == DimensionModifierOperation.Type.EXACT) {
+ if (o.getType() == DimensionModifierOperation.Type.EXACT
+ || o.getType() == DimensionModifierOperation.Type.EXACT_DP) {
h = o.getValue();
}
break;
@@ -326,6 +396,7 @@
return t + b;
}
+ @NonNull
public ArrayList<Component> getChildrenComponents() {
return mChildrenComponents;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
index 66fd053..0a085b4 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.WireBuffer;
@@ -38,6 +40,7 @@
super(parent, componentId, animationId, x, y, width, height);
}
+ @NonNull
public static String name() {
return "LayoutContent";
}
@@ -46,22 +49,23 @@
return Operations.LAYOUT_CONTENT;
}
+ @NonNull
@Override
protected String getSerializedName() {
return "CONTENT";
}
- public static void apply(WireBuffer buffer, int componentId) {
+ public static void apply(@NonNull WireBuffer buffer, int componentId) {
buffer.start(Operations.LAYOUT_CONTENT);
buffer.writeInt(componentId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int componentId = buffer.readInt();
operations.add(new LayoutComponentContent(componentId, 0, 0, 0, 0, null, -1));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.field(INT, "COMPONENT_ID", "unique id for this component")
.description(
@@ -71,7 +75,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mComponentId);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
new file mode 100644
index 0000000..c4df075
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.operations.TextData;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.ArrayList;
+
+public abstract class ListActionsOperation extends PaintOperation
+ implements ModifierOperation, DecoratorComponent {
+
+ String mOperationName;
+ float mWidth = 0;
+ float mHeight = 0;
+
+ private final float[] mLocationInWindow = new float[2];
+
+ public ListActionsOperation(String operationName) {
+ mOperationName = operationName;
+ }
+
+ public ArrayList<Operation> mList = new ArrayList<>();
+
+ public ArrayList<Operation> getList() {
+ return mList;
+ }
+
+ @Override
+ public String toString() {
+ return mOperationName;
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ for (Operation op : mList) {
+ if (op instanceof TextData) {
+ op.apply(context);
+ }
+ }
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void paint(PaintContext context) {}
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {
+ mWidth = width;
+ mHeight = height;
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, mOperationName);
+ for (Operation o : mList) {
+ if (o instanceof ActionOperation) {
+ ((ActionOperation) o).serializeToString(indent + 1, serializer);
+ }
+ }
+ }
+
+ public boolean applyActions(
+ RemoteContext context,
+ CoreDocument document,
+ Component component,
+ float x,
+ float y,
+ boolean force) {
+ if (!force && !component.isVisible()) {
+ return false;
+ }
+ if (!force && !component.contains(x, y)) {
+ return false;
+ }
+ mLocationInWindow[0] = 0f;
+ mLocationInWindow[1] = 0f;
+ component.getLocationInWindow(mLocationInWindow);
+ for (Operation o : mList) {
+ if (o instanceof ActionOperation) {
+ ((ActionOperation) o).runAction(context, document, component, x, y);
+ }
+ }
+ return true;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java
index 3086d6a..c90077b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -26,10 +29,11 @@
public class LoopEnd implements Operation {
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer);
}
+ @NonNull
@Override
public String toString() {
return "LOOP_END";
@@ -40,11 +44,13 @@
// nothing
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
+ @NonNull
public static String name() {
return "LoopEnd";
}
@@ -53,15 +59,15 @@
return Operations.LOOP_END;
}
- public static void apply(WireBuffer buffer) {
+ public static void apply(@NonNull WireBuffer buffer) {
buffer.start(id());
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
operations.add(new LoopEnd());
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Operations", id(), name()).description("End tag for loops");
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
index 6910008..eeaeafd 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -30,7 +33,7 @@
public class LoopOperation extends PaintOperation {
private static final int OP_CODE = Operations.LOOP_START;
- public ArrayList<Operation> mList = new ArrayList<>();
+ @NonNull public ArrayList<Operation> mList = new ArrayList<>();
int mIndexVariableId;
float mUntil = 12;
@@ -49,27 +52,30 @@
mIndexVariableId = indexId;
}
+ @NonNull
public ArrayList<Operation> getList() {
return mList;
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mUntil, mFrom, mStep, mIndexVariableId);
}
+ @NonNull
@Override
public String toString() {
return "LoopOperation";
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
if (mIndexVariableId == 0) {
for (float i = mFrom; i < mUntil; i += mStep) {
for (Operation op : mList) {
@@ -89,11 +95,13 @@
}
}
+ @NonNull
public static String name() {
return "Loop";
}
- public static void apply(WireBuffer buffer, float count, float from, float step, int indexId) {
+ public static void apply(
+ @NonNull WireBuffer buffer, float count, float from, float step, int indexId) {
buffer.start(OP_CODE);
buffer.writeFloat(count);
buffer.writeFloat(from);
@@ -101,7 +109,7 @@
buffer.writeInt(indexId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
float count = buffer.readFloat();
float from = buffer.readFloat();
float step = buffer.readFloat();
@@ -109,7 +117,7 @@
operations.add(new LoopOperation(count, from, step, indexId));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Operations", OP_CODE, name())
.description("Loop. This operation execute" + " a list of action in a loop");
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java
similarity index 68%
rename from core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierEnd.java
rename to core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java
index fe726ac..bd8d1f0 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -23,16 +26,17 @@
import java.util.List;
-public class ClickModifierEnd implements Operation {
+public class OperationsListEnd implements Operation {
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer);
}
+ @NonNull
@Override
public String toString() {
- return "CLICK_END";
+ return "LIST_END";
}
@Override
@@ -40,31 +44,31 @@
// nothing
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
+ @NonNull
public static String name() {
- return "ClickModifierEnd";
+ return "ListEnd";
}
public static int id() {
- return Operations.MODIFIER_CLICK_END;
+ return Operations.OPERATIONS_LIST_END;
}
- public static void apply(WireBuffer buffer) {
+ public static void apply(@NonNull WireBuffer buffer) {
buffer.start(id());
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
- operations.add(new ClickModifierEnd());
+ public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
+ operations.add(new OperationsListEnd());
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
- .description(
- "End tag for click modifiers. This operation marks the end"
- + "of a click modifier");
+ .description("End tag for list of operations.");
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
index 680bb0b..524ae59 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -34,7 +36,8 @@
/** Represents the root layout component. Entry point to the component tree layout/paint. */
public class RootLayoutComponent extends Component implements ComponentStartOperation {
- int mCurrentId = -1;
+ private int mCurrentId = -1;
+ private boolean mHasTouchListeners = false;
public RootLayoutComponent(
int componentId,
@@ -52,6 +55,7 @@
super(parent, componentId, -1, x, y, width, height);
}
+ @NonNull
@Override
public String toString() {
return "ROOT "
@@ -69,7 +73,7 @@
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(
indent,
"ROOT ["
@@ -89,6 +93,15 @@
}
/**
+ * Set the flag to traverse the tree when touch events happen
+ *
+ * @param value true to indicate that the tree has touch listeners
+ */
+ public void setHasTouchListeners(boolean value) {
+ mHasTouchListeners = value;
+ }
+
+ /**
* Traverse the hierarchy and assign generated ids to component without ids. Most components
* would already have ids assigned during the document creation, but this allow us to take care
* of any components added during the inflation.
@@ -100,7 +113,7 @@
assignId(this);
}
- private void assignId(Component component) {
+ private void assignId(@NonNull Component component) {
if (component.mComponentId == -1) {
mCurrentId--;
component.mComponentId = mCurrentId;
@@ -113,7 +126,7 @@
}
/** This will measure then layout the tree of components */
- public void layout(RemoteContext context) {
+ public void layout(@NonNull RemoteContext context) {
if (!mNeedsMeasure) {
return;
}
@@ -134,7 +147,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
mNeedsRepaint = false;
context.getContext().lastComponent = this;
context.save();
@@ -152,13 +165,15 @@
context.restore();
}
+ @NonNull
public String displayHierarchy() {
StringSerializer serializer = new StringSerializer();
displayHierarchy(this, 0, serializer);
return serializer.toString();
}
- public void displayHierarchy(Component component, int indent, StringSerializer serializer) {
+ public void displayHierarchy(
+ @NonNull Component component, int indent, @NonNull StringSerializer serializer) {
component.serializeToString(indent, serializer);
for (Operation c : component.mList) {
if (c instanceof ComponentModifiers) {
@@ -171,6 +186,7 @@
}
}
+ @NonNull
public static String name() {
return "RootLayout";
}
@@ -179,17 +195,17 @@
return Operations.LAYOUT_ROOT;
}
- public static void apply(WireBuffer buffer, int componentId) {
+ public static void apply(@NonNull WireBuffer buffer, int componentId) {
buffer.start(Operations.LAYOUT_ROOT);
buffer.writeInt(componentId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int componentId = buffer.readInt();
operations.add(new RootLayoutComponent(componentId, 0, 0, 0, 0, null, -1));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.field(INT, "COMPONENT_ID", "unique id for this component")
.description(
@@ -199,7 +215,11 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mComponentId);
}
+
+ public boolean hasTouchListeners() {
+ return mHasTouchListeners;
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java
new file mode 100644
index 0000000..486efbd
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+
+import java.util.List;
+
+/** Represents a touch cancel modifier + actions */
+public class TouchCancelModifierOperation extends ListActionsOperation implements TouchHandler {
+
+ private static final int OP_CODE = Operations.MODIFIER_TOUCH_CANCEL;
+
+ public TouchCancelModifierOperation() {
+ super("TOUCH_CANCEL_MODIFIER");
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ apply(buffer);
+ }
+
+ @Override
+ public String toString() {
+ return "TouchCancelModifier";
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ RootLayoutComponent root = context.getDocument().getRootLayoutComponent();
+ if (root != null) {
+ root.setHasTouchListeners(true);
+ }
+ super.apply(context);
+ }
+
+ @Override
+ public void onTouchDown(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // nothing
+ }
+
+ @Override
+ public void onTouchUp(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // nothing
+ }
+
+ @Override
+ public void onTouchCancel(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ applyActions(context, document, component, x, y, true);
+ }
+
+ public static String name() {
+ return "TouchCancelModifier";
+ }
+
+ public static void apply(WireBuffer buffer) {
+ buffer.start(OP_CODE);
+ }
+
+ public static void read(WireBuffer buffer, List<Operation> operations) {
+ operations.add(new TouchCancelModifierOperation());
+ }
+
+ public static void documentation(DocumentationBuilder doc) {
+ doc.operation("Modifier Operations", OP_CODE, name())
+ .description(
+ "Touch cancel modifier. This operation contains"
+ + " a list of action executed on Touch cancel");
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchDownModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchDownModifierOperation.java
new file mode 100644
index 0000000..5d379fe
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchDownModifierOperation.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+
+import java.util.List;
+
+/** Represents a touch down modifier + actions */
+public class TouchDownModifierOperation extends ListActionsOperation implements TouchHandler {
+
+ private static final int OP_CODE = Operations.MODIFIER_TOUCH_DOWN;
+
+ public TouchDownModifierOperation() {
+ super("TOUCH_DOWN_MODIFIER");
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ apply(buffer);
+ }
+
+ @Override
+ public String toString() {
+ return "TouchDownModifier";
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ RootLayoutComponent root = context.getDocument().getRootLayoutComponent();
+ if (root != null) {
+ root.setHasTouchListeners(true);
+ }
+ super.apply(context);
+ }
+
+ @Override
+ public void onTouchDown(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ if (applyActions(context, document, component, x, y, false)) {
+ document.appliedTouchOperation(component);
+ }
+ }
+
+ @Override
+ public void onTouchUp(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // nothing
+ }
+
+ @Override
+ public void onTouchCancel(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // nothing
+ }
+
+ public static String name() {
+ return "TouchModifier";
+ }
+
+ public static void apply(WireBuffer buffer) {
+ buffer.start(OP_CODE);
+ }
+
+ public static void read(WireBuffer buffer, List<Operation> operations) {
+ operations.add(new TouchDownModifierOperation());
+ }
+
+ public static void documentation(DocumentationBuilder doc) {
+ doc.operation("Modifier Operations", OP_CODE, name())
+ .description(
+ "Touch down modifier. This operation contains"
+ + " a list of action executed on Touch down");
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchHandler.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchHandler.java
new file mode 100644
index 0000000..5adfc33
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchHandler.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+
+/** Interface to represent operations that can handle touch events */
+public interface TouchHandler {
+
+ /**
+ * callback for a touch down event
+ *
+ * @param context the current context
+ * @param document the current document
+ * @param component the component on which the touch has been received
+ * @param x the x position of the click in document coordinates
+ * @param y the y position of the click in document coordinates
+ */
+ void onTouchDown(
+ RemoteContext context, CoreDocument document, Component component, float x, float y);
+
+ /**
+ * callback for a touch up event
+ *
+ * @param context the current context
+ * @param document the current document
+ * @param component the component on which the touch has been received
+ * @param x the x position of the click in document coordinates
+ * @param y the y position of the click in document coordinates
+ */
+ void onTouchUp(
+ RemoteContext context, CoreDocument document, Component component, float x, float y);
+
+ /**
+ * callback for a touch cancel event
+ *
+ * @param context the current context
+ * @param document the current document
+ * @param component the component on which the touch has been received
+ * @param x the x position of the click in document coordinates
+ * @param y the y position of the click in document coordinates
+ */
+ void onTouchCancel(
+ RemoteContext context, CoreDocument document, Component component, float x, float y);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchUpModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchUpModifierOperation.java
new file mode 100644
index 0000000..263cc43
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchUpModifierOperation.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+
+import java.util.List;
+
+/** Represents a touch up modifier + actions */
+public class TouchUpModifierOperation extends ListActionsOperation implements TouchHandler {
+
+ private static final int OP_CODE = Operations.MODIFIER_TOUCH_UP;
+
+ public TouchUpModifierOperation() {
+ super("TOUCH_UP_MODIFIER");
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ apply(buffer);
+ }
+
+ @Override
+ public String toString() {
+ return "TouchUpModifier";
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ RootLayoutComponent root = context.getDocument().getRootLayoutComponent();
+ if (root != null) {
+ root.setHasTouchListeners(true);
+ }
+ super.apply(context);
+ }
+
+ @Override
+ public void onTouchDown(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // nothing
+ }
+
+ @Override
+ public void onTouchUp(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ applyActions(context, document, component, x, y, true);
+ }
+
+ @Override
+ public void onTouchCancel(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // nothing
+ }
+
+ public static String name() {
+ return "TouchUpModifier";
+ }
+
+ public static void apply(WireBuffer buffer) {
+ buffer.start(OP_CODE);
+ }
+
+ public static void read(WireBuffer buffer, List<Operation> operations) {
+ operations.add(new TouchUpModifierOperation());
+ }
+
+ public static void documentation(DocumentationBuilder doc) {
+ doc.operation("Modifier Operations", OP_CODE, name())
+ .description(
+ "Touch up modifier. This operation contains"
+ + " a list of action executed on Touch up");
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
index e450585..6036b74 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.animation;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
@@ -44,18 +46,23 @@
float mP = 0f;
float mVp = 0f;
+
+ @NonNull
FloatAnimation mMotionEasing =
new FloatAnimation(mMotionEasingType, mDuration / 1000f, null, 0f, Float.NaN);
+
+ @NonNull
FloatAnimation mVisibilityEasing =
new FloatAnimation(
mVisibilityEasingType, mDurationVisibilityChange / 1000f, null, 0f, Float.NaN);
+
ParticleAnimation mParticleAnimation;
public AnimateMeasure(
long startTime,
- Component component,
+ @NonNull Component component,
ComponentMeasure original,
- ComponentMeasure target,
+ @NonNull ComponentMeasure target,
int duration,
int durationVisibilityChange,
AnimationSpec.ANIMATION enterAnimation,
@@ -94,9 +101,9 @@
mVp = mVisibilityEasing.get(visibilityProgress);
}
- public PaintBundle paint = new PaintBundle();
+ @NonNull public PaintBundle paint = new PaintBundle();
- public void apply(PaintContext context) {
+ public void apply(@NonNull PaintContext context) {
update(context.getContext().currentTime);
mComponent.setX(getX());
@@ -338,7 +345,7 @@
}
}
- public void updateTarget(ComponentMeasure measure, long currentTime) {
+ public void updateTarget(@NonNull ComponentMeasure measure, long currentTime) {
mOriginal.setX(getX());
mOriginal.setY(getY());
mOriginal.setW(getWidth());
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
index 35533cb..47abade 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -92,6 +95,7 @@
return mExitAnimation;
}
+ @NonNull
@Override
public String toString() {
return "ANIMATION_SPEC (" + mMotionDuration + " ms)";
@@ -109,7 +113,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(
buffer,
mAnimationId,
@@ -126,11 +130,13 @@
// nothing here
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
+ @NonNull
public static String name() {
return "AnimationSpec";
}
@@ -139,10 +145,11 @@
return Operations.ANIMATION_SPEC;
}
- public static int animationToInt(ANIMATION animation) {
+ public static int animationToInt(@NonNull ANIMATION animation) {
return animation.ordinal();
}
+ @NonNull
public static ANIMATION intToAnimation(int value) {
switch (value) {
case 0:
@@ -167,14 +174,14 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int animationId,
int motionDuration,
int motionEasingType,
int visibilityDuration,
int visibilityEasingType,
- ANIMATION enterAnimation,
- ANIMATION exitAnimation) {
+ @NonNull ANIMATION enterAnimation,
+ @NonNull ANIMATION exitAnimation) {
buffer.start(Operations.ANIMATION_SPEC);
buffer.writeInt(animationId);
buffer.writeInt(motionDuration);
@@ -185,7 +192,7 @@
buffer.writeInt(animationToInt(exitAnimation));
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int animationId = buffer.readInt();
int motionDuration = buffer.readInt();
int motionEasingType = buffer.readInt();
@@ -205,7 +212,7 @@
operations.add(op);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.description("define the animation")
.field(INT, "animationId", "")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java
index 686643f..37d2078 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.animation;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
@@ -24,14 +26,14 @@
import java.util.HashMap;
public class ParticleAnimation {
- HashMap<Integer, ArrayList<Particle>> mAllParticles = new HashMap<>();
+ @NonNull HashMap<Integer, ArrayList<Particle>> mAllParticles = new HashMap<>();
- PaintBundle mPaint = new PaintBundle();
+ @NonNull PaintBundle mPaint = new PaintBundle();
public void animate(
- PaintContext context,
- Component component,
- ComponentMeasure start,
+ @NonNull PaintContext context,
+ @NonNull Component component,
+ @NonNull ComponentMeasure start,
ComponentMeasure end,
float progress) {
ArrayList<Particle> particles = mAllParticles.get(component.getComponentId());
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
index 047a968..f3e5509 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -75,6 +77,7 @@
verticalPositioning);
}
+ @NonNull
@Override
public String toString() {
return "BOX ["
@@ -93,6 +96,7 @@
+ mVisibility;
}
+ @NonNull
@Override
protected String getSerializedName() {
return "BOX";
@@ -100,7 +104,11 @@
@Override
public void computeWrapSize(
- PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) {
+ PaintContext context,
+ float maxWidth,
+ float maxHeight,
+ @NonNull MeasurePass measure,
+ @NonNull Size size) {
for (Component c : mChildrenComponents) {
c.measure(context, 0f, maxWidth, 0f, maxHeight, measure);
ComponentMeasure m = measure.get(c);
@@ -119,14 +127,14 @@
float maxWidth,
float minHeight,
float maxHeight,
- MeasurePass measure) {
+ @NonNull MeasurePass measure) {
for (Component child : mChildrenComponents) {
child.measure(context, minWidth, maxWidth, minHeight, maxHeight, measure);
}
}
@Override
- public void internalLayoutMeasure(PaintContext context, MeasurePass measure) {
+ public void internalLayoutMeasure(PaintContext context, @NonNull MeasurePass measure) {
ComponentMeasure selfMeasure = measure.get(this);
float selfWidth = selfMeasure.getW() - mPaddingLeft - mPaddingRight;
float selfHeight = selfMeasure.getH() - mPaddingTop - mPaddingBottom;
@@ -161,6 +169,7 @@
}
}
+ @NonNull
public static String name() {
return "BoxLayout";
}
@@ -170,7 +179,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int componentId,
int animationId,
int horizontalPositioning,
@@ -182,7 +191,7 @@
buffer.writeInt(verticalPositioning);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int componentId = buffer.readInt();
int animationId = buffer.readInt();
int horizontalPositioning = buffer.readInt();
@@ -196,7 +205,7 @@
verticalPositioning));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.description(
"Box layout implementation.\n\n"
@@ -224,7 +233,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mComponentId, mAnimationId, mHorizontalPositioning, mVerticalPositioning);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java
index f799767..12ff969 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -44,6 +46,7 @@
this(parent, componentId, animationId, 0, 0, 0, 0);
}
+ @NonNull
@Override
public String toString() {
return "CANVAS ["
@@ -62,11 +65,13 @@
+ mVisibility;
}
+ @NonNull
@Override
protected String getSerializedName() {
return "CANVAS";
}
+ @NonNull
public static String name() {
return "CanvasLayout";
}
@@ -75,19 +80,19 @@
return Operations.LAYOUT_CANVAS;
}
- public static void apply(WireBuffer buffer, int componentId, int animationId) {
+ public static void apply(@NonNull WireBuffer buffer, int componentId, int animationId) {
buffer.start(Operations.LAYOUT_CANVAS);
buffer.writeInt(componentId);
buffer.writeInt(animationId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int componentId = buffer.readInt();
int animationId = buffer.readInt();
operations.add(new CanvasLayout(null, componentId, animationId));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.description("Canvas implementation. Encapsulate draw operations.\n\n")
.field(INT, "COMPONENT_ID", "unique id for this component")
@@ -98,7 +103,7 @@
}
@Override
- public void internalLayoutMeasure(PaintContext context, MeasurePass measure) {
+ public void internalLayoutMeasure(PaintContext context, @NonNull MeasurePass measure) {
ComponentMeasure selfMeasure = measure.get(this);
float selfWidth = selfMeasure.getW() - mPaddingLeft - mPaddingRight;
float selfHeight = selfMeasure.getH() - mPaddingTop - mPaddingBottom;
@@ -112,7 +117,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mComponentId, mAnimationId);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
index 402b784..52bf4c5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -87,6 +89,7 @@
spacedBy);
}
+ @NonNull
@Override
public String toString() {
return "COLUMN ["
@@ -105,14 +108,24 @@
+ mVisibility;
}
+ @NonNull
@Override
protected String getSerializedName() {
return "COLUMN";
}
@Override
+ public boolean isInVerticalFill() {
+ return super.isInVerticalFill() || childrenHaveVerticalWeights();
+ }
+
+ @Override
public void computeWrapSize(
- PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) {
+ PaintContext context,
+ float maxWidth,
+ float maxHeight,
+ @NonNull MeasurePass measure,
+ @NonNull Size size) {
DebugLog.s(() -> "COMPUTE WRAP SIZE in " + this + " (" + mComponentId + ")");
int visibleChildrens = 0;
for (Component c : mChildrenComponents) {
@@ -137,7 +150,7 @@
float maxWidth,
float minHeight,
float maxHeight,
- MeasurePass measure) {
+ @NonNull MeasurePass measure) {
DebugLog.s(() -> "COMPUTE SIZE in " + this + " (" + mComponentId + ")");
float mh = maxHeight;
for (Component child : mChildrenComponents) {
@@ -151,7 +164,7 @@
}
@Override
- public void internalLayoutMeasure(PaintContext context, MeasurePass measure) {
+ public void internalLayoutMeasure(PaintContext context, @NonNull MeasurePass measure) {
ComponentMeasure selfMeasure = measure.get(this);
DebugLog.s(
() ->
@@ -302,6 +315,7 @@
DebugLog.e();
}
+ @NonNull
public static String name() {
return "ColumnLayout";
}
@@ -311,7 +325,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int componentId,
int animationId,
int horizontalPositioning,
@@ -325,7 +339,7 @@
buffer.writeFloat(spacedBy);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int componentId = buffer.readInt();
int animationId = buffer.readInt();
int horizontalPositioning = buffer.readInt();
@@ -341,7 +355,7 @@
spacedBy));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.description(
"Column layout implementation, positioning components one"
@@ -374,7 +388,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(
buffer,
mComponentId,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
index 308ed64..0c4d24a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.managers;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
@@ -27,7 +29,7 @@
/** Base class for layout managers -- resizable components. */
public abstract class LayoutManager extends LayoutComponent implements Measurable {
- Size mCachedWrapSize = new Size(0f, 0f);
+ @NonNull Size mCachedWrapSize = new Size(0f, 0f);
public LayoutManager(
Component parent,
@@ -62,6 +64,38 @@
// nothing here
}
+ protected boolean childrenHaveHorizontalWeights() {
+ for (Component c : mChildrenComponents) {
+ if (c instanceof LayoutManager) {
+ LayoutManager m = (LayoutManager) c;
+ if (m.getWidthModifier() != null && m.getWidthModifier().hasWeight()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ protected boolean childrenHaveVerticalWeights() {
+ for (Component c : mChildrenComponents) {
+ if (c instanceof LayoutManager) {
+ LayoutManager m = (LayoutManager) c;
+ if (m.getHeightModifier() != null && m.getHeightModifier().hasWeight()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean isInHorizontalFill() {
+ return mWidthModifier.isFill();
+ }
+
+ public boolean isInVerticalFill() {
+ return mHeightModifier.isFill();
+ }
+
/** Base implementation of the measure resolution */
@Override
public void measure(
@@ -70,7 +104,7 @@
float maxWidth,
float minHeight,
float maxHeight,
- MeasurePass measure) {
+ @NonNull MeasurePass measure) {
boolean hasWrap = true;
float measuredWidth =
Math.min(maxWidth, computeModifierDefinedWidth() - mMarginLeft - mMarginRight);
@@ -87,7 +121,7 @@
} else {
hasWrap = false;
}
- if (mWidthModifier.isFill()) {
+ if (isInHorizontalFill()) {
measuredWidth = insetMaxWidth;
} else if (mWidthModifier.hasWeight()) {
measuredWidth = Math.max(measuredWidth, computeModifierDefinedWidth());
@@ -95,7 +129,7 @@
measuredWidth = Math.max(measuredWidth, minWidth);
measuredWidth = Math.min(measuredWidth, insetMaxWidth);
}
- if (mHeightModifier.isFill()) {
+ if (isInVerticalFill()) {
measuredHeight = insetMaxHeight;
} else if (mHeightModifier.hasWeight()) {
measuredHeight = Math.max(measuredHeight, computeModifierDefinedHeight());
@@ -136,7 +170,7 @@
/** basic layout of internal components */
@Override
- public void layout(RemoteContext context, MeasurePass measure) {
+ public void layout(@NonNull RemoteContext context, @NonNull MeasurePass measure) {
super.layout(context, measure);
ComponentMeasure self = measure.get(this);
@@ -153,7 +187,7 @@
* @param context
* @param measure
*/
- public void selfLayout(RemoteContext context, MeasurePass measure) {
+ public void selfLayout(@NonNull RemoteContext context, @NonNull MeasurePass measure) {
super.layout(context, measure);
ComponentMeasure self = measure.get(this);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
index b29a05c..a366dc8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -85,6 +87,7 @@
spacedBy);
}
+ @NonNull
@Override
public String toString() {
return "ROW ["
@@ -103,14 +106,24 @@
+ mVisibility;
}
+ @NonNull
@Override
protected String getSerializedName() {
return "ROW";
}
@Override
+ public boolean isInHorizontalFill() {
+ return super.isInHorizontalFill() || childrenHaveHorizontalWeights();
+ }
+
+ @Override
public void computeWrapSize(
- PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) {
+ PaintContext context,
+ float maxWidth,
+ float maxHeight,
+ @NonNull MeasurePass measure,
+ @NonNull Size size) {
DebugLog.s(() -> "COMPUTE WRAP SIZE in " + this + " (" + mComponentId + ")");
// int visibleChildrens = 0;
for (Component c : mChildrenComponents) {
@@ -135,7 +148,7 @@
float maxWidth,
float minHeight,
float maxHeight,
- MeasurePass measure) {
+ @NonNull MeasurePass measure) {
DebugLog.s(() -> "COMPUTE SIZE in " + this + " (" + mComponentId + ")");
float mw = maxWidth;
for (Component child : mChildrenComponents) {
@@ -149,7 +162,7 @@
}
@Override
- public void internalLayoutMeasure(PaintContext context, MeasurePass measure) {
+ public void internalLayoutMeasure(PaintContext context, @NonNull MeasurePass measure) {
ComponentMeasure selfMeasure = measure.get(this);
DebugLog.s(
() ->
@@ -305,6 +318,7 @@
DebugLog.e();
}
+ @NonNull
public static String name() {
return "RowLayout";
}
@@ -314,7 +328,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int componentId,
int animationId,
int horizontalPositioning,
@@ -328,7 +342,7 @@
buffer.writeFloat(spacedBy);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int componentId = buffer.readInt();
int animationId = buffer.readInt();
int horizontalPositioning = buffer.readInt();
@@ -344,7 +358,7 @@
spacedBy));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.description(
"Row layout implementation, positioning components one"
@@ -377,7 +391,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(
buffer,
mComponentId,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java
index b5c7281..e47ffde 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.managers;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -50,10 +52,10 @@
// This keep track of all the components associated with a given Id,
// (the key being the id), and the set of components corresponds to the set of states
// TODO: we should be able to optimize this
- public Map<Integer, Component[]> statePaintedComponents = new HashMap<>();
+ @NonNull public Map<Integer, Component[]> statePaintedComponents = new HashMap<>();
public int MAX_CACHE_ELEMENTS = 16;
- public int[] cacheListElementsId = new int[MAX_CACHE_ELEMENTS];
+ @NonNull public int[] cacheListElementsId = new int[MAX_CACHE_ELEMENTS];
public boolean inTransition = false;
@@ -168,7 +170,7 @@
}
@Override
- public void layout(RemoteContext context, MeasurePass measure) {
+ public void layout(@NonNull RemoteContext context, @NonNull MeasurePass measure) {
ComponentMeasure self = measure.get(this);
super.selfLayout(context, measure);
@@ -207,12 +209,12 @@
@Override
public void measure(
- PaintContext context,
+ @NonNull PaintContext context,
float minWidth,
float maxWidth,
float minHeight,
float maxHeight,
- MeasurePass measure) {
+ @NonNull MeasurePass measure) {
// The general approach for this widget is to do most of the work/setup in measure.
// layout and paint then simply use what's been setup in the measure phase.
@@ -364,19 +366,20 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
if (mIndexId != 0) {
int newValue = context.getContext().mRemoteComposeState.getInteger(mIndexId);
if (newValue != currentLayoutIndex) {
previousLayoutIndex = currentLayoutIndex;
currentLayoutIndex = newValue;
inTransition = true;
- System.out.println("currentLayout index is $currentLayoutIndex");
+ // System.out.println("currentLayout index is $currentLayoutIndex");
// executeValueSetActions(getLayout(currentLayoutIndex));
invalidateMeasure();
}
}
- System.out.println("PAINTING LAYOUT STATELAYOUT, CURRENT INDEX " + currentLayoutIndex);
+ // System.out.println("PAINTING LAYOUT STATELAYOUT, CURRENT INDEX " +
+ // currentLayoutIndex);
// Make sure to mark any components that are not in either the current or previous layout
// as being GONE.
int index = 0;
@@ -529,6 +532,7 @@
// }
// }
+ @NonNull
@Override
public String toString() {
return "STATE_LAYOUT";
@@ -539,7 +543,7 @@
// }
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int componentId,
int animationId,
int horizontalPositioning,
@@ -553,7 +557,7 @@
buffer.writeInt(indexId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int componentId = buffer.readInt();
int animationId = buffer.readInt();
buffer.readInt(); // horizontalPositioning
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
index c1cabcd..8aa7712 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -44,22 +46,24 @@
private int mFontStyle = 0;
private float mFontWeight = 400f;
private int mFontFamilyId = -1;
+ private int mTextAlign = -1;
private int mType = -1;
private float mTextX;
private float mTextY;
+ private float mTextW;
private String mCachedString = "";
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (mTextId != -1) {
context.listensTo(mTextId, this);
}
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
mCachedString = context.getText(mTextId);
if (mType == -1) {
if (mFontFamilyId != -1) {
@@ -97,7 +101,8 @@
float fontSize,
int fontStyle,
float fontWeight,
- int fontFamilyId) {
+ int fontFamilyId,
+ int textAlign) {
super(parent, componentId, animationId, x, y, width, height);
mTextId = textId;
mColor = color;
@@ -105,6 +110,7 @@
mFontStyle = fontStyle;
mFontWeight = fontWeight;
mFontFamilyId = fontFamilyId;
+ mTextAlign = textAlign;
}
public TextLayout(
@@ -116,7 +122,8 @@
float fontSize,
int fontStyle,
float fontWeight,
- int fontFamilyId) {
+ int fontFamilyId,
+ int textAlign) {
this(
parent,
componentId,
@@ -130,13 +137,14 @@
fontSize,
fontStyle,
fontWeight,
- fontFamilyId);
+ fontFamilyId,
+ textAlign);
}
- public PaintBundle mPaint = new PaintBundle();
+ @NonNull public PaintBundle mPaint = new PaintBundle();
@Override
- public void paintingComponent(PaintContext context) {
+ public void paintingComponent(@NonNull PaintContext context) {
context.save();
context.translate(mX, mY);
mComponentModifiers.paint(context);
@@ -176,6 +184,7 @@
context.restore();
}
+ @NonNull
@Override
public String toString() {
return "TEXT_LAYOUT ["
@@ -194,13 +203,14 @@
+ mVisibility;
}
+ @NonNull
@Override
protected String getSerializedName() {
return "TEXT_LAYOUT";
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(
indent,
getSerializedName()
@@ -228,7 +238,11 @@
@Override
public void computeWrapSize(
- PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) {
+ @NonNull PaintContext context,
+ float maxWidth,
+ float maxHeight,
+ MeasurePass measure,
+ @NonNull Size size) {
context.savePaint();
mPaint.reset();
mPaint.setTextSize(mFontSize);
@@ -244,8 +258,10 @@
mTextX = -bounds[0];
size.setHeight(h);
mTextY = -bounds[1];
+ mTextW = w;
}
+ @NonNull
public static String name() {
return "TextLayout";
}
@@ -255,7 +271,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
int componentId,
int animationId,
int textId,
@@ -263,7 +279,8 @@
float fontSize,
int fontStyle,
float fontWeight,
- int fontFamilyId) {
+ int fontFamilyId,
+ int textAlign) {
buffer.start(id());
buffer.writeInt(componentId);
buffer.writeInt(animationId);
@@ -273,9 +290,10 @@
buffer.writeInt(fontStyle);
buffer.writeFloat(fontWeight);
buffer.writeInt(fontFamilyId);
+ buffer.writeInt(textAlign);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int componentId = buffer.readInt();
int animationId = buffer.readInt();
int textId = buffer.readInt();
@@ -284,6 +302,7 @@
int fontStyle = buffer.readInt();
float fontWeight = buffer.readFloat();
int fontFamilyId = buffer.readInt();
+ int textAlign = buffer.readInt();
operations.add(
new TextLayout(
null,
@@ -294,10 +313,11 @@
fontSize,
fontStyle,
fontWeight,
- fontFamilyId));
+ fontFamilyId,
+ textAlign));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", id(), name())
.description("Text layout implementation.\n\n")
.field(INT, "COMPONENT_ID", "unique id for this component")
@@ -313,7 +333,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(
buffer,
mComponentId,
@@ -323,6 +343,7 @@
mFontSize,
mFontStyle,
mFontWeight,
- mFontFamilyId);
+ mFontFamilyId,
+ mTextAlign);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java
index 285425f..426e023 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.measure;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
/** Encapsulate the result of a measure pass for a component */
@@ -80,7 +82,7 @@
this(id, x, y, w, h, Component.Visibility.VISIBLE);
}
- public ComponentMeasure(Component component) {
+ public ComponentMeasure(@NonNull Component component) {
this(
component.getComponentId(),
component.getX(),
@@ -90,7 +92,7 @@
component.mVisibility);
}
- public void copyFrom(ComponentMeasure m) {
+ public void copyFrom(@NonNull ComponentMeasure m) {
mX = m.mX;
mY = m.mY;
mW = m.mW;
@@ -98,7 +100,7 @@
mVisibility = m.mVisibility;
}
- public boolean same(ComponentMeasure m) {
+ public boolean same(@NonNull ComponentMeasure m) {
return mX == m.mX && mY == m.mY && mW == m.mW && mH == m.mH && mVisibility == m.mVisibility;
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java
index 8d01fea..112ab1b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.measure;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import java.util.HashMap;
@@ -24,13 +26,13 @@
* array vs the current hashmap
*/
public class MeasurePass {
- HashMap<Integer, ComponentMeasure> mList = new HashMap<>();
+ @NonNull HashMap<Integer, ComponentMeasure> mList = new HashMap<>();
public void clear() {
mList.clear();
}
- public void add(ComponentMeasure measure) throws Exception {
+ public void add(@NonNull ComponentMeasure measure) throws Exception {
if (measure.mId == -1) {
throw new Exception("Component has no id!");
}
@@ -41,7 +43,7 @@
return mList.containsKey(id);
}
- public ComponentMeasure get(Component c) {
+ public ComponentMeasure get(@NonNull Component c) {
if (!mList.containsKey(c.getComponentId())) {
ComponentMeasure measure =
new ComponentMeasure(
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
index 64e40f7..76a97ca 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -42,7 +44,7 @@
float mA;
int mShapeType = ShapeType.RECTANGLE;
- public PaintBundle mPaint = new PaintBundle();
+ @NonNull public PaintBundle mPaint = new PaintBundle();
public BackgroundModifierOperation(
float x,
@@ -66,12 +68,12 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mX, mY, mWidth, mHeight, mR, mG, mB, mA, mShapeType);
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(
indent,
"BACKGROUND = ["
@@ -101,11 +103,13 @@
this.mHeight = height;
}
+ @NonNull
@Override
public String toString() {
return "BackgroundModifierOperation(" + mWidth + " x " + mHeight + ")";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -115,7 +119,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
float x,
float y,
float width,
@@ -138,7 +142,7 @@
buffer.writeInt(shapeType);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
float x = buffer.readFloat();
float y = buffer.readFloat();
float width = buffer.readFloat();
@@ -153,7 +157,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.savePaint();
mPaint.reset();
mPaint.setStyle(PaintBundle.STYLE_FILL);
@@ -167,7 +171,7 @@
context.restorePaint();
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Modifier Operations", OP_CODE, CLASS_NAME)
.description("define the Background Modifier")
.field(FLOAT, "x", "")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
index 92c0a73..d48a9c7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -45,7 +47,7 @@
float mA;
int mShapeType = ShapeType.RECTANGLE;
- public PaintBundle paint = new PaintBundle();
+ @NonNull public PaintBundle paint = new PaintBundle();
public BorderModifierOperation(
float x,
@@ -73,7 +75,7 @@
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(
indent,
"BORDER = ["
@@ -105,7 +107,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(
buffer,
mX,
@@ -127,6 +129,7 @@
this.mHeight = height;
}
+ @NonNull
@Override
public String toString() {
return "BorderModifierOperation("
@@ -152,6 +155,7 @@
+ ")";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -161,7 +165,7 @@
}
public static void apply(
- WireBuffer buffer,
+ @NonNull WireBuffer buffer,
float x,
float y,
float width,
@@ -188,7 +192,7 @@
buffer.writeInt(shapeType);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
float x = buffer.readFloat();
float y = buffer.readFloat();
float width = buffer.readFloat();
@@ -206,7 +210,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.savePaint();
paint.reset();
paint.setColor(mR, mG, mB, mA);
@@ -225,7 +229,7 @@
context.restorePaint();
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Modifier Operations", OP_CODE, CLASS_NAME)
.description("define the Border Modifier")
.field(FLOAT, "x", "")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
index 0d8aeaa..78b51c3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
@@ -15,14 +15,14 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
-import com.android.internal.widget.remotecompose.core.CoreDocument;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.WireBuffer;
import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
-import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
import java.util.List;
@@ -35,7 +35,7 @@
float mHeight;
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.clipRect(0f, 0f, mWidth, mHeight);
}
@@ -46,21 +46,16 @@
}
@Override
- public void onClick(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
- // nothing
- }
-
- @Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(indent, "CLIP_RECT = [" + mWidth + ", " + mHeight + "]");
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer);
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -69,15 +64,15 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer) {
+ public static void apply(@NonNull WireBuffer buffer) {
buffer.start(OP_CODE);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
operations.add(new ClipRectModifierOperation());
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Canvas Operations", OP_CODE, CLASS_NAME)
.description("Draw the specified round-rect");
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
index 95786a8..011d7ed 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.PaintOperation;
@@ -22,29 +24,34 @@
import com.android.internal.widget.remotecompose.core.WireBuffer;
import com.android.internal.widget.remotecompose.core.operations.MatrixRestore;
import com.android.internal.widget.remotecompose.core.operations.MatrixSave;
+import com.android.internal.widget.remotecompose.core.operations.layout.ClickHandler;
import com.android.internal.widget.remotecompose.core.operations.layout.ClickModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.TouchHandler;
import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
import java.util.ArrayList;
/** Maintain a list of modifiers */
-public class ComponentModifiers extends PaintOperation implements DecoratorComponent {
- ArrayList<ModifierOperation> mList = new ArrayList<>();
+public class ComponentModifiers extends PaintOperation
+ implements DecoratorComponent, ClickHandler, TouchHandler {
+ @NonNull ArrayList<ModifierOperation> mList = new ArrayList<>();
+ @NonNull
public ArrayList<ModifierOperation> getList() {
return mList;
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
super.apply(context);
for (ModifierOperation op : mList) {
op.apply(context);
}
}
+ @NonNull
@Override
public String toString() {
String str = "ComponentModifiers \n";
@@ -59,7 +66,7 @@
// nothing
}
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(indent, "MODIFIERS");
for (ModifierOperation m : mList) {
m.serializeToString(indent + 1, serializer);
@@ -75,7 +82,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
float tx = 0f;
float ty = 0f;
for (ModifierOperation op : mList) {
@@ -127,8 +134,38 @@
public void onClick(
RemoteContext context, CoreDocument document, Component component, float x, float y) {
for (ModifierOperation op : mList) {
- if (op instanceof DecoratorComponent) {
- ((DecoratorComponent) op).onClick(context, document, component, x, y);
+ if (op instanceof ClickHandler) {
+ ((ClickHandler) op).onClick(context, document, component, x, y);
+ }
+ }
+ }
+
+ @Override
+ public void onTouchDown(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ for (ModifierOperation op : mList) {
+ if (op instanceof TouchHandler) {
+ ((TouchHandler) op).onTouchDown(context, document, component, x, y);
+ }
+ }
+ }
+
+ @Override
+ public void onTouchUp(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ for (ModifierOperation op : mList) {
+ if (op instanceof TouchHandler) {
+ ((TouchHandler) op).onTouchUp(context, document, component, x, y);
+ }
+ }
+ }
+
+ @Override
+ public void onTouchCancel(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ for (ModifierOperation op : mList) {
+ if (op instanceof TouchHandler) {
+ ((TouchHandler) op).onTouchCancel(context, document, component, x, y);
}
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java
index 312d016..26e737b3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java
@@ -17,7 +17,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
-import com.android.internal.widget.remotecompose.core.CoreDocument;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -37,49 +39,52 @@
private static final int OP_CODE = Operations.MODIFIER_VISIBILITY;
int mVisibilityId;
- Component.Visibility mVisibility = Component.Visibility.VISIBLE;
+ @NonNull Component.Visibility mVisibility = Component.Visibility.VISIBLE;
private LayoutComponent mParent;
public ComponentVisibilityOperation(int id) {
mVisibilityId = id;
}
+ @NonNull
@Override
public String toString() {
return "ComponentVisibilityOperation(" + mVisibilityId + ")";
}
+ @NonNull
public String serializedName() {
return "COMPONENT_VISIBILITY";
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(indent, serializedName() + " = " + mVisibilityId);
}
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
public void write(WireBuffer buffer) {}
- public static void apply(WireBuffer buffer, int valueId) {
+ public static void apply(@NonNull WireBuffer buffer, int valueId) {
buffer.start(OP_CODE);
buffer.writeInt(valueId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int valueId = buffer.readInt();
operations.add(new ComponentVisibilityOperation(valueId));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", OP_CODE, "ComponentVisibility")
.description(
"This operation allows setting a component"
@@ -88,12 +93,12 @@
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
context.listensTo(mVisibilityId, this);
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
int visibility = context.getInteger(mVisibilityId);
if (visibility == Component.Visibility.VISIBLE.ordinal()) {
mVisibility = Component.Visibility.VISIBLE;
@@ -115,8 +120,4 @@
@Override
public void layout(RemoteContext context, float width, float height) {}
-
- @Override
- public void onClick(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java
index 41e18cb..b4c4108 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DecoratorModifierOperation.java
@@ -15,10 +15,7 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
-import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.PaintOperation;
-import com.android.internal.widget.remotecompose.core.RemoteContext;
-import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent;
/**
@@ -26,11 +23,4 @@
* output (background, border...)
*/
public abstract class DecoratorModifierOperation extends PaintOperation
- implements ModifierOperation, DecoratorComponent {
-
- @Override
- public void onClick(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
- // nothing
- }
-}
+ implements ModifierOperation, DecoratorComponent {}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
index 408bebc..3c2d85c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.VariableSupport;
import com.android.internal.widget.remotecompose.core.operations.Utils;
@@ -29,8 +32,10 @@
WRAP,
WEIGHT,
INTRINSIC_MIN,
- INTRINSIC_MAX;
+ INTRINSIC_MAX,
+ EXACT_DP;
+ @NonNull
static Type fromInt(int value) {
switch (value) {
case 0:
@@ -45,6 +50,8 @@
return INTRINSIC_MIN;
case 5:
return INTRINSIC_MAX;
+ case 6:
+ return EXACT_DP;
}
return EXACT;
}
@@ -68,19 +75,32 @@
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
if (mType == Type.EXACT) {
mOutValue = Float.isNaN(mValue) ? context.getFloat(Utils.idFromNan(mValue)) : mValue;
}
+ if (mType == Type.EXACT_DP) {
+ float pre = mOutValue;
+ mOutValue = Float.isNaN(mValue) ? context.getFloat(Utils.idFromNan(mValue)) : mValue;
+ mOutValue *= context.getDensity();
+ if (pre != mOutValue) {
+ context.getDocument().getRootLayoutComponent().invalidateMeasure();
+ }
+ }
}
@Override
- public void registerListening(RemoteContext context) {
+ public void registerListening(@NonNull RemoteContext context) {
if (mType == Type.EXACT) {
if (Float.isNaN(mValue)) {
context.listensTo(Utils.idFromNan(mValue), this);
}
}
+ if (mType == Type.EXACT_DP) {
+ if (Float.isNaN(mValue)) {
+ context.listensTo(Utils.idFromNan(mValue), this);
+ }
+ }
}
public boolean hasWeight() {
@@ -107,25 +127,31 @@
mOutValue = mValue = value;
}
+ @NonNull
public String serializedName() {
return "DIMENSION";
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
if (mType == Type.EXACT) {
serializer.append(indent, serializedName() + " = " + mValue);
}
+ if (mType == Type.EXACT_DP) {
+ serializer.append(indent, serializedName() + " = " + mValue + " dp");
+ }
}
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
+ @NonNull
@Override
public String toString() {
return "DimensionModifierOperation(" + mValue + ")";
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java
new file mode 100644
index 0000000..2b30382
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.operations.layout.AnimatableValue;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/**
+ * Represents a padding modifier. Padding modifiers can be chained and will impact following
+ * modifiers.
+ */
+public class GraphicsLayerModifierOperation extends DecoratorModifierOperation {
+ private static final int OP_CODE = Operations.MODIFIER_GRAPHICS_LAYER;
+ public static final String CLASS_NAME = "GraphicsLayerModifierOperation";
+
+ AnimatableValue mScaleX;
+ AnimatableValue mScaleY;
+ AnimatableValue mRotationX;
+ AnimatableValue mRotationY;
+ AnimatableValue mRotationZ;
+ AnimatableValue mTransformOriginX;
+ AnimatableValue mTransformOriginY;
+ AnimatableValue mShadowElevation;
+ AnimatableValue mAlpha;
+ AnimatableValue mCameraDistance;
+ int mBlendMode;
+ int mSpotShadowColorId;
+ int mAmbientShadowColorId;
+ int mColorFilterId;
+ int mRenderEffectId;
+
+ public GraphicsLayerModifierOperation(
+ float scaleX,
+ float scaleY,
+ float rotationX,
+ float rotationY,
+ float rotationZ,
+ float shadowElevation,
+ float transformOriginX,
+ float transformOriginY,
+ float alpha,
+ float cameraDistance,
+ int blendMode,
+ int spotShadowColorId,
+ int ambientShadowColorId,
+ int colorFilterId,
+ int renderEffectId) {
+ mScaleX = new AnimatableValue(scaleX);
+ mScaleY = new AnimatableValue(scaleY);
+ mRotationX = new AnimatableValue(rotationX);
+ mRotationY = new AnimatableValue(rotationY);
+ mRotationZ = new AnimatableValue(rotationZ);
+ mShadowElevation = new AnimatableValue(shadowElevation);
+ mTransformOriginX = new AnimatableValue(transformOriginX);
+ mTransformOriginY = new AnimatableValue(transformOriginY);
+ mAlpha = new AnimatableValue(alpha);
+ mCameraDistance = new AnimatableValue(cameraDistance);
+ mBlendMode = blendMode;
+ mSpotShadowColorId = spotShadowColorId;
+ mAmbientShadowColorId = ambientShadowColorId;
+ mColorFilterId = colorFilterId;
+ mRenderEffectId = renderEffectId;
+ }
+
+ public float getScaleX() {
+ return mScaleX.getValue();
+ }
+
+ public float getScaleY() {
+ return mScaleY.getValue();
+ }
+
+ public float getRotationX() {
+ return mRotationX.getValue();
+ }
+
+ public float getRotationY() {
+ return mRotationY.getValue();
+ }
+
+ public float getRotationZ() {
+ return mRotationZ.getValue();
+ }
+
+ public float getShadowElevation() {
+ return mShadowElevation.getValue();
+ }
+
+ public float getTransformOriginX() {
+ return mTransformOriginX.getValue();
+ }
+
+ public float getTransformOriginY() {
+ return mTransformOriginY.getValue();
+ }
+
+ public float getAlpha() {
+ return mAlpha.getValue();
+ }
+
+ public float getCameraDistance() {
+ return mCameraDistance.getValue();
+ }
+
+ // TODO: add implementation for blendmode
+ public int getBlendModeId() {
+ return mBlendMode;
+ }
+
+ // TODO: add implementation for shadow
+ public int getSpotShadowColorId() {
+ return mSpotShadowColorId;
+ }
+
+ public int getAmbientShadowColorId() {
+ return mAmbientShadowColorId;
+ }
+
+ // TODO: add implementation for color filters
+ public int getColorFilterId() {
+ return mColorFilterId;
+ }
+
+ public int getRenderEffectId() {
+ return mRenderEffectId;
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ apply(
+ buffer,
+ mScaleX.getValue(),
+ mScaleY.getValue(),
+ mRotationX.getValue(),
+ mRotationY.getValue(),
+ mRotationZ.getValue(),
+ mShadowElevation.getValue(),
+ mTransformOriginX.getValue(),
+ mTransformOriginY.getValue(),
+ mAlpha.getValue(),
+ mCameraDistance.getValue(),
+ mBlendMode,
+ mSpotShadowColorId,
+ mAmbientShadowColorId,
+ mColorFilterId,
+ mRenderEffectId);
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, "GRAPHICS_LAYER = [" + mScaleX + ", " + mScaleY + "]");
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ mScaleX.evaluate(context);
+ mScaleY.evaluate(context);
+ mRotationX.evaluate(context);
+ mRotationY.evaluate(context);
+ mRotationZ.evaluate(context);
+ mTransformOriginX.evaluate(context);
+ mTransformOriginY.evaluate(context);
+ mShadowElevation.evaluate(context);
+ mAlpha.evaluate(context);
+ mCameraDistance.evaluate(context);
+ }
+
+ @Override
+ public String toString() {
+ return "GraphicsLayerModifierOperation(" + mScaleX + ", " + mScaleY + ")";
+ }
+
+ public static String name() {
+ return CLASS_NAME;
+ }
+
+ public static int id() {
+ return OP_CODE;
+ }
+
+ public static void apply(
+ WireBuffer buffer,
+ float scaleX,
+ float scaleY,
+ float rotationX,
+ float rotationY,
+ float rotationZ,
+ float shadowElevation,
+ float transformOriginX,
+ float transformOriginY,
+ float alpha,
+ float cameraDistance,
+ int blendMode,
+ int spotShadowColorId,
+ int ambientShadowColorId,
+ int colorFilterId,
+ int renderEffectId) {
+ buffer.start(OP_CODE);
+ buffer.writeFloat(scaleX);
+ buffer.writeFloat(scaleY);
+ buffer.writeFloat(rotationX);
+ buffer.writeFloat(rotationY);
+ buffer.writeFloat(rotationZ);
+ buffer.writeFloat(shadowElevation);
+ buffer.writeFloat(transformOriginX);
+ buffer.writeFloat(transformOriginY);
+ buffer.writeFloat(alpha);
+ buffer.writeFloat(cameraDistance);
+ buffer.writeInt(blendMode);
+ buffer.writeInt(spotShadowColorId);
+ buffer.writeInt(ambientShadowColorId);
+ buffer.writeInt(colorFilterId);
+ buffer.writeInt(renderEffectId);
+ }
+
+ public static void read(WireBuffer buffer, List<Operation> operations) {
+ float scaleX = buffer.readFloat();
+ float scaleY = buffer.readFloat();
+ float rotationX = buffer.readFloat();
+ float rotationY = buffer.readFloat();
+ float rotationZ = buffer.readFloat();
+ float shadowElevation = buffer.readFloat();
+ float transformOriginX = buffer.readFloat();
+ float transformOriginY = buffer.readFloat();
+ float alpha = buffer.readFloat();
+ float cameraDistance = buffer.readFloat();
+ int blendMode = buffer.readInt();
+ int spotShadowColorId = buffer.readInt();
+ int ambientShadowColorId = buffer.readInt();
+ int colorFilterId = buffer.readInt();
+ int renderEffectId = buffer.readInt();
+ operations.add(
+ new GraphicsLayerModifierOperation(
+ scaleX,
+ scaleY,
+ rotationX,
+ rotationY,
+ rotationZ,
+ shadowElevation,
+ transformOriginX,
+ transformOriginY,
+ alpha,
+ cameraDistance,
+ blendMode,
+ spotShadowColorId,
+ ambientShadowColorId,
+ colorFilterId,
+ renderEffectId));
+ }
+
+ public static void documentation(DocumentationBuilder doc) {
+ doc.operation("Modifier Operations", OP_CODE, CLASS_NAME)
+ .description("define the GraphicsLayer Modifier")
+ .field(FLOAT, "scaleX", "")
+ .field(FLOAT, "scaleY", "")
+ .field(FLOAT, "rotationX", "")
+ .field(FLOAT, "rotationY", "")
+ .field(FLOAT, "rotationZ", "")
+ .field(FLOAT, "shadowElevation", "")
+ .field(FLOAT, "transformOriginX", "")
+ .field(FLOAT, "transformOriginY", "")
+ .field(FLOAT, "alpha", "")
+ .field(FLOAT, "cameraDistance", "")
+ .field(INT, "blendMode", "")
+ .field(INT, "spotShadowColorId", "")
+ .field(INT, "ambientShadowColorId", "")
+ .field(INT, "colorFilterId", "")
+ .field(INT, "renderEffectId", "");
+ }
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {}
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
index d3613f8..97c76c0 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.WireBuffer;
@@ -30,6 +32,7 @@
private static final int OP_CODE = Operations.MODIFIER_HEIGHT;
public static final String CLASS_NAME = "HeightModifierOperation";
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -38,13 +41,13 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, int type, float value) {
+ public static void apply(@NonNull WireBuffer buffer, int type, float value) {
buffer.start(OP_CODE);
buffer.writeInt(type);
buffer.writeFloat(value);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Type type = Type.fromInt(buffer.readInt());
float value = buffer.readFloat();
Operation op = new HeightModifierOperation(type, value);
@@ -52,7 +55,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mType.ordinal(), mValue);
}
@@ -68,17 +71,19 @@
super(value);
}
+ @NonNull
@Override
public String toString() {
- return "Height(" + mValue + ")";
+ return "Height(" + mType + ", " + mValue + ")";
}
+ @NonNull
@Override
public String serializedName() {
return "HEIGHT";
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Modifier Operations", OP_CODE, CLASS_NAME)
.description("define the animation")
.field(INT, "type", "")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java
index ac42470a..836321f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -39,6 +42,7 @@
mActionId = id;
}
+ @NonNull
@Override
public String toString() {
return "HostActionOperation(" + mActionId + ")";
@@ -48,20 +52,22 @@
return mActionId;
}
+ @NonNull
public String serializedName() {
return "HOST_ACTION";
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(indent, serializedName() + " = " + mActionId);
}
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -70,21 +76,25 @@
@Override
public void runAction(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ @NonNull RemoteContext context,
+ CoreDocument document,
+ Component component,
+ float x,
+ float y) {
context.runAction(mActionId, "");
}
- public static void apply(WireBuffer buffer, int actionId) {
+ public static void apply(@NonNull WireBuffer buffer, int actionId) {
buffer.start(OP_CODE);
buffer.writeInt(actionId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int actionId = buffer.readInt();
operations.add(new HostActionOperation(actionId));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", OP_CODE, "HostAction")
.description("Host action. This operation represents a host action")
.field(INT, "ACTION_ID", "Host Action ID");
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java
index b674a58..e97e897 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -33,31 +36,47 @@
public class HostNamedActionOperation implements ActionOperation {
private static final int OP_CODE = Operations.HOST_NAMED_ACTION;
- int mTextId = -1;
+ public static final int FLOAT_TYPE = 0;
+ public static final int INT_TYPE = 1;
+ public static final int STRING_TYPE = 2;
+ public static final int NONE_TYPE = -1;
- public HostNamedActionOperation(int id) {
+ int mTextId = -1;
+ int mType = NONE_TYPE;
+ int mValueId = -1;
+
+ public HostNamedActionOperation(int id, int type, int valueId) {
mTextId = id;
+ mType = type;
+ mValueId = valueId;
}
+ @NonNull
@Override
public String toString() {
- return "HostNamedActionOperation(" + mTextId + ")";
+ return "HostNamedActionOperation(" + mTextId + " : " + mValueId + ")";
}
+ @NonNull
public String serializedName() {
return "HOST_NAMED_ACTION";
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
- serializer.append(indent, serializedName() + " = " + mTextId);
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
+ if (mValueId != -1) {
+ serializer.append(indent, serializedName() + " = " + mTextId + " : " + mValueId);
+ } else {
+ serializer.append(indent, serializedName() + " = " + mTextId);
+ }
}
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -66,23 +85,42 @@
@Override
public void runAction(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
- context.runNamedAction(mTextId);
+ @NonNull RemoteContext context,
+ CoreDocument document,
+ Component component,
+ float x,
+ float y) {
+ Object value = null;
+ if (mValueId != -1) {
+ if (mType == INT_TYPE) {
+ value = context.mRemoteComposeState.getInteger(mValueId);
+ } else if (mType == STRING_TYPE) {
+ value = context.mRemoteComposeState.getFromId(mValueId);
+ } else if (mType == FLOAT_TYPE) {
+ value = context.mRemoteComposeState.getFloat(mValueId);
+ }
+ }
+ context.runNamedAction(mTextId, value);
}
- public static void apply(WireBuffer buffer, int textId) {
+ public static void apply(@NonNull WireBuffer buffer, int textId, int type, int valueId) {
buffer.start(OP_CODE);
buffer.writeInt(textId);
+ buffer.writeInt(type);
+ buffer.writeInt(valueId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int textId = buffer.readInt();
- operations.add(new HostNamedActionOperation(textId));
+ int type = buffer.readInt();
+ int valueId = buffer.readInt();
+ operations.add(new HostNamedActionOperation(textId, type, valueId));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", OP_CODE, "HostNamedAction")
.description("Host Named action. This operation represents a host action")
- .field(INT, "TEXT_ID", "Named Host Action Text ID");
+ .field(INT, "TEXT_ID", "Named Host Action Text ID")
+ .field(INT, "VALUE_ID", "Named Host Action Value ID");
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java
new file mode 100644
index 0000000..65fe345
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.operations.Utils;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/** Represents an offset modifier. */
+public class OffsetModifierOperation extends DecoratorModifierOperation {
+ private static final int OP_CODE = Operations.MODIFIER_OFFSET;
+ public static final String CLASS_NAME = "OffsetModifierOperation";
+
+ float mX;
+ float mY;
+
+ public OffsetModifierOperation(float x, float y) {
+ this.mX = x;
+ this.mY = y;
+ }
+
+ public float getX() {
+ return mX;
+ }
+
+ public float getY() {
+ return mY;
+ }
+
+ public void setX(float x) {
+ this.mX = x;
+ }
+
+ public void setY(float y) {
+ this.mY = y;
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ apply(buffer, mX, mY);
+ }
+
+ // @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, "OFFSET = [" + mX + ", " + mY + "]");
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ float x = context.getContext().mRemoteComposeState.getFloat(Utils.idFromNan(mX));
+ float y = context.getContext().mRemoteComposeState.getFloat(Utils.idFromNan(mY));
+ float density = context.getContext().getDensity();
+ x *= density;
+ y *= density;
+ context.translate(x, y);
+ }
+
+ @Override
+ public String toString() {
+ return "OffsetModifierOperation(" + mX + ", " + mY + ")";
+ }
+
+ public static String name() {
+ return CLASS_NAME;
+ }
+
+ public static int id() {
+ return OP_CODE;
+ }
+
+ public static void apply(WireBuffer buffer, float x, float y) {
+ buffer.start(OP_CODE);
+ buffer.writeFloat(x);
+ buffer.writeFloat(y);
+ }
+
+ public static void read(WireBuffer buffer, List<Operation> operations) {
+ float x = buffer.readFloat();
+ float y = buffer.readFloat();
+ operations.add(new OffsetModifierOperation(x, y));
+ }
+
+ public static void documentation(DocumentationBuilder doc) {
+ doc.operation("Modifier Operations", OP_CODE, CLASS_NAME)
+ .description("define the Offset Modifier")
+ .field(FLOAT, "x", "")
+ .field(FLOAT, "y", "");
+ }
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {}
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
index e0ec1a6..ed5522e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -78,12 +81,12 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mLeft, mTop, mRight, mBottom);
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(
indent, "PADDING = [" + mLeft + ", " + mTop + ", " + mRight + ", " + mBottom + "]");
}
@@ -91,11 +94,13 @@
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
+ @NonNull
@Override
public String toString() {
return "PaddingModifierOperation("
@@ -109,6 +114,7 @@
+ ")";
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -117,7 +123,8 @@
return Operations.MODIFIER_PADDING;
}
- public static void apply(WireBuffer buffer, float left, float top, float right, float bottom) {
+ public static void apply(
+ @NonNull WireBuffer buffer, float left, float top, float right, float bottom) {
buffer.start(Operations.MODIFIER_PADDING);
buffer.writeFloat(left);
buffer.writeFloat(top);
@@ -125,7 +132,7 @@
buffer.writeFloat(bottom);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
float left = buffer.readFloat();
float top = buffer.readFloat();
float right = buffer.readFloat();
@@ -133,7 +140,7 @@
operations.add(new PaddingModifierOperation(left, top, right, bottom));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Modifier Operations", OP_CODE, CLASS_NAME)
.description("define the Padding Modifier")
.field(FLOAT, "left", "")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
index dc95fe7..6218dd5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
@@ -17,7 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
-import com.android.internal.widget.remotecompose.core.CoreDocument;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -25,7 +26,6 @@
import com.android.internal.widget.remotecompose.core.WireBuffer;
import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
import com.android.internal.widget.remotecompose.core.operations.DrawBase4;
-import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent;
import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
@@ -37,7 +37,7 @@
public static final int OP_CODE = Operations.MODIFIER_ROUNDED_CLIP_RECT;
public static final String CLASS_NAME = "RoundedClipRectModifierOperation";
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Maker m = RoundedClipRectModifierOperation::new;
read(m, buffer, operations);
}
@@ -46,16 +46,17 @@
return OP_CODE;
}
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@Override
- protected void write(WireBuffer buffer, float v1, float v2, float v3, float v4) {
+ protected void write(@NonNull WireBuffer buffer, float v1, float v2, float v3, float v4) {
apply(buffer, v1, v2, v3, v4);
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Modifier Operations", id(), "RoundedClipRectModifierOperation")
.description("clip with rectangle")
.field(
@@ -90,7 +91,7 @@
}
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
context.roundedClipRect(mWidth, mHeight, mX1, mY1, mX2, mY2);
}
@@ -101,13 +102,7 @@
}
@Override
- public void onClick(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
- // nothing
- }
-
- @Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(
indent,
"ROUNDED_CLIP_RECT = ["
@@ -135,7 +130,11 @@
* @param bottomEnd bottomEnd radius
*/
public static void apply(
- WireBuffer buffer, float topStart, float topEnd, float bottomStart, float bottomEnd) {
+ @NonNull WireBuffer buffer,
+ float topStart,
+ float topEnd,
+ float bottomStart,
+ float bottomEnd) {
write(buffer, OP_CODE, topStart, topEnd, bottomStart, bottomEnd);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java
new file mode 100644
index 0000000..29ec828
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.operations.layout.ActionOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/** Apply a value change on an float variable. */
+public class ValueFloatChangeActionOperation implements ActionOperation {
+ private static final int OP_CODE = Operations.VALUE_FLOAT_CHANGE_ACTION;
+
+ int mTargetValueId = -1;
+ float mValue = -1;
+
+ public ValueFloatChangeActionOperation(int id, float value) {
+ mTargetValueId = id;
+ mValue = value;
+ }
+
+ @Override
+ public String toString() {
+ return "ValueFloatChangeActionOperation(" + mTargetValueId + ")";
+ }
+
+ public String serializedName() {
+ return "VALUE_FLOAT_CHANGE";
+ }
+
+ @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, serializedName() + " = " + mTargetValueId + " -> " + mValue);
+ }
+
+ @Override
+ public void apply(RemoteContext context) {}
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {}
+
+ @Override
+ public void runAction(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ System.out.println("OVERRIDE " + mTargetValueId + " TO " + mValue);
+ context.overrideFloat(mTargetValueId, mValue);
+ }
+
+ public static void apply(WireBuffer buffer, int valueId, float value) {
+ buffer.start(OP_CODE);
+ buffer.writeInt(valueId);
+ buffer.writeFloat(value);
+ }
+
+ public static void read(WireBuffer buffer, List<Operation> operations) {
+ int valueId = buffer.readInt();
+ float value = buffer.readFloat();
+ operations.add(new ValueFloatChangeActionOperation(valueId, value));
+ }
+
+ public static void documentation(DocumentationBuilder doc) {
+ doc.operation("Layout Operations", OP_CODE, "ValueFloatChangeActionOperation")
+ .description(
+ "ValueIntegerChange action. "
+ + " This operation represents a value change for the given id")
+ .field(INT, "TARGET_VALUE_ID", "Value ID")
+ .field(FLOAT, "VALUE", "float value to be assigned to the target");
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java
index 8876720..d7ce8ac 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -41,25 +44,28 @@
mValue = value;
}
+ @NonNull
@Override
public String toString() {
return "ValueChangeActionOperation(" + mTargetValueId + ")";
}
+ @NonNull
public String serializedName() {
return "VALUE_INTEGER_CHANGE";
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(indent, serializedName() + " = " + mTargetValueId + " -> " + mValue);
}
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -68,23 +74,27 @@
@Override
public void runAction(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ @NonNull RemoteContext context,
+ CoreDocument document,
+ Component component,
+ float x,
+ float y) {
context.overrideInteger(mTargetValueId, mValue);
}
- public static void apply(WireBuffer buffer, int valueId, int value) {
+ public static void apply(@NonNull WireBuffer buffer, int valueId, int value) {
buffer.start(OP_CODE);
buffer.writeInt(valueId);
buffer.writeInt(value);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int valueId = buffer.readInt();
int value = buffer.readInt();
operations.add(new ValueIntegerChangeActionOperation(valueId, value));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", OP_CODE, "ValueIntegerChangeActionOperation")
.description(
"ValueIntegerChange action. "
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java
index fb5e911..75d13e7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -41,17 +44,19 @@
mValueExpressionId = value;
}
+ @NonNull
@Override
public String toString() {
return "ValueIntegerExpressionChangeActionOperation(" + mTargetValueId + ")";
}
+ @NonNull
public String serializedName() {
return "VALUE_INTEGER_EXPRESSION_CHANGE";
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(
indent, serializedName() + " = " + mTargetValueId + " -> " + mValueExpressionId);
}
@@ -59,8 +64,9 @@
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -69,23 +75,27 @@
@Override
public void runAction(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ @NonNull RemoteContext context,
+ @NonNull CoreDocument document,
+ Component component,
+ float x,
+ float y) {
document.evaluateIntExpression(mValueExpressionId, (int) mTargetValueId, context);
}
- public static void apply(WireBuffer buffer, long valueId, long value) {
+ public static void apply(@NonNull WireBuffer buffer, long valueId, long value) {
buffer.start(OP_CODE);
buffer.writeLong(valueId);
buffer.writeLong(value);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
long valueId = buffer.readLong();
long value = buffer.readLong();
operations.add(new ValueIntegerExpressionChangeActionOperation(valueId, value));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", OP_CODE, "ValueIntegerExpressionChangeActionOperation")
.description(
"ValueIntegerExpressionChange action. "
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java
index a64a492..26d7244 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java
@@ -17,6 +17,9 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -41,6 +44,7 @@
mValueId = value;
}
+ @NonNull
@Override
public String toString() {
return "ValueChangeActionOperation(" + mTargetValueId + ")";
@@ -50,20 +54,22 @@
return mTargetValueId;
}
+ @NonNull
public String serializedName() {
return "VALUE_CHANGE";
}
@Override
- public void serializeToString(int indent, StringSerializer serializer) {
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
serializer.append(indent, serializedName() + " = " + mTargetValueId + " -> " + mValueId);
}
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@Nullable String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -72,23 +78,27 @@
@Override
public void runAction(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ @NonNull RemoteContext context,
+ CoreDocument document,
+ Component component,
+ float x,
+ float y) {
context.overrideText(mTargetValueId, mValueId);
}
- public static void apply(WireBuffer buffer, int valueId, int value) {
+ public static void apply(@NonNull WireBuffer buffer, int valueId, int value) {
buffer.start(OP_CODE);
buffer.writeInt(valueId);
buffer.writeInt(value);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int valueId = buffer.readInt();
int value = buffer.readInt();
operations.add(new ValueStringChangeActionOperation(valueId, value));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Layout Operations", OP_CODE, "ValueStringChangeActionOperation")
.description(
"ValueStrin gChange action. "
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
index 62403b3..e2f899c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
@@ -18,6 +18,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.WireBuffer;
@@ -30,6 +32,7 @@
private static final int OP_CODE = Operations.MODIFIER_WIDTH;
public static final String CLASS_NAME = "WidthModifierOperation";
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -38,13 +41,13 @@
return OP_CODE;
}
- public static void apply(WireBuffer buffer, int type, float value) {
+ public static void apply(@NonNull WireBuffer buffer, int type, float value) {
buffer.start(OP_CODE);
buffer.writeInt(type);
buffer.writeFloat(value);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
Type type = Type.fromInt(buffer.readInt());
float value = buffer.readFloat();
Operation op = new WidthModifierOperation(type, value);
@@ -56,7 +59,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mType.ordinal(), mValue);
}
@@ -68,17 +71,19 @@
super(value);
}
+ @NonNull
@Override
public String toString() {
- return "Width(" + mValue + ")";
+ return "Width(" + mType + ", " + mValue + ")";
}
+ @NonNull
@Override
public String serializedName() {
return "WIDTH";
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Modifier Operations", OP_CODE, CLASS_NAME)
.description("define the animation")
.field(INT, "type", "")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java
new file mode 100644
index 0000000..aa20e03
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.operations.Utils;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/** Represents a ZIndex modifier, allowing to change the z-index of a component. */
+public class ZIndexModifierOperation extends DecoratorModifierOperation {
+ private static final int OP_CODE = Operations.MODIFIER_ZINDEX;
+ public static final String CLASS_NAME = "ZIndexModifierOperation";
+ float mValue;
+ float mCurrentValue;
+
+ public ZIndexModifierOperation(float value) {
+ this.mValue = value;
+ }
+
+ public float getValue() {
+ return mCurrentValue;
+ }
+
+ public void setmValue(float value) {
+ this.mValue = value;
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ apply(buffer, mValue);
+ }
+
+ // @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, "ZINDEX = [" + mValue + "]");
+ }
+
+ @Override
+ public String deepToString(String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ mCurrentValue = mValue;
+ if (Utils.isVariable(mValue)) {
+ mCurrentValue =
+ context.getContext().mRemoteComposeState.getFloat(Utils.idFromNan(mValue));
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ZIndexModifierOperation(" + mValue + ")";
+ }
+
+ public static String name() {
+ return CLASS_NAME;
+ }
+
+ public static int id() {
+ return OP_CODE;
+ }
+
+ public static void apply(WireBuffer buffer, float value) {
+ buffer.start(OP_CODE);
+ buffer.writeFloat(value);
+ }
+
+ public static void read(WireBuffer buffer, List<Operation> operations) {
+ float value = buffer.readFloat();
+ operations.add(new ZIndexModifierOperation(value));
+ }
+
+ public static void documentation(DocumentationBuilder doc) {
+ doc.operation("Modifier Operations", OP_CODE, CLASS_NAME)
+ .description("define the Z-Index Modifier")
+ .field(FLOAT, "value", "");
+ }
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {}
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
index 4849b12..d8e49b0 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.utils;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import java.util.ArrayList;
/** Internal utility debug class */
@@ -23,12 +26,12 @@
public static final boolean DEBUG_LAYOUT_ON = false;
public static class Node {
- public Node parent;
+ @Nullable public Node parent;
public String name;
public String endString;
- public ArrayList<Node> list = new ArrayList<>();
+ @NonNull public ArrayList<Node> list = new ArrayList<>();
- public Node(Node parent, String name) {
+ public Node(@Nullable Node parent, String name) {
this.parent = parent;
this.name = name;
this.endString = name + " DONE";
@@ -48,21 +51,21 @@
}
}
- public static Node node = new Node(null, "Root");
- public static Node currentNode = node;
+ @NonNull public static Node node = new Node(null, "Root");
+ @NonNull public static Node currentNode = node;
public static void clear() {
node = new Node(null, "Root");
currentNode = node;
}
- public static void s(StringValueSupplier valueSupplier) {
+ public static void s(@NonNull StringValueSupplier valueSupplier) {
if (DEBUG_LAYOUT_ON) {
currentNode = new Node(currentNode, valueSupplier.getString());
}
}
- public static void log(StringValueSupplier valueSupplier) {
+ public static void log(@NonNull StringValueSupplier valueSupplier) {
if (DEBUG_LAYOUT_ON) {
new LogNode(currentNode, valueSupplier.getString());
}
@@ -78,7 +81,7 @@
}
}
- public static void e(StringValueSupplier valueSupplier) {
+ public static void e(@NonNull StringValueSupplier valueSupplier) {
if (DEBUG_LAYOUT_ON) {
currentNode.endString = valueSupplier.getString();
if (currentNode.parent != null) {
@@ -89,7 +92,7 @@
}
}
- public static void printNode(int indent, Node node, StringBuilder builder) {
+ public static void printNode(int indent, @NonNull Node node, @NonNull StringBuilder builder) {
if (DEBUG_LAYOUT_ON) {
StringBuilder indentationBuilder = new StringBuilder();
for (int i = 0; i < indent; i++) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java
index 9a3cd54..a808cf0 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.paint;
+import android.annotation.NonNull;
+
/** Provides a Builder pattern for a PaintBundle */
class Painter {
PaintBundle mPaint;
@@ -24,16 +26,19 @@
return mPaint;
}
+ @NonNull
public Painter setAntiAlias(boolean aa) {
mPaint.setAntiAlias(aa);
return this;
}
+ @NonNull
public Painter setColor(int color) {
mPaint.setColor(color);
return this;
}
+ @NonNull
public Painter setColorId(int colorId) {
mPaint.setColorId(colorId);
return this;
@@ -44,6 +49,7 @@
*
* @param join set the paint's Join, used whenever the paint's style is Stroke or StrokeAndFill.
*/
+ @NonNull
public Painter setStrokeJoin(int join) {
mPaint.setStrokeJoin(join);
return this;
@@ -56,6 +62,7 @@
* @param width set the paint's stroke width, used whenever the paint's style is Stroke or
* StrokeAndFill.
*/
+ @NonNull
public Painter setStrokeWidth(float width) {
mPaint.setStrokeWidth(width);
return this;
@@ -67,6 +74,7 @@
*
* @param style The new style to set in the paint
*/
+ @NonNull
public Painter setStyle(int style) {
mPaint.setStyle(style);
return this;
@@ -78,6 +86,7 @@
* @param cap set the paint's line cap style, used whenever the paint's style is Stroke or
* StrokeAndFill.
*/
+ @NonNull
public Painter setStrokeCap(int cap) {
mPaint.setStrokeCap(cap);
return this;
@@ -90,6 +99,7 @@
* @param miter set the miter limit on the paint, used whenever the paint's style is Stroke or
* StrokeAndFill.
*/
+ @NonNull
public Painter setStrokeMiter(float miter) {
mPaint.setStrokeMiter(miter);
return this;
@@ -101,6 +111,7 @@
*
* @param alpha set the alpha component [0..1.0] of the paint's color.
*/
+ @NonNull
public Painter setAlpha(float alpha) {
mPaint.setAlpha((alpha > 2) ? alpha / 255f : alpha);
return this;
@@ -112,6 +123,7 @@
* @param color The ARGB source color used with the specified Porter-Duff mode
* @param mode The porter-duff mode that is applied
*/
+ @NonNull
public Painter setPorterDuffColorFilter(int color, int mode) {
mPaint.setColorFilter(color, mode);
return this;
@@ -130,6 +142,7 @@
* line.
* @param tileMode The Shader tiling mode
*/
+ @NonNull
public Painter setLinearGradient(
float startX,
float startY,
@@ -155,6 +168,7 @@
* circle.
* @param tileMode The Shader tiling mode
*/
+ @NonNull
public Painter setRadialGradient(
float centerX,
float centerY,
@@ -178,6 +192,7 @@
* may produce unexpected results. If positions is NULL, then the colors are automatically
* spaced evenly.
*/
+ @NonNull
public Painter setSweepGradient(float centerX, float centerY, int[] colors, float[] positions) {
mPaint.setSweepGradient(colors, 0, positions, centerX, centerY);
return this;
@@ -188,6 +203,7 @@
*
* @param size set the paint's text size in pixel units.
*/
+ @NonNull
public Painter setTextSize(float size) {
mPaint.setTextSize(size);
return this;
@@ -215,16 +231,19 @@
* @param weight The desired weight to be drawn.
* @param italic {@code true} if italic style is desired to be drawn. Otherwise, {@code false}
*/
+ @NonNull
public Painter setTypeface(int fontType, int weight, boolean italic) {
mPaint.setTextStyle(fontType, weight, italic);
return this;
}
+ @NonNull
public Painter setFilterBitmap(boolean filter) {
mPaint.setFilterBitmap(filter);
return this;
}
+ @NonNull
public Painter setShader(int id) {
mPaint.setShader(id);
return this;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
index 1d673c4..b25f4cd 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
@@ -15,11 +15,12 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
-/**
- * high performance floating point expression evaluator used in animation
- */
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/** high performance floating point expression evaluator used in animation */
public class AnimatedFloatExpression {
- static IntMap<String> sNames = new IntMap<>();
+ @NonNull static IntMap<String> sNames = new IntMap<>();
public static final int OFFSET = 0x310_000;
public static final float ADD = asNan(OFFSET + 1);
public static final float SUB = asNan(OFFSET + 2);
@@ -74,7 +75,7 @@
private static final float FP_TO_DEG = 0.017453292f; // 180/PI
float[] mStack;
- float[] mLocalStack = new float[128];
+ @NonNull float[] mLocalStack = new float[128];
float[] mVar;
CollectionsAccess mCollectionsAccess;
@@ -201,7 +202,7 @@
* @param var
* @return
*/
- public float eval(float[] exp, int len, float... var) {
+ public float eval(@NonNull float[] exp, int len, float... var) {
System.arraycopy(exp, 0, mLocalStack, 0, len);
mStack = mLocalStack;
mVar = var;
@@ -224,7 +225,7 @@
* @param var
* @return
*/
- public float evalDB(float[] exp, float... var) {
+ public float evalDB(@NonNull float[] exp, float... var) {
mStack = exp;
mVar = var;
int sp = -1;
@@ -240,195 +241,281 @@
return mStack[sp];
}
- Op[] mOps = {
+ @NonNull Op[] mOps;
+
+ {
+ Op mADD =
+ (sp) -> { // ADD
+ mStack[sp - 1] = mStack[sp - 1] + mStack[sp];
+ return sp - 1;
+ };
+ Op mSUB =
+ (sp) -> { // SUB
+ mStack[sp - 1] = mStack[sp - 1] - mStack[sp];
+ return sp - 1;
+ };
+ Op mMUL =
+ (sp) -> { // MUL
+ mStack[sp - 1] = mStack[sp - 1] * mStack[sp];
+ return sp - 1;
+ };
+ Op mDIV =
+ (sp) -> { // DIV
+ mStack[sp - 1] = mStack[sp - 1] / mStack[sp];
+ return sp - 1;
+ };
+ Op mMOD =
+ (sp) -> { // MOD
+ mStack[sp - 1] = mStack[sp - 1] % mStack[sp];
+ return sp - 1;
+ };
+ Op mMIN =
+ (sp) -> { // MIN
+ mStack[sp - 1] = (float) Math.min(mStack[sp - 1], mStack[sp]);
+ return sp - 1;
+ };
+ Op mMAX =
+ (sp) -> { // MAX
+ mStack[sp - 1] = (float) Math.max(mStack[sp - 1], mStack[sp]);
+ return sp - 1;
+ };
+ Op mPOW =
+ (sp) -> { // POW
+ mStack[sp - 1] = (float) Math.pow(mStack[sp - 1], mStack[sp]);
+ return sp - 1;
+ };
+ Op mSQRT =
+ (sp) -> { // SQRT
+ mStack[sp] = (float) Math.sqrt(mStack[sp]);
+ return sp;
+ };
+ Op mABS =
+ (sp) -> { // ABS
+ mStack[sp] = (float) Math.abs(mStack[sp]);
+ return sp;
+ };
+ Op mSIGN =
+ (sp) -> { // SIGN
+ mStack[sp] = (float) Math.signum(mStack[sp]);
+ return sp;
+ };
+ Op mCOPY_SIGN =
+ (sp) -> { // copySign
+ mStack[sp - 1] = (float) Math.copySign(mStack[sp - 1], mStack[sp]);
+ return sp - 1;
+ };
+ Op mEXP =
+ (sp) -> { // EXP
+ mStack[sp] = (float) Math.exp(mStack[sp]);
+ return sp;
+ };
+ Op mFLOOR =
+ (sp) -> { // FLOOR
+ mStack[sp] = (float) Math.floor(mStack[sp]);
+ return sp;
+ };
+ Op mLOG =
+ (sp) -> { // LOG
+ mStack[sp] = (float) Math.log10(mStack[sp]);
+ return sp;
+ };
+ Op mLN =
+ (sp) -> { // LN
+ mStack[sp] = (float) Math.log(mStack[sp]);
+ return sp;
+ };
+ Op mROUND =
+ (sp) -> { // ROUND
+ mStack[sp] = (float) Math.round(mStack[sp]);
+ return sp;
+ };
+ Op mSIN =
+ (sp) -> { // SIN
+ mStack[sp] = (float) Math.sin(mStack[sp]);
+ return sp;
+ };
+ Op mCOS =
+ (sp) -> { // COS
+ mStack[sp] = (float) Math.cos(mStack[sp]);
+ return sp;
+ };
+ Op mTAN =
+ (sp) -> { // TAN
+ mStack[sp] = (float) Math.tan(mStack[sp]);
+ return sp;
+ };
+ Op mASIN =
+ (sp) -> { // ASIN
+ mStack[sp] = (float) Math.asin(mStack[sp]);
+ return sp;
+ };
+ Op mACOS =
+ (sp) -> { // ACOS
+ mStack[sp] = (float) Math.acos(mStack[sp]);
+ return sp;
+ };
+ Op mATAN =
+ (sp) -> { // ATAN
+ mStack[sp] = (float) Math.atan(mStack[sp]);
+ return sp;
+ };
+ Op mATAN2 =
+ (sp) -> { // ATAN2
+ mStack[sp - 1] = (float) Math.atan2(mStack[sp - 1], mStack[sp]);
+ return sp - 1;
+ };
+ Op mMAD =
+ (sp) -> { // MAD
+ mStack[sp - 2] = mStack[sp] + mStack[sp - 1] * mStack[sp - 2];
+ return sp - 2;
+ };
+ Op mTERNARY_CONDITIONAL =
+ (sp) -> { // TERNARY_CONDITIONAL
+ mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2];
+ return sp - 2;
+ };
+ Op mCLAMP =
+ (sp) -> { // CLAMP
+ mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
+ return sp - 2;
+ };
+ Op mCBRT =
+ (sp) -> { // CBRT
+ mStack[sp] = (float) Math.pow(mStack[sp], 1 / 3.);
+ return sp;
+ };
+ Op mDEG =
+ (sp) -> { // DEG
+ mStack[sp] = mStack[sp] * FP_TO_RAD;
+ return sp;
+ };
+ Op mRAD =
+ (sp) -> { // RAD
+ mStack[sp] = mStack[sp] * FP_TO_DEG;
+ return sp;
+ };
+ Op mCEIL =
+ (sp) -> { // CEIL
+ mStack[sp] = (float) Math.ceil(mStack[sp]);
+ return sp;
+ };
+ Op mA_DEREF =
+ (sp) -> { // A_DEREF
+ int id = fromNaN(mStack[sp]);
+ mStack[sp - 1] = mCollectionsAccess.getFloatValue(id, (int) mStack[sp - 1]);
+ return sp - 1;
+ };
+ Op mA_MAX =
+ (sp) -> { // A_MAX
+ int id = fromNaN(mStack[sp]);
+ float[] array = mCollectionsAccess.getFloats(id);
+ float max = array[0];
+ for (int i = 1; i < array.length; i++) {
+ max = Math.max(max, array[i]);
+ }
+ mStack[sp] = max;
+ return sp;
+ };
+ Op mA_MIN =
+ (sp) -> { // A_MIN
+ int id = fromNaN(mStack[sp]);
+ float[] array = mCollectionsAccess.getFloats(id);
+ float max = array[0];
+ for (int i = 1; i < array.length; i++) {
+ max = Math.max(max, array[i]);
+ }
+ mStack[sp] = max;
+ return sp;
+ };
+ Op mA_SUM =
+ (sp) -> { // A_SUM
+ int id = fromNaN(mStack[sp]);
+ float[] array = mCollectionsAccess.getFloats(id);
+ float sum = 0;
+ for (int i = 0; i < array.length; i++) {
+ sum += array[i];
+ }
+ mStack[sp] = sum;
+ return sp;
+ };
+ Op mA_AVG =
+ (sp) -> { // A_AVG
+ int id = fromNaN(mStack[sp]);
+ float[] array = mCollectionsAccess.getFloats(id);
+ float sum = 0;
+ for (int i = 0; i < array.length; i++) {
+ sum += array[i];
+ }
+ mStack[sp] = sum / array.length;
+ return sp;
+ };
+ Op mA_LEN =
+ (sp) -> { // A_LEN
+ int id = fromNaN(mStack[sp]);
+ mStack[sp] = mCollectionsAccess.getListLength(id);
+ return sp;
+ };
+ Op mFIRST_VAR =
+ (sp) -> { // FIRST_VAR
+ mStack[sp] = mVar[0];
+ return sp;
+ };
+ Op mSECOND_VAR =
+ (sp) -> { // SECOND_VAR
+ mStack[sp] = mVar[1];
+ return sp;
+ };
+ Op mTHIRD_VAR =
+ (sp) -> { // THIRD_VAR
+ mStack[sp] = mVar[2];
+ return sp;
+ };
+
+ Op[] ops = {
null,
- (sp) -> { // ADD
- mStack[sp - 1] = mStack[sp - 1] + mStack[sp];
- return sp - 1;
- },
- (sp) -> { // SUB
- mStack[sp - 1] = mStack[sp - 1] - mStack[sp];
- return sp - 1;
- },
- (sp) -> { // MUL
- mStack[sp - 1] = mStack[sp - 1] * mStack[sp];
- return sp - 1;
- },
- (sp) -> { // DIV
- mStack[sp - 1] = mStack[sp - 1] / mStack[sp];
- return sp - 1;
- },
- (sp) -> { // MOD
- mStack[sp - 1] = mStack[sp - 1] % mStack[sp];
- return sp - 1;
- },
- (sp) -> { // MIN
- mStack[sp - 1] = (float) Math.min(mStack[sp - 1], mStack[sp]);
- return sp - 1;
- },
- (sp) -> { // MAX
- mStack[sp - 1] = (float) Math.max(mStack[sp - 1], mStack[sp]);
- return sp - 1;
- },
- (sp) -> { // POW
- mStack[sp - 1] = (float) Math.pow(mStack[sp - 1], mStack[sp]);
- return sp - 1;
- },
- (sp) -> { // SQRT
- mStack[sp] = (float) Math.sqrt(mStack[sp]);
- return sp;
- },
- (sp) -> { // ABS
- mStack[sp] = (float) Math.abs(mStack[sp]);
- return sp;
- },
- (sp) -> { // SIGN
- mStack[sp] = (float) Math.signum(mStack[sp]);
- return sp;
- },
- (sp) -> { // copySign
- mStack[sp - 1] = (float) Math.copySign(mStack[sp - 1], mStack[sp]);
- return sp - 1;
- },
- (sp) -> { // EXP
- mStack[sp] = (float) Math.exp(mStack[sp]);
- return sp;
- },
- (sp) -> { // FLOOR
- mStack[sp] = (float) Math.floor(mStack[sp]);
- return sp;
- },
- (sp) -> { // LOG
- mStack[sp] = (float) Math.log10(mStack[sp]);
- return sp;
- },
- (sp) -> { // LN
- mStack[sp] = (float) Math.log(mStack[sp]);
- return sp;
- },
- (sp) -> { // ROUND
- mStack[sp] = (float) Math.round(mStack[sp]);
- return sp;
- },
- (sp) -> { // SIN
- mStack[sp] = (float) Math.sin(mStack[sp]);
- return sp;
- },
- (sp) -> { // COS
- mStack[sp] = (float) Math.cos(mStack[sp]);
- return sp;
- },
- (sp) -> { // TAN
- mStack[sp] = (float) Math.tan(mStack[sp]);
- return sp;
- },
- (sp) -> { // ASIN
- mStack[sp] = (float) Math.asin(mStack[sp]);
- return sp;
- },
- (sp) -> { // ACOS
- mStack[sp] = (float) Math.acos(mStack[sp]);
- return sp;
- },
- (sp) -> { // ATAN
- mStack[sp] = (float) Math.atan(mStack[sp]);
- return sp;
- },
- (sp) -> { // ATAN2
- mStack[sp - 1] = (float) Math.atan2(mStack[sp - 1], mStack[sp]);
- return sp - 1;
- },
- (sp) -> { // MAD
- mStack[sp - 2] = mStack[sp] + mStack[sp - 1] * mStack[sp - 2];
- return sp - 2;
- },
- (sp) -> { // Ternary conditional
- mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2];
- return sp - 2;
- },
- (sp) -> { // CLAMP(min,max, val)
- mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
- return sp - 2;
- },
- (sp) -> { // CBRT cuberoot
- mStack[sp] = (float) Math.pow(mStack[sp], 1 / 3.);
- return sp;
- },
- (sp) -> { // DEG
- mStack[sp] = mStack[sp] * FP_TO_RAD;
- return sp;
- },
- (sp) -> { // RAD
- mStack[sp] = mStack[sp] * FP_TO_DEG;
- return sp;
- },
- (sp) -> { // CEIL
- mStack[sp] = (float) Math.ceil(mStack[sp]);
- return sp;
- },
- (sp) -> { // A_DEREF
- int id = fromNaN(mStack[sp]);
- mStack[sp] = mCollectionsAccess.getFloatValue(id, (int) mStack[sp - 1]);
- return sp - 1;
- },
- (sp) -> { // A_MAX
- int id = fromNaN(mStack[sp]);
- float[] array = mCollectionsAccess.getFloats(id);
- float max = array[0];
- for (int i = 1; i < array.length; i++) {
- max = Math.max(max, array[i]);
- }
- mStack[sp] = max;
- return sp;
- },
- (sp) -> { // A_MIN
- int id = fromNaN(mStack[sp]);
- float[] array = mCollectionsAccess.getFloats(id);
- float max = array[0];
- for (int i = 1; i < array.length; i++) {
- max = Math.max(max, array[i]);
- }
- mStack[sp] = max;
- return sp;
- },
- (sp) -> { // A_SUM
- int id = fromNaN(mStack[sp]);
- float[] array = mCollectionsAccess.getFloats(id);
- float sum = 0;
- for (int i = 0; i < array.length; i++) {
- sum += array[i];
- }
- mStack[sp] = sum;
- return sp;
- },
- (sp) -> { // A_AVG
- int id = fromNaN(mStack[sp]);
- float[] array = mCollectionsAccess.getFloats(id);
- float sum = 0;
- for (int i = 0; i < array.length; i++) {
- sum += array[i];
- }
- mStack[sp] = sum / array.length;
- return sp;
- },
- (sp) -> { // A_LEN
- int id = fromNaN(mStack[sp]);
- mStack[sp] = mCollectionsAccess.getListLength(id);
- return sp;
- },
- (sp) -> { // first var =
- mStack[sp] = mVar[0];
- return sp;
- },
- (sp) -> { // second var y?
- mStack[sp] = mVar[1];
- return sp;
- },
- (sp) -> { // 3rd var z?
- mStack[sp] = mVar[2];
- return sp;
- },
- };
+ mADD,
+ mSUB,
+ mMUL,
+ mDIV,
+ mMOD,
+ mMIN,
+ mMAX,
+ mPOW,
+ mSQRT,
+ mABS,
+ mSIGN,
+ mCOPY_SIGN,
+ mEXP,
+ mFLOOR,
+ mLOG,
+ mLN,
+ mROUND,
+ mSIN,
+ mCOS,
+ mTAN,
+ mASIN,
+ mACOS,
+ mATAN,
+ mATAN2,
+ mMAD,
+ mTERNARY_CONDITIONAL,
+ mCLAMP,
+ mCBRT,
+ mDEG,
+ mRAD,
+ mCEIL,
+ mA_DEREF,
+ mA_MAX,
+ mA_MIN,
+ mA_SUM,
+ mA_AVG,
+ mA_LEN,
+ mFIRST_VAR,
+ mSECOND_VAR,
+ mTHIRD_VAR,
+ };
+ mOps = ops;
+ }
static {
int k = 0;
@@ -483,6 +570,7 @@
* @param f
* @return
*/
+ @Nullable
public static String toMathName(float f) {
int id = fromNaN(f) - OFFSET;
return sNames.get(id);
@@ -495,7 +583,8 @@
* @param labels
* @return
*/
- public static String toString(float[] exp, String[] labels) {
+ @NonNull
+ public static String toString(@NonNull float[] exp, @Nullable String[] labels) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < exp.length; i++) {
float v = exp[i];
@@ -525,7 +614,7 @@
return s.toString();
}
- static String toString(float[] exp, int sp) {
+ static String toString(@NonNull float[] exp, int sp) {
// String[] str = new String[exp.length];
if (Float.isNaN(exp[sp])) {
int id = fromNaN(exp[sp]) - OFFSET;
@@ -575,42 +664,42 @@
}
static final int[] NO_OF_OPS = {
- -1, // no op
- 2,
- 2,
- 2,
- 2,
- 2, // + - * / %
- 2,
- 2,
- 2, // min max, power
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1, // sqrt,abs,CopySign,exp,floor,log,ln
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 2, // round,sin,cos,tan,asin,acos,atan,atan2
- 3,
- 3,
- 3,
- 1,
- 1,
- 1,
- 1,
- 0,
- 0,
- 0 // mad, ?:,
- // a[0],a[1],a[2]
+ -1, // no op
+ 2,
+ 2,
+ 2,
+ 2,
+ 2, // + - * / %
+ 2,
+ 2,
+ 2, // min max, power
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1, // sqrt,abs,CopySign,exp,floor,log,ln
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2, // round,sin,cos,tan,asin,acos,atan,atan2
+ 3,
+ 3,
+ 3,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0 // mad, ?:,
+ // a[0],a[1],a[2]
};
/**
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java
index 00c87c1..e74b335 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
+import android.annotation.NonNull;
+
/** Implement the scaling logic for Compose Image or ImageView */
public class ImageScaling {
@@ -97,6 +99,7 @@
adjustDrawToType();
}
+ @NonNull
static String str(float v) {
String s = " " + (int) v;
return s.substring(s.length() - 3);
@@ -210,6 +213,7 @@
}
}
+ @NonNull
public static String typeToString(int type) {
String[] typeString = {
"none",
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java
index 84e7843..749c0fe 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
+import android.annotation.Nullable;
+
import java.util.ArrayList;
import java.util.Arrays;
@@ -42,6 +44,7 @@
mSize = 0;
}
+ @Nullable
public T put(int key, T value) {
if (key == NOT_PRESENT) throw new IllegalArgumentException("Key cannot be NOT_PRESENT");
if (mSize > mKeys.length * LOAD_FACTOR) {
@@ -50,6 +53,7 @@
return insert(key, value);
}
+ @Nullable
public T get(int key) {
int index = findKey(key);
if (index == -1) {
@@ -61,6 +65,7 @@
return mSize;
}
+ @Nullable
private T insert(int key, T value) {
int index = hash(key) % mKeys.length;
while (mKeys[index] != NOT_PRESENT && mKeys[index] != key) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
index baa144d..8905431 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
/**
* High performance Integer expression evaluator
*
@@ -22,7 +25,7 @@
* 0)
*/
public class IntegerExpressionEvaluator {
- static IntMap<String> sNames = new IntMap<>();
+ @NonNull static IntMap<String> sNames = new IntMap<>();
public static final int OFFSET = 0x10000;
// add, sub, mul,div,mod,min,max, shl, shr, ushr, OR, AND , XOR, COPY_SIGN
public static final int I_ADD = OFFSET + 1;
@@ -57,7 +60,7 @@
public static final int I_VAR2 = OFFSET + 25;
int[] mStack;
- int[] mLocalStack = new int[128];
+ @NonNull int[] mLocalStack = new int[128];
int[] mVar;
interface Op {
@@ -68,8 +71,8 @@
* Evaluate an integer expression
*
* @param mask bits that are operators
- * @param exp rpn sequence of values and operators
- * @param var variables if the expression is a function
+ * @param exp rpn sequence of values and operators
+ * @param var variables if the expression is a function
* @return return the results of evaluating the expression
*/
public int eval(int mask, int[] exp, int... var) {
@@ -91,12 +94,12 @@
* Evaluate a integer expression
*
* @param mask bits that are operators
- * @param exp rpn sequence of values and operators
- * @param len the number of values in the expression
- * @param var variables if the expression is a function
+ * @param exp rpn sequence of values and operators
+ * @param len the number of values in the expression
+ * @param var variables if the expression is a function
* @return return the results of evaluating the expression
*/
- public int eval(int mask, int[] exp, int len, int... var) {
+ public int eval(int mask, @NonNull int[] exp, int len, int... var) {
System.arraycopy(exp, 0, mLocalStack, 0, len);
mStack = mLocalStack;
mVar = var;
@@ -116,11 +119,11 @@
* Evaluate a int expression
*
* @param opMask bits that are operators
- * @param exp rpn sequence of values and operators
- * @param var variables if the expression is a function
+ * @param exp rpn sequence of values and operators
+ * @param var variables if the expression is a function
* @return return the results of evaluating the expression
*/
- public int evalDB(int opMask, int[] exp, int... var) {
+ public int evalDB(int opMask, @NonNull int[] exp, int... var) {
mStack = exp;
mVar = var;
int sp = -1;
@@ -137,113 +140,172 @@
return mStack[sp];
}
- Op[] mOps = {
+ @NonNull Op[] mOps;
+
+ {
+ Op mADD =
+ (sp) -> { // ADD
+ mStack[sp - 1] = mStack[sp - 1] + mStack[sp];
+ return sp - 1;
+ };
+ Op mSUB =
+ (sp) -> { // SUB
+ mStack[sp - 1] = mStack[sp - 1] - mStack[sp];
+ return sp - 1;
+ };
+ Op mMUL =
+ (sp) -> { // MUL
+ mStack[sp - 1] = mStack[sp - 1] * mStack[sp];
+ return sp - 1;
+ };
+ Op mDIV =
+ (sp) -> { // DIV
+ mStack[sp - 1] = mStack[sp - 1] / mStack[sp];
+ return sp - 1;
+ };
+ Op mMOD =
+ (sp) -> { // MOD
+ mStack[sp - 1] = mStack[sp - 1] % mStack[sp];
+ return sp - 1;
+ };
+ Op mSHL =
+ (sp) -> { // SHL
+ mStack[sp - 1] = mStack[sp - 1] << mStack[sp];
+ return sp - 1;
+ };
+ Op mSHR =
+ (sp) -> { // SHR
+ mStack[sp - 1] = mStack[sp - 1] >> mStack[sp];
+ return sp - 1;
+ };
+ Op mUSHR =
+ (sp) -> { // USHR
+ mStack[sp - 1] = mStack[sp - 1] >>> mStack[sp];
+ return sp - 1;
+ };
+ Op mOR =
+ (sp) -> { // OR
+ mStack[sp - 1] = mStack[sp - 1] | mStack[sp];
+ return sp - 1;
+ };
+ Op mAND =
+ (sp) -> { // AND
+ mStack[sp - 1] = mStack[sp - 1] & mStack[sp];
+ return sp - 1;
+ };
+ Op mXOR =
+ (sp) -> { // XOR
+ mStack[sp - 1] = mStack[sp - 1] ^ mStack[sp];
+ return sp - 1;
+ };
+ Op mCOPY_SIGN =
+ (sp) -> { // COPY_SIGN
+ mStack[sp - 1] = (mStack[sp - 1] ^ (mStack[sp] >> 31)) - (mStack[sp] >> 31);
+ return sp - 1;
+ };
+ Op mMIN =
+ (sp) -> { // MIN
+ mStack[sp - 1] = Math.min(mStack[sp - 1], mStack[sp]);
+ return sp - 1;
+ };
+ Op mMAX =
+ (sp) -> { // MAX
+ mStack[sp - 1] = Math.max(mStack[sp - 1], mStack[sp]);
+ return sp - 1;
+ };
+ Op mNEG =
+ (sp) -> { // NEG
+ mStack[sp] = -mStack[sp];
+ return sp;
+ };
+ Op mABS =
+ (sp) -> { // ABS
+ mStack[sp] = Math.abs(mStack[sp]);
+ return sp;
+ };
+ Op mINCR =
+ (sp) -> { // INCR
+ mStack[sp] = mStack[sp] + 1;
+ return sp;
+ };
+ Op mDECR =
+ (sp) -> { // DECR
+ mStack[sp] = mStack[sp] - 1;
+ return sp;
+ };
+ Op mNOT =
+ (sp) -> { // NOT
+ mStack[sp] = ~mStack[sp];
+ return sp;
+ };
+ Op mSIGN =
+ (sp) -> { // SIGN
+ mStack[sp] = (mStack[sp] >> 31) | (-mStack[sp] >>> 31);
+ return sp;
+ };
+ Op mCLAMP =
+ (sp) -> { // CLAMP
+ mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
+ return sp - 2;
+ };
+ Op mTERNARY_CONDITIONAL =
+ (sp) -> { // TERNARY_CONDITIONAL
+ mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2];
+ return sp - 2;
+ };
+ Op mMAD =
+ (sp) -> { // MAD
+ mStack[sp - 2] = mStack[sp] + mStack[sp - 1] * mStack[sp - 2];
+ return sp - 2;
+ };
+ Op mFIRST_VAR =
+ (sp) -> { // FIRST_VAR
+ mStack[sp] = mVar[0];
+ return sp;
+ };
+ Op mSECOND_VAR =
+ (sp) -> { // SECOND_VAR
+ mStack[sp] = mVar[1];
+ return sp;
+ };
+ Op mTHIRD_VAR =
+ (sp) -> { // THIRD_VAR
+ mStack[sp] = mVar[2];
+ return sp;
+ };
+
+ Op[] ops = {
null,
- (sp) -> { // ADD
- mStack[sp - 1] = mStack[sp - 1] + mStack[sp];
- return sp - 1;
- },
- (sp) -> { // SUB
- mStack[sp - 1] = mStack[sp - 1] - mStack[sp];
- return sp - 1;
- },
- (sp) -> { // MUL
- mStack[sp - 1] = mStack[sp - 1] * mStack[sp];
- return sp - 1;
- },
- (sp) -> { // DIV
- mStack[sp - 1] = mStack[sp - 1] / mStack[sp];
- return sp - 1;
- },
- (sp) -> { // MOD
- mStack[sp - 1] = mStack[sp - 1] % mStack[sp];
- return sp - 1;
- },
- (sp) -> { // SHL shift left
- mStack[sp - 1] = mStack[sp - 1] << mStack[sp];
- return sp - 1;
- },
- (sp) -> { // SHR shift right
- mStack[sp - 1] = mStack[sp - 1] >> mStack[sp];
- return sp - 1;
- },
- (sp) -> { // USHR unsigned shift right
- mStack[sp - 1] = mStack[sp - 1] >>> mStack[sp];
- return sp - 1;
- },
- (sp) -> { // OR operator
- mStack[sp - 1] = mStack[sp - 1] | mStack[sp];
- return sp - 1;
- },
- (sp) -> { // AND operator
- mStack[sp - 1] = mStack[sp - 1] & mStack[sp];
- return sp - 1;
- },
- (sp) -> { // XOR xor operator
- mStack[sp - 1] = mStack[sp - 1] ^ mStack[sp];
- return sp - 1;
- },
- (sp) -> { // COPY_SIGN copy the sing of (using bit magic)
- mStack[sp - 1] = (mStack[sp - 1] ^ (mStack[sp] >> 31)) - (mStack[sp] >> 31);
- return sp - 1;
- },
- (sp) -> { // MIN
- mStack[sp - 1] = Math.min(mStack[sp - 1], mStack[sp]);
- return sp - 1;
- },
- (sp) -> { // MAX
- mStack[sp - 1] = Math.max(mStack[sp - 1], mStack[sp]);
- return sp - 1;
- },
- (sp) -> { // NEG
- mStack[sp] = -mStack[sp];
- return sp;
- },
- (sp) -> { // ABS
- mStack[sp] = Math.abs(mStack[sp]);
- return sp;
- },
- (sp) -> { // INCR increment
- mStack[sp] = mStack[sp] + 1;
- return sp;
- },
- (sp) -> { // DECR decrement
- mStack[sp] = mStack[sp] - 1;
- return sp;
- },
- (sp) -> { // NOT Bit invert
- mStack[sp] = ~mStack[sp];
- return sp;
- },
- (sp) -> { // SIGN x<0 = -1,x==0 = 0 , x>0 = 1
- mStack[sp] = (mStack[sp] >> 31) | (-mStack[sp] >>> 31);
- return sp;
- },
- (sp) -> { // CLAMP(min,max, val)
- mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
- return sp - 2;
- },
- (sp) -> { // Ternary conditional
- mStack[sp - 2] = (mStack[sp] > 0) ? mStack[sp - 1] : mStack[sp - 2];
- return sp - 2;
- },
- (sp) -> { // MAD
- mStack[sp - 2] = mStack[sp] + mStack[sp - 1] * mStack[sp - 2];
- return sp - 2;
- },
- (sp) -> { // first var =
- mStack[sp] = mVar[0];
- return sp;
- },
- (sp) -> { // second var y?
- mStack[sp] = mVar[1];
- return sp;
- },
- (sp) -> { // 3rd var z?
- mStack[sp] = mVar[2];
- return sp;
- },
- };
+ mADD,
+ mSUB,
+ mMUL,
+ mDIV,
+ mMOD,
+ mSHL,
+ mSHR,
+ mUSHR,
+ mOR,
+ mAND,
+ mXOR,
+ mCOPY_SIGN,
+ mMIN,
+ mMAX,
+ mNEG,
+ mABS,
+ mINCR,
+ mDECR,
+ mNOT,
+ mSIGN,
+ mCLAMP,
+ mTERNARY_CONDITIONAL,
+ mMAD,
+ mFIRST_VAR,
+ mSECOND_VAR,
+ mTHIRD_VAR,
+ };
+
+ mOps = ops;
+ }
static {
int k = 0;
@@ -283,6 +345,7 @@
* @param f the numerical value of the function + offset
* @return the math name of the function
*/
+ @Nullable
public static String toMathName(int f) {
int id = f - OFFSET;
return sNames.get(id);
@@ -292,11 +355,12 @@
* Convert an expression encoded as an array of ints int to a string
*
* @param opMask bits that are operators
- * @param exp rpn sequence of values and operators
+ * @param exp rpn sequence of values and operators
* @param labels String that represent the variable names
* @return
*/
- public static String toString(int opMask, int[] exp, String[] labels) {
+ @NonNull
+ public static String toString(int opMask, @NonNull int[] exp, String[] labels) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < exp.length; i++) {
int v = exp[i];
@@ -324,10 +388,11 @@
* Convert an expression encoded as an array of ints int ot a string
*
* @param opMask bit mask of operators vs commands
- * @param exp rpn sequence of values and operators
+ * @param exp rpn sequence of values and operators
* @return string representation of the expression
*/
- public static String toString(int opMask, int[] exp) {
+ @NonNull
+ public static String toString(int opMask, @NonNull int[] exp) {
StringBuilder s = new StringBuilder();
s.append(Integer.toBinaryString(opMask));
s.append(" : ");
@@ -355,13 +420,15 @@
* This creates an infix string expression
*
* @param opMask The bits that are operators
- * @param exp the array of expressions
+ * @param exp the array of expressions
* @return infix string
*/
- public static String toStringInfix(int opMask, int[] exp) {
+ @NonNull
+ public static String toStringInfix(int opMask, @NonNull int[] exp) {
return toString(opMask, exp, exp.length - 1);
}
+ @NonNull
static String toString(int mask, int[] exp, int sp) {
if (((1 << sp) & mask) != 0) {
int id = exp[sp] - OFFSET;
@@ -412,34 +479,34 @@
}
static final int[] NO_OF_OPS = {
- -1, // no op
- 2,
- 2,
- 2,
- 2,
- 2, // + - * / %
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2, // <<, >> , >>> , | , &, ^, min max
- 1,
- 1,
- 1,
- 1,
- 1,
- 1, // neg, abs, ++, -- , not , sign
- 3,
- 3,
- 3, // clamp, ifElse, mad,
- 0,
- 0,
- 0 // mad, ?:,
- // a[0],a[1],a[2]
+ -1, // no op
+ 2,
+ 2,
+ 2,
+ 2,
+ 2, // + - * / %
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2, // <<, >> , >>> , | , &, ^, min max
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1, // neg, abs, ++, -- , not , sign
+ 3,
+ 3,
+ 3, // clamp, ifElse, mad,
+ 0,
+ 0,
+ 0 // mad, ?:,
+ // a[0],a[1],a[2]
};
/**
@@ -456,7 +523,7 @@
* is it an id or operation
*
* @param opMask the bits that mark elements as an operation
- * @param i the bit to check
+ * @param i the bit to check
* @return true if the bit is 1
*/
public static boolean isOperation(int opMask, int i) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java
index ab7576e..92127c1 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringSerializer.java
@@ -15,9 +15,14 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
/** Utility serializer maintaining an indent buffer */
public class StringSerializer {
- StringBuffer mBuffer = new StringBuffer();
+ @NonNull StringBuffer mBuffer = new StringBuffer();
+
+ @NonNull
String mIndentBuffer = " ";
/**
@@ -26,7 +31,7 @@
* @param indent the indentation level to use
* @param content content to append
*/
- public void append(int indent, String content) {
+ public void append(int indent, @Nullable String content) {
String indentation = mIndentBuffer.substring(0, indent);
mBuffer.append(indentation);
mBuffer.append(indentation);
@@ -44,6 +49,7 @@
*
* @return string representation
*/
+ @NonNull
@Override
public String toString() {
return mBuffer.toString();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java
index f2ccb40..a95a175 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
+import android.annotation.NonNull;
+
import java.util.Arrays;
/** Utilities for string manipulation */
@@ -30,6 +32,7 @@
* @param post character to pad width 0 = no pad typically ' ' or '0'
* @return
*/
+ @NonNull
public static String floatToString(
float value, int beforeDecimalPoint, int afterDecimalPoint, char pre, char post) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/CubicEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/CubicEasing.java
index 60a59cf..1343345 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/CubicEasing.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/CubicEasing.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities.easing;
+import android.annotation.NonNull;
+
class CubicEasing extends Easing {
float mX1 = 0f;
float mY1 = 0f;
@@ -62,7 +64,7 @@
mType = type;
}
- void setup(float[] values) {
+ void setup(@NonNull float[] values) {
setup(values[0], values[1], values[2], values[3]);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java
index a29b8af..ebb22b6 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities.easing;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
/** Support Animation of the FloatExpression */
public class FloatAnimation extends Easing {
float[] mSpec;
@@ -31,6 +34,7 @@
// private float mScale = 1;
float mOffset = 0;
+ @NonNull
@Override
public String toString() {
@@ -74,7 +78,7 @@
* @return
*/
public static float[] packToFloatArray(
- float duration, int type, float[] spec, float initialValue, float wrap) {
+ float duration, int type, @Nullable float[] spec, float initialValue, float wrap) {
int count = 0;
if (!Float.isNaN(initialValue)) {
@@ -129,6 +133,90 @@
}
/**
+ * Useful to debug the packed form of an animation string
+ *
+ * @param description
+ * @return
+ */
+ public static String unpackAnimationToString(float[] description) {
+ float[] mSpec = description;
+ float mDuration = (mSpec.length == 0) ? 1 : mSpec[0];
+ int len = 0;
+ int type = 0;
+ float wrapValue = Float.NaN;
+ float initialValue = Float.NaN;
+ if (mSpec.length > 1) {
+ int num_type = Float.floatToRawIntBits(mSpec[1]);
+ type = num_type & 0xFF;
+ boolean wrap = ((num_type >> 8) & 0x1) > 0;
+ boolean init = ((num_type >> 8) & 0x2) > 0;
+ len = (num_type >> 16) & 0xFFFF;
+ int off = 2 + len;
+ if (init) {
+ initialValue = mSpec[off++];
+ }
+ if (wrap) {
+ wrapValue = mSpec[off];
+ }
+ }
+ float[] params = description;
+ int offset = 2;
+
+ String typeStr = "";
+ switch (type) {
+ case CUBIC_STANDARD:
+ typeStr = "CUBIC_STANDARD";
+ break;
+ case CUBIC_ACCELERATE:
+ typeStr = "CUBIC_ACCELERATE";
+ break;
+ case CUBIC_DECELERATE:
+ typeStr = "CUBIC_DECELERATE";
+ break;
+ case CUBIC_LINEAR:
+ typeStr = "CUBIC_LINEAR";
+ break;
+ case CUBIC_ANTICIPATE:
+ typeStr = "CUBIC_ANTICIPATE";
+ break;
+ case CUBIC_OVERSHOOT:
+ typeStr = "CUBIC_OVERSHOOT";
+
+ break;
+ case CUBIC_CUSTOM:
+ typeStr = "CUBIC_CUSTOM (";
+ typeStr += params[offset + 0] + " ";
+ typeStr += params[offset + 1] + " ";
+ typeStr += params[offset + 2] + " ";
+ typeStr += params[offset + 3] + " )";
+ break;
+ case EASE_OUT_BOUNCE:
+ typeStr = "EASE_OUT_BOUNCE";
+
+ break;
+ case EASE_OUT_ELASTIC:
+ typeStr = "EASE_OUT_ELASTIC";
+ break;
+ case SPLINE_CUSTOM:
+ typeStr = "SPLINE_CUSTOM (";
+ for (int i = offset; i < offset + len; i++) {
+ typeStr += params[i] + " ";
+ }
+ typeStr += ")";
+ break;
+ }
+
+ String str = mDuration + " " + typeStr;
+ if (!Float.isNaN(initialValue)) {
+ str += " init =" + initialValue;
+ }
+ if (!Float.isNaN(wrapValue)) {
+ str += " wrap =" + wrapValue;
+ }
+ return str;
+ }
+
+ /**
* Create an animation based on a float encoding of the animation
*
* @param description
@@ -208,21 +296,43 @@
setScaleOffset();
}
+ private static float wrap(float wrap, float value) {
+ value = value % wrap;
+ if (value < 0) {
+ value += wrap;
+ }
+ return value;
+ }
+
+ float wrapDistance(float wrap, float from, float to) {
+ float delta = (to - from) % 360;
+ if (delta < -wrap / 2) {
+ delta += wrap;
+ } else if (delta > wrap / 2) {
+ delta -= wrap;
+ }
+ return delta;
+ }
+
/**
* Set the target value to interpolate to
*
* @param value
*/
public void setTargetValue(float value) {
- if (Float.isNaN(mWrap)) {
- mTargetValue = value;
- } else {
- if (Math.abs((value % mWrap) + mWrap - mInitialValue)
- < Math.abs((value % mWrap) - mInitialValue)) {
- mTargetValue = (value % mWrap) + mWrap;
+ mTargetValue = value;
+ if (!Float.isNaN(mWrap)) {
+ mInitialValue = wrap(mWrap, mInitialValue);
+ mTargetValue = wrap(mWrap, mTargetValue);
+ if (Float.isNaN(mInitialValue)) {
+ mInitialValue = mTargetValue;
+ }
- } else {
- mTargetValue = value % mWrap;
+ float dist = wrapDistance(mWrap, mInitialValue, mTargetValue);
+ if ((dist > 0) && (mTargetValue < mInitialValue)) {
+ mTargetValue += mWrap;
+ } else if ((dist < 0) && (mTargetValue > mInitialValue)) {
+ mTargetValue -= mWrap;
}
}
setScaleOffset();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java
index 75a6032..90b65bf 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java
@@ -15,10 +15,12 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities.easing;
+import android.annotation.NonNull;
+
/** Provides and interface to create easing functions */
public class GeneralEasing extends Easing {
float[] mEasingData = new float[0];
- Easing mEasingCurve = new CubicEasing(CUBIC_STANDARD);
+ @NonNull Easing mEasingCurve = new CubicEasing(CUBIC_STANDARD);
/**
* Set the curve based on the float encoding of it
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java
index 9355cac..f540e70 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities.easing;
+import android.annotation.NonNull;
+
import java.util.Arrays;
/** This performs a spline interpolation in multiple dimensions */
@@ -32,7 +34,7 @@
* @param time the point along the curve
* @param y the parameter at those points
*/
- public MonotonicCurveFit(double[] time, double[][] y) {
+ public MonotonicCurveFit(@NonNull double[] time, @NonNull double[][] y) {
final int n = time.length;
final int dim = y[0].length;
mSlopeTemp = new double[dim];
@@ -331,7 +333,8 @@
}
/** This builds a monotonic spline to be used as a wave function */
- public static MonotonicCurveFit buildWave(String configString) {
+ @NonNull
+ public static MonotonicCurveFit buildWave(@NonNull String configString) {
// done this way for efficiency
String str = configString;
double[] values = new double[str.length() / 2];
@@ -350,7 +353,8 @@
return buildWave(Arrays.copyOf(values, count));
}
- private static MonotonicCurveFit buildWave(double[] values) {
+ @NonNull
+ private static MonotonicCurveFit buildWave(@NonNull double[] values) {
int length = values.length * 3 - 2;
int len = values.length - 1;
double gap = 1.0 / len;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java
index b459689..c7be3ca 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities.easing;
+import android.annotation.NonNull;
+
/**
* This class translates a series of floating point values into a continuous curve for use in an
* easing function including quantize functions it is used with the "spline(0,0.3,0.3,0.5,...0.9,1)"
@@ -28,6 +30,7 @@
mCurveFit = genSpline(params, offset, len);
}
+ @NonNull
private static MonotonicCurveFit genSpline(float[] values, int off, int arrayLen) {
int length = arrayLen * 3 - 2;
int len = arrayLen - 1;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
new file mode 100644
index 0000000..3e24372
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.utilities.touch;
+
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class VelocityEasing {
+ private float mStartPos = 0;
+ private float mStartV = 0;
+ private float mEndPos = 0;
+ private float mDuration = 0;
+
+ private Stage[] mStage = {new Stage(1), new Stage(2), new Stage(3)};
+ private int mNumberOfStages = 0;
+ private Easing mEasing;
+ private double mEasingAdapterDistance = 0;
+ private double mEasingAdapterA = 0;
+ private double mEasingAdapterB = 0;
+ private boolean mOneDimension = true;
+ private float mTotalEasingDuration = 0;
+
+ public float getDuration() {
+ if (mEasing != null) {
+ return mTotalEasingDuration;
+ }
+ return mDuration;
+ }
+
+ public float getV(float t) {
+ if (mEasing == null) {
+ for (int i = 0; i < mNumberOfStages; i++) {
+ if (mStage[i].mEndTime > t) {
+ return mStage[i].getVel(t);
+ }
+ }
+ return 0f;
+ }
+ int lastStages = mNumberOfStages - 1;
+ for (int i = 0; i < lastStages; i++) {
+ if (mStage[i].mEndTime > t) {
+ return mStage[i].getVel(t);
+ }
+ }
+ return (float) getEasingDiff((t - mStage[lastStages].mStartTime));
+ }
+
+ public float getPos(float t) {
+ if (mEasing == null) {
+ for (int i = 0; i < mNumberOfStages; i++) {
+ if (mStage[i].mEndTime > t) {
+ return mStage[i].getPos(t);
+ }
+ }
+ return mEndPos;
+ }
+ int lastStages = mNumberOfStages - 1;
+ for (int i = 0; i < lastStages; i++) {
+ if (mStage[i].mEndTime > t) {
+ return mStage[i].getPos(t);
+ }
+ }
+ var ret = (float) getEasing((t - mStage[lastStages].mStartTime));
+ ret += mStage[lastStages].mStartPos;
+ return ret;
+ }
+
+ public String toString() {
+ var s = " ";
+ for (int i = 0; i < mNumberOfStages; i++) {
+ Stage stage = mStage[i];
+ s += " $i $stage";
+ }
+ return s;
+ }
+
+ public void config(
+ float currentPos,
+ float destination,
+ float currentVelocity,
+ float maxTime,
+ float maxAcceleration,
+ float maxVelocity,
+ Easing easing) {
+ float pos = currentPos;
+ float velocity = currentVelocity;
+ if (pos == destination) {
+ pos += 1f;
+ }
+ mStartPos = pos;
+ mEndPos = destination;
+ if (easing != null) {
+ this.mEasing = easing.clone();
+ }
+ float dir = Math.signum(destination - pos);
+ float maxV = maxVelocity * dir;
+ float maxA = maxAcceleration * dir;
+ if (velocity == 0.0) {
+ velocity = 0.0001f * dir;
+ }
+ mStartV = velocity;
+ if (!rampDown(pos, destination, velocity, maxTime)) {
+ if (!(mOneDimension
+ && cruseThenRampDown(pos, destination, velocity, maxTime, maxA, maxV))) {
+ if (!rampUpRampDown(pos, destination, velocity, maxA, maxV, maxTime)) {
+ rampUpCruseRampDown(pos, destination, velocity, maxA, maxV, maxTime);
+ }
+ }
+ }
+ if (mOneDimension) {
+ configureEasingAdapter();
+ }
+ }
+
+ private boolean rampDown(
+ float currentPos, float destination, float currentVelocity, float maxTime) {
+ float timeToDestination = 2 * ((destination - currentPos) / currentVelocity);
+ if (timeToDestination > 0 && timeToDestination <= maxTime) { // hit the brakes
+ mNumberOfStages = 1;
+ mStage[0].setUp(currentVelocity, currentPos, 0f, 0f, destination, timeToDestination);
+ mDuration = timeToDestination;
+ return true;
+ }
+ return false;
+ }
+
+ private boolean cruseThenRampDown(
+ float currentPos,
+ float destination,
+ float currentVelocity,
+ float maxTime,
+ float maxA,
+ float maxV) {
+ float timeToBreak = currentVelocity / maxA;
+ float brakeDist = currentVelocity * timeToBreak / 2;
+ float cruseDist = destination - currentPos - brakeDist;
+ float cruseTime = cruseDist / currentVelocity;
+ float totalTime = cruseTime + timeToBreak;
+ if (totalTime > 0 && totalTime < maxTime) {
+ mNumberOfStages = 2;
+ mStage[0].setUp(currentVelocity, currentPos, 0f, currentVelocity, cruseDist, cruseTime);
+ mStage[1].setUp(
+ currentVelocity,
+ currentPos + cruseDist,
+ cruseTime,
+ 0f,
+ destination,
+ cruseTime + timeToBreak);
+ mDuration = cruseTime + timeToBreak;
+ return true;
+ }
+ return false;
+ }
+
+ private boolean rampUpRampDown(
+ float currentPos,
+ float destination,
+ float currentVelocity,
+ float maxA,
+ float maxVelocity,
+ float maxTime) {
+ float peak_v =
+ Math.signum(maxA)
+ * (float)
+ Math.sqrt(
+ (maxA * (destination - currentPos)
+ + currentVelocity * currentVelocity / 2));
+ if (maxVelocity / peak_v > 1) {
+ float t1 = (peak_v - currentVelocity) / maxA;
+ float d1 = (peak_v + currentVelocity) * t1 / 2 + currentPos;
+ float t2 = peak_v / maxA;
+ mNumberOfStages = 2;
+ mStage[0].setUp(currentVelocity, currentPos, 0f, peak_v, d1, t1);
+ mStage[1].setUp(peak_v, d1, t1, 0f, destination, t2 + t1);
+ mDuration = t2 + t1;
+ if (mDuration > maxTime) {
+ return false;
+ }
+ if (mDuration < maxTime / 2) {
+ t1 = mDuration / 2;
+ t2 = t1;
+ peak_v = (2 * (destination - currentPos) / t1 - currentVelocity) / 2;
+ d1 = (peak_v + currentVelocity) * t1 / 2 + currentPos;
+ mNumberOfStages = 2;
+ mStage[0].setUp(currentVelocity, currentPos, 0f, peak_v, d1, t1);
+ mStage[1].setUp(peak_v, d1, t1, 0f, destination, t2 + t1);
+ mDuration = t2 + t1;
+ if (mDuration > maxTime) {
+ System.out.println(" fail ");
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void rampUpCruseRampDown(
+ float currentPos,
+ float destination,
+ float currentVelocity,
+ float maxA,
+ float maxV,
+ float maxTime) {
+ float t1 = maxTime / 3;
+ float t2 = t1 * 2;
+ float distance = destination - currentPos;
+ float dt2 = t2 - t1;
+ float dt3 = maxTime - t2;
+ float v1 = (2 * distance - currentVelocity * t1) / (t1 + 2 * dt2 + dt3);
+ mDuration = maxTime;
+ float d1 = (currentVelocity + v1) * t1 / 2;
+ float d2 = (v1 + v1) * (t2 - t1) / 2;
+ mNumberOfStages = 3;
+ float acc = (v1 - currentVelocity) / t1;
+ float dec = v1 / dt3;
+ mStage[0].setUp(currentVelocity, currentPos, 0f, v1, currentPos + d1, t1);
+ mStage[1].setUp(v1, currentPos + d1, t1, v1, currentPos + d1 + d2, t2);
+ mStage[2].setUp(v1, currentPos + d1 + d2, t2, 0f, destination, maxTime);
+ mDuration = maxTime;
+ }
+
+ double getEasing(double t) {
+ double gx = t * t * mEasingAdapterA + t * mEasingAdapterB;
+ if (gx > 1) {
+ return mEasingAdapterDistance;
+ } else {
+ return mEasing.get(gx) * mEasingAdapterDistance;
+ }
+ }
+
+ private double getEasingDiff(double t) {
+ double gx = t * t * mEasingAdapterA + t * mEasingAdapterB;
+ if (gx > 1) {
+ return 0.0;
+ } else {
+ return mEasing.getDiff(gx)
+ * mEasingAdapterDistance
+ * (t * mEasingAdapterA + mEasingAdapterB);
+ }
+ }
+
+ protected void configureEasingAdapter() {
+ if (mEasing == null) {
+ return;
+ }
+ int last = mNumberOfStages - 1;
+ float initialVelocity = mStage[last].mStartV;
+ float distance = mStage[last].mEndPos - mStage[last].mStartPos;
+ float duration = mStage[last].mEndTime - mStage[last].mStartTime;
+ double baseVel = mEasing.getDiff(0.0);
+ mEasingAdapterB = initialVelocity / (baseVel * distance);
+ mEasingAdapterA = 1 - mEasingAdapterB;
+ mEasingAdapterDistance = distance;
+ double easingDuration =
+ (Math.sqrt(4 * mEasingAdapterA + mEasingAdapterB * mEasingAdapterB)
+ - mEasingAdapterB)
+ / (2 * mEasingAdapterA);
+ mTotalEasingDuration = (float) (easingDuration + mStage[last].mStartTime);
+ }
+
+ interface Easing {
+ double get(double t);
+
+ double getDiff(double t);
+
+ Easing clone();
+ }
+
+ class Stage {
+ private float mStartV = 0;
+ private float mStartPos = 0;
+ private float mStartTime = 0;
+ private float mEndV = 0;
+ private float mEndPos = 0;
+ private float mEndTime = 0;
+ private float mDeltaV = 0;
+ private float mDeltaT = 0;
+ final int mStage;
+
+ Stage(int n) {
+ mStage = n;
+ }
+
+ void setUp(
+ float startV,
+ float startPos,
+ float startTime,
+ float endV,
+ float endPos,
+ float endTime) {
+ this.mStartV = startV;
+ this.mStartPos = startPos;
+ this.mStartTime = startTime;
+ this.mEndV = endV;
+ this.mEndTime = endTime;
+ this.mEndPos = endPos;
+ mDeltaV = this.mEndV - this.mStartV;
+ mDeltaT = this.mEndTime - this.mStartTime;
+ }
+
+ float getPos(float t) {
+ float dt = t - mStartTime;
+ float pt = dt / mDeltaT;
+ float v = mStartV + mDeltaV * pt;
+ return dt * (mStartV + v) / 2 + mStartPos;
+ }
+
+ float getVel(float t) {
+ float dt = t - mStartTime;
+ float pt = dt / (mEndTime - mStartTime);
+ return mStartV + mDeltaV * pt;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java
index 57a8042..3fba8ac 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.BYTE;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -47,23 +49,26 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mValue);
}
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
public String deepToString(String indent) {
return toString();
}
+ @NonNull
@Override
public String toString() {
return "BooleanConstant[" + mId + "] = " + mValue + "";
}
+ @NonNull
public static String name() {
return "OrigamiBoolean";
}
@@ -79,20 +84,20 @@
* @param id
* @param value
*/
- public static void apply(WireBuffer buffer, int id, boolean value) {
+ public static void apply(@NonNull WireBuffer buffer, int id, boolean value) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeBoolean(value);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
boolean value = buffer.readBoolean();
operations.add(new BooleanConstant(id, value));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, "BooleanConstant")
.description("A boolean and its associated id")
.field(DocumentedOperation.INT, "id", "id of Int")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java
index 3ef9db9..79f2a8d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -37,25 +39,28 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mValue);
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.loadInteger(mId, mValue);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return toString();
}
+ @NonNull
@Override
public String toString() {
return "IntegerConstant[" + mId + "] = " + mValue + "";
}
+ @NonNull
public static String name() {
return "IntegerConstant";
}
@@ -71,20 +76,20 @@
* @param textId
* @param value
*/
- public static void apply(WireBuffer buffer, int textId, int value) {
+ public static void apply(@NonNull WireBuffer buffer, int textId, int value) {
buffer.start(Operations.DATA_INT);
buffer.writeInt(textId);
buffer.writeInt(value);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int value = buffer.readInt();
operations.add(new IntegerConstant(id, value));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", id(), "IntegerConstant")
.description("A integer and its associated id")
.field(DocumentedOperation.INT, "id", "id of Int")
diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java
index 6d51d19..01672b4 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java
@@ -17,6 +17,8 @@
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.LONG;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -47,7 +49,7 @@
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mValue);
}
@@ -56,11 +58,13 @@
context.putObject(mId, this);
}
+ @NonNull
@Override
public String deepToString(String indent) {
return toString();
}
+ @NonNull
@Override
public String toString() {
return "LongConstant[" + mId + "] = " + mValue + "";
@@ -73,20 +77,20 @@
* @param id
* @param value
*/
- public static void apply(WireBuffer buffer, int id, long value) {
+ public static void apply(@NonNull WireBuffer buffer, int id, long value) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeLong(value);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
long value = buffer.readLong();
operations.add(new LongConstant(id, value));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, "LongConstant")
.description("A boolean and its associated id")
.field(DocumentedOperation.INT, "id", "id of Int")
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
index 906282c..aaee9c5 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
@@ -112,6 +112,16 @@
}
/**
+ * Gets a array of Names of the named variables of a specific type defined in the doc.
+ *
+ * @param type the type of variable NamedVariable.COLOR_TYPE, STRING_TYPE, etc
+ * @return array of name or null
+ */
+ public String[] getNamedVariables(int type) {
+ return mDocument.getNamedVariables(type);
+ }
+
+ /**
* Return a component associated with id
*
* @param id the component id
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
index 06bf4cd..cc74b11 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
@@ -21,11 +21,14 @@
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
+import android.view.HapticFeedbackConstants;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
import com.android.internal.widget.remotecompose.player.platform.RemoteComposeCanvas;
@@ -57,11 +60,7 @@
* @param debugFlags 1 to set debug on
*/
public void setDebug(int debugFlags) {
- if (debugFlags == 1) {
- mInner.setDebug(true);
- } else {
- mInner.setDebug(false);
- }
+ mInner.setDebug(debugFlags);
}
public RemoteComposeDocument getDocument() {
@@ -82,6 +81,14 @@
mInner.setDocument(null);
}
mapColors();
+ mInner.setHapticEngine(
+ new CoreDocument.HapticEngine() {
+
+ @Override
+ public void haptic(int type) {
+ provideHapticFeedback(type);
+ }
+ });
}
/**
@@ -259,13 +266,40 @@
/**
* This returns a list of colors that have names in the Document.
*
- * @return
+ * @return the names of named Strings or null
*/
public String[] getNamedColors() {
return mInner.getNamedColors();
}
/**
+ * This returns a list of floats that have names in the Document.
+ *
+ * @return return the names of named floats in the document
+ */
+ public String[] getNamedFloats() {
+ return mInner.getNamedVariables(NamedVariable.FLOAT_TYPE);
+ }
+
+ /**
+ * This returns a list of string name that have names in the Document.
+ *
+ * @return the name of named string (not the string itself)
+ */
+ public String[] getNamedStrings() {
+ return mInner.getNamedVariables(NamedVariable.STRING_TYPE);
+ }
+
+ /**
+ * This returns a list of images that have names in the Document.
+ *
+ * @return
+ */
+ public String[] getNamedImages() {
+ return mInner.getNamedVariables(NamedVariable.IMAGE_TYPE);
+ }
+
+ /**
* This sets a color based on its name. Overriding the color set in the document.
*
* @param colorName Name of the color
@@ -481,4 +515,32 @@
return color;
}
}
+
+ private static int[] sHapticTable = {
+ HapticFeedbackConstants.NO_HAPTICS,
+ HapticFeedbackConstants.LONG_PRESS,
+ HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.KEYBOARD_TAP,
+ HapticFeedbackConstants.CLOCK_TICK,
+ HapticFeedbackConstants.CONTEXT_CLICK,
+ HapticFeedbackConstants.KEYBOARD_PRESS,
+ HapticFeedbackConstants.KEYBOARD_RELEASE,
+ HapticFeedbackConstants.VIRTUAL_KEY_RELEASE,
+ HapticFeedbackConstants.TEXT_HANDLE_MOVE,
+ HapticFeedbackConstants.GESTURE_START,
+ HapticFeedbackConstants.GESTURE_END,
+ HapticFeedbackConstants.CONFIRM,
+ HapticFeedbackConstants.REJECT,
+ HapticFeedbackConstants.TOGGLE_ON,
+ HapticFeedbackConstants.TOGGLE_OFF,
+ HapticFeedbackConstants.GESTURE_THRESHOLD_ACTIVATE,
+ HapticFeedbackConstants.GESTURE_THRESHOLD_DEACTIVATE,
+ HapticFeedbackConstants.DRAG_START,
+ HapticFeedbackConstants.SEGMENT_TICK,
+ HapticFeedbackConstants.SEGMENT_FREQUENT_TICK,
+ };
+
+ private void provideHapticFeedback(int type) {
+ performHapticFeedback(sHapticTable[type % sHapticTable.length]);
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
index f59a0d3..0b650a9 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
@@ -26,6 +26,8 @@
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.RenderEffect;
+import android.graphics.RenderNode;
import android.graphics.RuntimeShader;
import android.graphics.Shader;
import android.graphics.SweepGradient;
@@ -51,6 +53,8 @@
List<Paint> mPaintList = new ArrayList<>();
Canvas mCanvas;
Rect mTmpRect = new Rect(); // use in calculation of bounds
+ RenderNode mNode = null;
+ Canvas mPreviousCanvas = null;
public AndroidPaintContext(RemoteContext context, Canvas canvas) {
super(context);
@@ -122,6 +126,53 @@
}
@Override
+ public void startGraphicsLayer(int w, int h) {
+ mNode = new RenderNode("layer");
+ mNode.setPosition(0, 0, w, h);
+ mPreviousCanvas = mCanvas;
+ mCanvas = mNode.beginRecording();
+ }
+
+ @Override
+ public void setGraphicsLayer(
+ float scaleX,
+ float scaleY,
+ float rotationX,
+ float rotationY,
+ float rotationZ,
+ float shadowElevation,
+ float transformOriginX,
+ float transformOriginY,
+ float alpha,
+ int renderEffectId) {
+ if (mNode == null) {
+ return;
+ }
+ mNode.setScaleX(scaleX);
+ mNode.setScaleY(scaleY);
+ mNode.setRotationX(rotationX);
+ mNode.setRotationY(rotationY);
+ mNode.setRotationZ(rotationZ);
+ mNode.setPivotX(transformOriginX * mNode.getWidth());
+ mNode.setPivotY(transformOriginY * mNode.getHeight());
+ mNode.setAlpha(alpha);
+ if (renderEffectId == 1) {
+
+ RenderEffect effect = RenderEffect.createBlurEffect(8f, 8f, Shader.TileMode.CLAMP);
+ mNode.setRenderEffect(effect);
+ }
+ }
+
+ @Override
+ public void endGraphicsLayer() {
+ mNode.endRecording();
+ mCanvas = mPreviousCanvas;
+ mCanvas.drawRenderNode(mNode);
+ // node.discardDisplayList();
+ mNode = null;
+ }
+
+ @Override
public void translate(float translateX, float translateY) {
mCanvas.translate(translateX, translateY);
}
@@ -241,6 +292,8 @@
if (start != 0) {
textToPaint = textToPaint.substring(start);
}
+ } else if (end > textToPaint.length()) {
+ textToPaint = textToPaint.substring(start);
} else {
textToPaint = textToPaint.substring(start, end);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java
index f9b22a2..f28e85a 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java
@@ -18,6 +18,7 @@
import android.graphics.Bitmap;
import android.graphics.Path;
import android.graphics.PathIterator;
+import android.util.Log;
import com.android.internal.widget.remotecompose.core.Platform;
import com.android.internal.widget.remotecompose.core.operations.PathData;
@@ -27,6 +28,8 @@
/** Services that are needed to be provided by the platform during encoding. */
public class AndroidPlatformServices implements Platform {
+ private static final String LOG_TAG = "RemoteCompose";
+
@Override
public byte[] imageToByteArray(Object image) {
if (image instanceof Bitmap) {
@@ -67,6 +70,24 @@
return null;
}
+ @Override
+ public void log(LogCategory category, String message) {
+ switch (category) {
+ case DEBUG:
+ Log.d(LOG_TAG, message);
+ break;
+ case INFO:
+ Log.i(LOG_TAG, message);
+ break;
+ case WARN:
+ Log.w(LOG_TAG, message);
+ break;
+ default:
+ Log.e(LOG_TAG, message);
+ break;
+ }
+ }
+
private float[] androidPathToFloatArray(Path path) {
PathIterator i = path.getPathIterator();
int estimatedSize = 0;
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
index e7c0cc8..7a7edba 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
@@ -20,6 +20,7 @@
import android.graphics.Canvas;
import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.TouchListener;
import com.android.internal.widget.remotecompose.core.VariableSupport;
import com.android.internal.widget.remotecompose.core.operations.FloatExpression;
import com.android.internal.widget.remotecompose.core.operations.ShaderData;
@@ -143,9 +144,9 @@
}
@Override
- public void runNamedAction(int id) {
+ public void runNamedAction(int id, Object value) {
String text = getText(id);
- mDocument.runNamedAction(text);
+ mDocument.runNamedAction(text, value);
}
/**
@@ -200,6 +201,11 @@
}
@Override
+ public void overrideFloat(int id, float value) {
+ mRemoteComposeState.overrideFloat(id, value);
+ }
+
+ @Override
public void loadInteger(int id, int value) {
mRemoteComposeState.updateInteger(id, value);
}
@@ -268,6 +274,11 @@
return (ShaderData) mRemoteComposeState.getFromId(id);
}
+ @Override
+ public void addTouchListener(TouchListener touchExpression) {
+ mDocument.addTouchListener(touchExpression);
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////////
// Click handling
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -285,4 +296,8 @@
String metadata = (String) mRemoteComposeState.getFromId(metadataId);
mDocument.addClickArea(id, contentDescription, left, top, right, bottom, metadata);
}
+
+ public void hapticEffect(int type) {
+ mDocument.haptic(type);
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
index 7de6988..b54ed8a 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
@@ -21,6 +21,7 @@
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.VelocityTracker;
import android.view.View;
import android.widget.FrameLayout;
@@ -38,7 +39,7 @@
RemoteComposeDocument mDocument = null;
int mTheme = Theme.LIGHT;
boolean mInActionDown = false;
- boolean mDebug = false;
+ int mDebug = 0;
boolean mHasClickAreas = false;
Point mActionDownPoint = new Point(0, 0);
AndroidRemoteContext mARContext = new AndroidRemoteContext();
@@ -65,14 +66,14 @@
}
}
- public void setDebug(boolean value) {
+ public void setDebug(int value) {
if (mDebug != value) {
mDebug = value;
if (USE_VIEW_AREA_CLICK) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof ClickAreaView) {
- ((ClickAreaView) child).setDebug(mDebug);
+ ((ClickAreaView) child).setDebug(mDebug == 1);
}
}
}
@@ -107,7 +108,7 @@
ClickAreaView viewArea =
new ClickAreaView(
getContext(),
- mDebug,
+ mDebug == 1,
area.getId(),
area.getContentDescription(),
area.getMetadata());
@@ -128,6 +129,10 @@
}
}
+ public void setHapticEngine(CoreDocument.HapticEngine engine) {
+ mDocument.getDocument().setHapticEngine(engine);
+ }
+
@Override
public void onViewDetachedFromWindow(View view) {
removeAllViews();
@@ -138,6 +143,16 @@
}
/**
+ * Gets a array of Names of the named variables of a specific type defined in the loaded doc.
+ *
+ * @param type the type of variable NamedVariable.COLOR_TYPE, STRING_TYPE, etc
+ * @return array of name or null
+ */
+ public String[] getNamedVariables(int type) {
+ return mDocument.getNamedVariables(type);
+ }
+
+ /**
* set the color associated with this name.
*
* @param colorName Name of color typically "android.xxx"
@@ -198,7 +213,12 @@
this.mTheme = theme;
}
+ private VelocityTracker mVelocityTracker = null;
+
public boolean onTouchEvent(MotionEvent event) {
+ int index = event.getActionIndex();
+ int action = event.getActionMasked();
+ int pointerId = event.getPointerId(index);
if (USE_VIEW_AREA_CLICK && mHasClickAreas) {
return super.onTouchEvent(event);
}
@@ -207,15 +227,51 @@
mActionDownPoint.x = (int) event.getX();
mActionDownPoint.y = (int) event.getY();
mInActionDown = true;
+ CoreDocument doc = mDocument.getDocument();
+ if (doc.hasTouchListener()) {
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ } else {
+ mVelocityTracker.clear();
+ }
+ mVelocityTracker.addMovement(event);
+ doc.touchDown(mARContext, event.getX(), event.getY());
+ }
return true;
+
case MotionEvent.ACTION_CANCEL:
mInActionDown = false;
+ doc = mDocument.getDocument();
+ if (doc.hasTouchListener()) {
+ mVelocityTracker.computeCurrentVelocity(1000);
+ float dx = mVelocityTracker.getXVelocity(pointerId);
+ float dy = mVelocityTracker.getYVelocity(pointerId);
+ doc.touchCancel(mARContext, event.getX(), event.getY(), dx, dy);
+ }
return true;
case MotionEvent.ACTION_UP:
mInActionDown = false;
performClick();
+ doc = mDocument.getDocument();
+ if (doc.hasTouchListener()) {
+ mVelocityTracker.computeCurrentVelocity(1000);
+ float dx = mVelocityTracker.getXVelocity(pointerId);
+ float dy = mVelocityTracker.getYVelocity(pointerId);
+ doc.touchUp(mARContext, event.getX(), event.getY(), dx, dy);
+ }
return true;
+
case MotionEvent.ACTION_MOVE:
+ if (mInActionDown) {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.addMovement(event);
+ doc = mDocument.getDocument();
+ boolean repaint = doc.touchDrag(mARContext, event.getX(), event.getY());
+ if (repaint) {
+ invalidate();
+ }
+ }
+ }
}
return false;
}
@@ -292,7 +348,7 @@
mARContext.mWidth = getWidth();
mARContext.mHeight = getHeight();
mDocument.paint(mARContext, mTheme);
- if (mDebug) {
+ if (mDebug == 1) {
mCount++;
if (System.nanoTime() - mTime > 1000000000L) {
System.out.println(" count " + mCount + " fps");
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index df87a69..56292c3 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -2403,6 +2403,11 @@
}
}
+static void nativeEnableDebugLogCallPoints(JNIEnv* env, jclass clazz, jlong transactionObj) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+ transaction->enableDebugLogCallPoints();
+}
+
static const JNINativeMethod sSurfaceControlMethods[] = {
// clang-format off
{"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J",
@@ -2649,6 +2654,7 @@
{"nativeNotifyShutdown", "()V",
(void*)nativeNotifyShutdown },
{"nativeSetLuts", "(JJ[F[I[I[I[I)V", (void*)nativeSetLuts },
+ {"nativeEnableDebugLogCallPoints", "(J)V", (void*)nativeEnableDebugLogCallPoints },
// clang-format on
};
diff --git a/core/res/Android.bp b/core/res/Android.bp
index f6ca821..66c2e12 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -171,6 +171,7 @@
"android.security.flags-aconfig",
"com.android.hardware.input.input-aconfig",
"aconfig_trade_in_mode_flags",
+ "ranging_aconfig_flags",
],
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0479318..a6bf915 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2412,6 +2412,16 @@
android:label="@string/permlab_nearby_wifi_devices"
android:protectionLevel="dangerous" />
+ <!-- Required to be able to range to devices using generic ranging module.
+ @FlaggedApi("android.permission.flags.ranging_permission_enabled")
+ <p>Protection level: dangerous -->
+ <permission android:name="android.permission.RANGING"
+ android:permissionGroup="android.permission-group.UNDEFINED"
+ android:description="@string/permdesc_ranging"
+ android:label="@string/permlab_ranging"
+ android:protectionLevel="dangerous"
+ android:featureFlag="android.permission.flags.ranging_permission_enabled"/>
+
<!-- @SystemApi @TestApi Allows an application to suspend other apps, which will prevent the
user from using them until they are unsuspended.
@hide
@@ -2622,13 +2632,22 @@
<!-- @SystemApi Allows access to perform vendor effects in the vibrator.
<p>Protection level: signature
- @FlaggedApi("android.os.vibrator.vendor_vibration_effects")
+ @FlaggedApi(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
@hide
-->
<permission android:name="android.permission.VIBRATE_VENDOR_EFFECTS"
android:protectionLevel="signature|privileged"
android:featureFlag="android.os.vibrator.vendor_vibration_effects" />
+ <!-- @SystemApi Allows access to start a vendor vibration session.
+ <p>Protection level: signature
+ @FlaggedApi(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ @hide
+ -->
+ <permission android:name="android.permission.START_VIBRATION_SESSIONS"
+ android:protectionLevel="signature|privileged"
+ android:featureFlag="android.os.vibrator.vendor_vibration_effects" />
+
<!-- @SystemApi Allows access to the vibrator state.
<p>Protection level: signature
@hide
diff --git a/core/res/res/drawable/ic_zen_mode_type_unknown.xml b/core/res/res/drawable/ic_zen_mode_icon_star_badge.xml
similarity index 100%
rename from core/res/res/drawable/ic_zen_mode_type_unknown.xml
rename to core/res/res/drawable/ic_zen_mode_icon_star_badge.xml
diff --git a/core/res/res/layout/input_method_switch_item_new.xml b/core/res/res/layout/input_method_switch_item_new.xml
index f8710cc..7b241af 100644
--- a/core/res/res/layout/input_method_switch_item_new.xml
+++ b/core/res/res/layout/input_method_switch_item_new.xml
@@ -18,18 +18,20 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_item"
android:layout_width="match_parent"
- android:layout_height="72dp"
+ android:layout_height="wrap_content"
+ android:minHeight="72dp"
android:background="@drawable/input_method_switch_item_background"
android:gravity="center_vertical"
android:orientation="horizontal"
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="8dp"
android:paddingStart="20dp"
- android:paddingEnd="24dp">
+ android:paddingEnd="24dp"
+ android:paddingVertical="8dp">
<LinearLayout
android:layout_width="0dp"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start|center_vertical"
android:orientation="vertical">
@@ -39,11 +41,26 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
+ android:marqueeRepeatLimit="1"
android:singleLine="true"
android:fontFamily="google-sans-text"
android:textColor="@color/input_method_switch_on_item"
android:textAppearance="?attr/textAppearanceListItem"/>
+ <TextView
+ android:id="@+id/text2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dp"
+ android:ellipsize="marquee"
+ android:marqueeRepeatLimit="1"
+ android:singleLine="true"
+ android:fontFamily="google-sans-text"
+ android:textColor="?attr/materialColorOnSurfaceVariant"
+ android:textAppearance="?attr/textAppearanceListItemSecondary"
+ android:textAllCaps="true"
+ android:visibility="gone"/>
+
</LinearLayout>
<ImageView
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index ccc584a..1e3f402 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Naweek"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Geleentheid"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Slaap"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Moenie Steur Nie (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Bestuur deur <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aan"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Af"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> tot <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Enige kalender"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> demp sekere klanke"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Daar is \'n interne probleem met jou toestel en dit sal dalk onstabiel wees totdat jy \'n fabriekterugstelling doen."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Stuur en ontvang boodskappe sonder ’n selfoon- of wi-fi-netwerk"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Maak Boodskappe oop"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe dit werk"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Skakel “Kies netwerk outomaties” aan"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Skakel “Kies netwerk outomaties” in Instellings aan sodat jou foon ’n netwerk kan vind wat met satelliet werk"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Skakel aan"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Gaan terug"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Hangend …"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Stel Vingerafdrukslot weer op"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan nie meer herken word nie."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan nie meer herken word nie."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 22dc49c..91b4ef0 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"የሳምንት እረፍት ቀናት"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ክስተት"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"መተኛት"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"አትረብሽ (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"በ<xliff:g id="APP_NAME">%1$s</xliff:g> የሚተዳደር"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"በርቷል"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ጠፍቷል"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"፣ "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"ከ<xliff:g id="START">%1$s</xliff:g> እስከ <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ማንኛውም ቀን መቁጠሪያ"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> አንዳንድ ድምጾችን እየዘጋ ነው"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"መሣሪያዎ ላይ የውስጣዊ ችግር አለ፣ የፋብሪካ ውሂብ ዳግም እስኪያስጀምሩት ድረስ ላይረጋጋ ይችላል።"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"ያለ ሞባይል ወይም የWi-Fi አውታረ መረብ መልዕክቶችን ይላኩ እና ይቀበሉ"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"መልዕክቶች ይክፈቱ"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"እንዴት እንደሚሠራ"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"«አውታረ መረብን በራስ-ሰር ምረጥ» የሚለውን ያብሩ"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ስልክዎ ከሳተላይት ጋር የሚሠራ አውታረ መረብ እንዲያገኝ በቅንብሮች ውስጥ «አውታረ መረብን በራስ-ሰር ምረጥ» የሚለውን ያብሩ"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"አብራ"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ወደኋላ ተመለስ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"በመጠባበቅ ላይ..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ከእንግዲህ መለየት አይችልም።"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ከእንግዲህ መለየት አይችሉም።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 1aaad07..6e5dcd3 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1942,13 +1942,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"نهاية الأسبوع"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"حدث"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"النوم"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"عدم الإزعاج (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"تحت إدارة \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"مفعَّل"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"غير مفعَّل"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"من <xliff:g id="START">%1$s</xliff:g> إلى <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"من <xliff:g id="START">%1$s</xliff:g> إلى <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"أي تقويم"</string>
<string name="muted_by" msgid="91464083490094950">"يعمل <xliff:g id="THIRD_PARTY">%1$s</xliff:g> على كتم بعض الأصوات."</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"حدثت مشكلة داخلية في جهازك، وقد لا يستقر وضعه حتى إجراء إعادة الضبط على الإعدادات الأصلية."</string>
@@ -2430,15 +2430,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"يمكنك إرسال الرسائل واستلامها بدون شبكة الجوّال أو شبكة Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"فتح تطبيق \"الرسائل\""</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"طريقة العمل"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"تفعيل الإعداد \"اختيار الشبكة تلقائيًا\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"يمكنك تفعيل الإعداد \"اختيار الشبكة تلقائيًا\" من خلال \"الإعدادات\" لكي يتمكّن هاتفك من العثور على شبكة تعمل مع القمر الصناعي"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"تفعيل"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"رجوع"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"بانتظار الإزالة من الأرشيف…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"إعادة إعداد ميزة \"فتح الجهاز ببصمة الإصبع\""</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT">%s</xliff:g>\"."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" و\"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\"."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 74d8ed6..1af7810 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"সপ্তাহ অন্ত"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"অনুষ্ঠান"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"নিদ্ৰাৰত"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"অসুবিধা নিদিব (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ পৰিচালনা কৰা"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"অন আছে"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"অফ আছে"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>ৰ পৰা <xliff:g id="END">%2$s</xliff:g>লৈ"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"যিকোনো কেলেণ্ডাৰ"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>এ কিছুমান ধ্বনি মিউট কৰি আছে"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"আপোনাৰ ডিভাইচত এটা আভ্যন্তৰীণ সমস্যা আছে আৰু আপুনি ফেক্টৰী ডেটা ৰিছেট নকৰালৈকে ই সুস্থিৰভাৱে কাম নকৰিব পাৰে।"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"আপুনি কোনো ম’বাইল বা ৱাই-ফাই নেটৱৰ্ক নোহোৱাকৈ বাৰ্তা পঠিয়াওক আৰু লাভ কৰক"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খোলক"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ই কেনেকৈ কাম কৰে"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"স্বয়ংক্ৰিয়ভাৱে নেটৱৰ্ক বাছনি কৰক\" অন কৰক"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ছেটিঙত \"স্বয়ংক্ৰিয়ভাৱে নেটৱৰ্ক বাছনি কৰক\" অন কৰক, যাতে আপোনাৰ ফ’নটোৱে উপগ্ৰহৰ সৈতে কাম কৰা এটা নেটৱৰ্ক বিচাৰি পাব পাৰে"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"অন কৰক"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"উভতি যাওক"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"বিবেচনাধীন হৈ আছে..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ফিংগাৰপ্ৰিণ্ট আনলক পুনৰ ছেট আপ কৰক"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি।"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি।"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 22e86df..1ba96fe 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Həftə sonu"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Tədbir"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Yuxu vaxtı"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Narahat Etməyin (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> idarə edir"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aktiv"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Deaktiv"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"İstənilən təqvim"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> bəzi səsləri səssiz rejimə salır"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Cihazınızın daxili problemi var və istehsalçı sıfırlanması olmayana qədər qeyri-stabil ola bilər."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Mobil və ya Wi-Fi şəbəkəsi olmadan mesajlar göndərin və qəbul edin"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajı açın"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Haqqında"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"Avtomatik şəbəkə seçin\" funksiyasını aktiv edin"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Telefonunuzun peyklə işləyən şəbəkə tapa bilməsi üçün Ayarlarda \"Avtomatik şəbəkə seçin\" funksiyasını aktiv edin"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktiv edin"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Geri qayıdın"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Gözləmədə..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmaqla Kilidaçmanı yenidən ayarlayın"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artıq tanınmır."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artıq tanınmır."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index b9f909f..4c78d30 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Događaj"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spavanje"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ne uznemiravaj (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Upravlja: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Uključeno"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Isključeno"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bilo koji kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvuke"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Došlo je do internog problema u vezi sa uređajem i možda će biti nestabilan dok ne obavite resetovanje na fabrička podešavanja."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Šaljite i primajte poruke bez mobilne ili WiFi mreže"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Princip rada"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Uključite opciju Automatski izaberi mrežu"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Uključite opciju Automatski izaberi mrežu u Podešavanjima da bi telefon mogao da pronađe mrežu koja radi sa satelitom"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Uključi"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Nazad"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo podesite otključavanje otiskom prsta"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> više ne može da se prepozna."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više ne mogu da se prepoznaju."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index b252094..549ec78 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1940,13 +1940,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Выхадныя"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Падзея"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Рэжым сну"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Не турбаваць (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Пад кіраваннем праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Уключана"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Выключана"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Любы каляндар"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> выключае некаторыя гукі"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"На вашай прыладзе ўзнікла ўнутраная праблема, і яна можа працаваць нестабільна, пакуль вы не зробіце скід да заводскіх налад."</string>
@@ -2428,15 +2428,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Вы можаце адпраўляць і атрымліваць паведамленні, калі падключэнне да мабільнай сеткі або сеткі Wi-Fi адсутнічае"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Адкрыць Паведамленні"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як гэта працуе"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Уключыце параметр \"Выбіраць сетку аўтаматычна\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Уключыце ў наладах параметр \"Выбіраць сетку аўтаматычна\", каб ваш тэлефон мог знаходзіць сетку, якая працуе са спадарожнікам"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Уключыць"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Назад"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"У чаканні..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Наладзіць разблакіроўку адбіткам пальца паўторна"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больш не можа быць распазнаны."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больш не могуць быць распазнаны."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index e5a08bb..40aae51 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Събота и неделя"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Събитие"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Време за сън"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Не безпокойте (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Управлява се от <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Вкл."</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Изкл."</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"От <xliff:g id="START">%1$s</xliff:g> до <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Всички календари"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> заглушава някои звуци"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Възникна вътрешен проблем с устройството ви. То може да е нестабилно, докато не възстановите фабричните настройки."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Изпращайте и получавайте съобщения без мобилна или Wi-Fi мрежа"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Отваряне на Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Начин на работа"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Включване на „Автоматично избиране на мрежа“"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Включете „Автоматично избиране на мрежа“ в „Настройки“, за да може телефонът ви да намери мрежа, която работи със сателит"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Включване"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Назад"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Изчаква..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Повторно настройване на „Отключване с отпечатък“"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> вече не може да се разпознае."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> вече не могат да бъдат разпознати."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index df8a908..32077d8 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"সপ্তাহান্ত"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ইভেন্ট"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ঘুমানোর সময়"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"বিরক্ত করবে না (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ম্যানেজ করে"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"চালু আছে"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"বন্ধ আছে"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> থেকে <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"যেকোনও ক্যালেন্ডার"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> কিছু সাউন্ডকে মিউট করে দিচ্ছে"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"আপনার ডিভাইসে একটি অভ্যন্তরীন সমস্যা হয়েছে, এবং আপনি যতক্ষণ না পর্যন্ত এটিকে ফ্যাক্টরি ডেটা রিসেট করছেন ততক্ষণ এটি ঠিকভাবে কাজ নাও করতে পারে৷"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"কোনও মেবাইল বা ওয়াই-ফাই নেটওয়ার্ক ছাড়াই মেসেজ পাঠান ও রিসিভ করুন"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খুলুন"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"এটি কীভাবে কাজ করে"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"নেটওয়ার্ক অটোমেটিক বেছে নিন\" বিকল্প চালু করুন"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"সেটিংসে \"নেটওয়ার্ক অটোমেটিক বেছে নিন\" বিকল্পটি চালু করলে আপনার ফোন এমন নেটওয়ার্ক বেছে নিতে পারবে যা স্যাটেলাইটের মাধ্যমে কাজ করে"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"চালু করুন"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ফিরে যান"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"বাকি আছে…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"\'ফিঙ্গারপ্রিন্ট আনলক\' আবার সেট-আপ করুন"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> আর শনাক্ত করা যাবে না।"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আর শনাক্ত করা যাবে না।"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 35e30ba..266dee2 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -76,7 +76,7 @@
<string name="CLIRPermanent" msgid="166443681876381118">"Ne možete promijeniti postavke ID-a pozivaoca."</string>
<string name="auto_data_switch_title" msgid="3286350716870518297">"Prijenos podataka usmjeravanjem na <xliff:g id="CARRIERDISPLAY">%s</xliff:g>"</string>
<string name="auto_data_switch_content" msgid="803557715007110959">"Ove postavke možete uvijek promijeniti u Postavkama"</string>
- <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Nema usluge prijenosa podataka na mobilnoj mreži"</string>
+ <string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Nema usluge prenosa podataka na mobilnoj mreži"</string>
<string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"Hitni pozivi su nedostupni"</string>
<string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Nema usluge govornih poziva"</string>
<string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"Nema glasovne usluge ili hitnih poziva"</string>
@@ -89,7 +89,7 @@
<string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Prosljeđivanje poziva"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Način rada za hitni povratni poziv"</string>
- <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status prijenosa podataka na mobilnoj mreži"</string>
+ <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status prenosa podataka na mobilnoj mreži"</string>
<string name="notification_channel_sms" msgid="1243384981025535724">"SMS poruke"</string>
<string name="notification_channel_voice_mail" msgid="8457433203106654172">"Poruke govorne pošte"</string>
<string name="notification_channel_wfc" msgid="9048240466765169038">"Pozivanje putem WiFi-ja"</string>
@@ -310,7 +310,7 @@
<string name="notification_channel_display" msgid="6905032605735615090">"Ekran"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> troši bateriju"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"Broj aplikacija koje troše bateriju: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
- <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
+ <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Dodirnite za detalje o potrošnji baterije i prenosa podataka"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="8974401416068943888">"Siguran način rada"</string>
<string name="android_system_label" msgid="5974767339591067210">"Sistem Android"</string>
@@ -812,7 +812,7 @@
<string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"pristupi DRM certifikatima"</string>
<string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Dozvoljava aplikaciji da obezbijedi i koristi DRM certifikate. Nije potrebno za obične aplikacije."</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"prijem statusa prebacivanja preko Android prebacivanja"</string>
- <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Dozvoljava aplikaciji prijem informacija o trenutnim prijenosima putem funkcije Android Beam"</string>
+ <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Dozvoljava aplikaciji prijem informacija o trenutnim prenosima putem funkcije Android Beam"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"ukloni DRM certifikate"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Dozvoljava aplikaciji da ukloni DRM certifikate. Nije potrebno za obične aplikacije."</string>
<string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"poveži sa servisom za poruke operatera"</string>
@@ -1163,7 +1163,7 @@
<string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# dan}one{# dan}few{# dana}other{# dana}}"</string>
<string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# godina}one{# godina}few{# godine}other{# godina}}"</string>
<string name="VideoView_error_title" msgid="5750686717225068016">"Problem sa prikazom video sadržaja"</string>
- <string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Prijenos ovog video sadržaja ne može se izvršiti na ovom uređaju."</string>
+ <string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Prenos ovog video sadržaja ne može se izvršiti na ovom uređaju."</string>
<string name="VideoView_error_text_unknown" msgid="7658683339707607138">"Greška prilikom reproduciranja video sadržaja."</string>
<string name="VideoView_error_button" msgid="5138809446603764272">"Uredu"</string>
<string name="relative_time" msgid="8572030016028033243">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -1478,7 +1478,7 @@
<string name="ext_media_missing_message" msgid="4408988706227922909">"Ponovo umetnite uređaj"</string>
<string name="ext_media_move_specific_title" msgid="8492118544775964250">"Premješta se <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_move_title" msgid="2682741525619033637">"Premještanje podataka"</string>
- <string name="ext_media_move_success_title" msgid="4901763082647316767">"Prijenos sadržaja je završen"</string>
+ <string name="ext_media_move_success_title" msgid="4901763082647316767">"Prenos sadržaja je završen"</string>
<string name="ext_media_move_success_message" msgid="9159542002276982979">"Sadržaj je premješten na uređaj <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_move_failure_title" msgid="3184577479181333665">"Nije moguće premjestiti sadržaj"</string>
<string name="ext_media_move_failure_message" msgid="4197306718121869335">"Pokušajte ponovo premjestiti sadržaj"</string>
@@ -1620,9 +1620,9 @@
<string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB disk"</string>
<string name="storage_usb" msgid="2391213347883616886">"USB pohrana"</string>
<string name="extract_edit_menu_button" msgid="63954536535863040">"Uredi"</string>
- <string name="data_usage_warning_title" msgid="9034893717078325845">"Upozorenje o prijenosu podataka"</string>
+ <string name="data_usage_warning_title" msgid="9034893717078325845">"Upozorenje o prenosu podataka"</string>
<string name="data_usage_warning_body" msgid="1669325367188029454">"Potrošili ste <xliff:g id="APP">%s</xliff:g> podataka"</string>
- <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Dostignuto ograničenje za prijenos podataka"</string>
+ <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Dostignuto ograničenje za prenos podataka"</string>
<string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Dostignut limit WiFi podataka"</string>
<string name="data_usage_limit_body" msgid="3567699582000085710">"Prijenos podataka je pauziran do kraja ciklusa"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="101888478915677895">"Pređen limit mobilnih podataka"</string>
@@ -1915,7 +1915,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"Uredu"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnost u pozadini, određene vizuelne efekte i funkcije te neke mrežne veze."</string>
<string name="battery_saver_description" msgid="8518809702138617167">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnost u pozadini, određene vizuelne efekte i funkcije te neke mrežne veze."</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Radi smanjenja prijenosa podataka, Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupati podacima, ali će to činiti rjeđe. Naprimjer, to može značiti da se slike ne prikazuju dok ih ne dodirnete."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Radi smanjenja prenosa podataka, Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupati podacima, ali će to činiti rjeđe. Naprimjer, to može značiti da se slike ne prikazuju dok ih ne dodirnete."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Uključiti Uštedu podataka?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string>
<string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Traje jednu minutu (do {formattedTime})}one{Traje # min (do {formattedTime})}few{Traje # min (do {formattedTime})}other{Traje # min (do {formattedTime})}}"</string>
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Događaj"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spavanje"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ne ometaj (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Upravlja <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Uključeno"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Isključeno"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bilo koji kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvukove"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Postoji problem u vašem uređaju i može biti nestabilan dok ga ne vratite na fabričke postavke."</string>
@@ -2028,9 +2028,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na uređaju Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na tabletu."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na telefonu."</string>
- <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Aplikacija traži dodatna odobrenja, ali se ona ne mogu dati u sesiji prijenosa. Prvo dajte odobrenje na Android TV uređaju."</string>
- <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Aplikacija traži dodatna odobrenja, ali se ona ne mogu dati u sesiji prijenosa. Prvo dajte odobrenje na tabletu."</string>
- <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Aplikacija traži dodatna odobrenja, ali se ona ne mogu dati u sesiji prijenosa. Prvo dodajte odobrenje na telefonu."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Aplikacija traži dodatna odobrenja, ali se ona ne mogu dati u sesiji prenosa. Prvo dajte odobrenje na Android TV uređaju."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Aplikacija traži dodatna odobrenja, ali se ona ne mogu dati u sesiji prenosa. Prvo dajte odobrenje na tabletu."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Aplikacija traži dodatna odobrenja, ali se ona ne mogu dati u sesiji prenosa. Prvo dodajte odobrenje na telefonu."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ova aplikacija zahtijeva dodatnu sigurnost. Umjesto toga pokušajte na uređaju Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ova aplikacija zahtijeva dodatnu sigurnost. Umjesto toga pokušajte na tabletu."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ova aplikacija zahtijeva dodatnu sigurnost. Umjesto toga pokušajte na telefonu."</string>
@@ -2373,8 +2373,8 @@
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Provjerite aktivne aplikacije"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nije moguće pristupiti kameri telefona s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nije moguće pristupiti kameri tableta s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
- <string name="vdm_secure_window" msgid="161700398158812314">"Ovom ne možete pristupiti tokom prijenosa. Umjesto toga pokušajte na telefonu."</string>
- <string name="vdm_pip_blocked" msgid="4036107522497281397">"Tokom prijenosa nije moguće gledati sliku u slici"</string>
+ <string name="vdm_secure_window" msgid="161700398158812314">"Ovom ne možete pristupiti tokom prenosa. Umjesto toga pokušajte na telefonu."</string>
+ <string name="vdm_pip_blocked" msgid="4036107522497281397">"Tokom prenosa nije moguće gledati sliku u slici"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistemski zadano"</string>
<string name="default_card_name" msgid="9198284935962911468">"KARTICA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
<string name="permlab_companionProfileWatch" msgid="2457738382085872542">"Odobrenje za profil pratećeg sata da upravlja satovima"</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Šaljite i primajte poruke bez mobilne ili WiFi mreže"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvorite Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako ovo funkcionira"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Uključite \"Automatski odaberi mrežu\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Uključite \"Automatski odaberi mrežu\" u Postavkama da telefon može pronaći mrežu koja funkcionira sa satelitom"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Uključi"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Nazad"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo postavite otključavanje otiskom prsta"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> se više ne može prepoznati."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se više ne mogu prepoznati."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 7c817b9..691126b 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1929,7 +1929,7 @@
<string name="zen_mode_until_next_day" msgid="1403042784161725038">"Finalitza: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_until" msgid="2250286190237669079">"Finalitza: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_alarm" msgid="7046911727540499275">"Finalitza: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (propera alarma)"</string>
- <string name="zen_mode_forever" msgid="740585666364912448">"Fins que no el desactivis"</string>
+ <string name="zen_mode_forever" msgid="740585666364912448">"Fins que no ho desactivis"</string>
<string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Fins que desactivis el mode No molestis"</string>
<string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="8009920446193610996">"Replega"</string>
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Cap de setmana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Esdeveniment"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Mentre dormo"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"No molestis (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gestionat per <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activat"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desactivat"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualsevol calendari"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> està silenciant alguns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"S\'ha produït un error intern al dispositiu i és possible que funcioni de manera inestable fins que restableixis les dades de fàbrica."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envia i rep missatges sense una xarxa mòbil o Wi‑Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Obre Missatges"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Com funciona"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Activa l\'opció Selecciona la xarxa automàticament"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Activa l\'opció Selecciona la xarxa automàticament a Configuració perquè el telèfon pugui trobar una xarxa que funcioni per satèl·lit"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activa"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Torna"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendent..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Torna a configurar Desbloqueig amb empremta digital"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ja no es pot reconèixer."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ja no es poden reconèixer."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index a9766bf..f6ee489 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1940,13 +1940,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Víkend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Událost"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spánek"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Nerušit (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Spravováno aplikací <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Zapnuto"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Vypnuto"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"V libovolném kalendáři"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vypíná určité zvuky"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"V zařízení došlo k internímu problému. Dokud neprovedete obnovení továrních dat, může být nestabilní."</string>
@@ -2428,15 +2428,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Odesílejte a přijímejte zprávy bez mobilní sítě nebo Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otevřít Zprávy"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to funguje"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Zapněte Vybírat síť automaticky"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Zapněte v Nastavení možnost Vybírat síť automaticky, aby telefon našel síť, která používá satelit"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Zapnout"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Zpět"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Čeká na vyřízení…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Opětovné nastavení odemknutí otiskem prstu"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> se nedaří rozpoznat."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se nedaří rozpoznat."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 58e9e6f..a861e3a 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -563,7 +563,7 @@
<string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"Adgang til skjulte profiler"</string>
<string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"Giver appen adgang til skjulte profiler."</string>
<string name="permlab_setWallpaperHints" msgid="1153485176642032714">"ændre størrelsen på din baggrund"</string>
- <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Tillader, at appen giver tips til systembaggrundens størrelse."</string>
+ <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Tillader, at appen giver tip til systembaggrundens størrelse."</string>
<string name="permlab_setTimeZone" msgid="7922618798611542432">"angive tidszone"</string>
<string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Tillader, at appen kan ændre tidszonen på din tablet."</string>
<string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Tillader, at appen kan ændre tidszonen på din Android TV-enhed."</string>
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Begivenhed"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sover"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Forstyr ikke (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Administreres af <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Til"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Fra"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> til <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Alle kalendere"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> slår nogle lyde fra"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Der er et internt problem med enheden, og den vil muligvis være ustabil, indtil du gendanner fabriksdataene."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send og modtag beskeder uden et mobil- eller Wi-Fi-netværk"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Åbn Beskeder"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Sådan fungerer det"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Aktivér \"Vælg netværk automatisk\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Aktivér \"Vælg netværk automatisk\" under Indstillinger, så din telefon kan finde et netværk, der fungerer sammen med satellit"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivér"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Gå tilbage"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Afventer…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer fingeroplåsning igen"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan ikke længere genkendes."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan ikke længere genkendes."</string>
@@ -2454,7 +2498,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="3523799286376321137">"Sms"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="2051507523525651067">"Musik"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="3571770335653387606">"Kalender"</string>
- <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"Lommeregner"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6753209559716091507">"Lommeregner"</string>
<string name="keyboard_shortcut_group_applications_maps" msgid="7950000659522589471">"Kort"</string>
<string name="keyboard_shortcut_group_applications" msgid="3010389163951364798">"Apps"</string>
<string name="fingerprint_loe_notification_msg" msgid="3927447270148854546">"Dine fingeraftryk kan ikke længere genkendes. Konfigurer fingeroplåsning igen."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index fa2c9cf..58c4c5e 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Wochenende"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Termin"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Schlafen"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Bitte nicht stören (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Verwaltet von <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"An"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Aus"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> bis <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Alle Kalender"</string>
<string name="muted_by" msgid="91464083490094950">"Einige Töne werden von <xliff:g id="THIRD_PARTY">%1$s</xliff:g> stummgeschaltet"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Es liegt ein internes Problem mit deinem Gerät vor. Möglicherweise verhält es sich instabil, bis du es auf die Werkseinstellungen zurücksetzt."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Du kannst ohne Mobilgerät oder WLAN Nachrichten senden und empfangen"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages öffnen"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"So funktionierts"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"„Netz automatisch auswählen“ aktivieren"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Aktiviere in den Einstellungen die Option „Netz automatisch auswählen“, damit dein Smartphone ein Netzwerk finden kann, das mit dem Satelliten funktioniert"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivieren"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Zurück"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ausstehend…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Entsperrung per Fingerabdruck neu einrichten"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> wird nicht mehr erkannt."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werden nicht mehr erkannt."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 9e360e8..3a32c52 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Σαββατοκύριακο"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Συμβάν"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Ύπνος"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Μην ενοχλείτε (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Διαχείριση από <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ενεργός"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Ανενεργός"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> έως <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Οποιοδήποτε ημερολόγιο"</string>
<string name="muted_by" msgid="91464083490094950">"Το τρίτο μέρος <xliff:g id="THIRD_PARTY">%1$s</xliff:g> θέτει ορισμένους ήχους σε σίγαση"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας και ενδέχεται να είναι ασταθής μέχρι την επαναφορά των εργοστασιακών ρυθμίσεων."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Αποστολή και λήψη μηνυμάτων χωρίς δίκτυο κινητής τηλεφωνίας ή Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Άνοιγμα Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Πώς λειτουργεί"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Ενεργοποίηση της λειτουργίας Αυτόματη επιλογή δικτύου"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Ενεργοποιήστε τη λειτουργία Αυτόματη επιλογή δικτύου στις Ρυθμίσεις, ώστε το τηλέφωνό σας να μπορεί να βρει ένα δίκτυο που λειτουργεί με δορυφόρο"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ενεργοποίηση"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Επιστροφή"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Σε εκκρεμότητα…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με δακτυλικό αποτύπωμα"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και του <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index d36ccf5..84cc409 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sleeping"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Do Not Disturb (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Managed by <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> to <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send and receive messages without a mobile or Wi-Fi network"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Turn on \'Automatically select network\'"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Turn on \'Automatically select network\' in Settings so your phone can find a network that works with satellite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Turn on"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Go back"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised."</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 3fac736..4225004 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1938,6 +1938,7 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sleeping"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Do Not Disturb (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Managed by <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
@@ -2430,6 +2431,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Turn on"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Go back"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string>
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satellite SOS is now available"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"You can message emergency services if there\'s no mobile or Wi-Fi network. Google Messages must be your default messaging app."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satellite SOS isn\'t supported"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satellite SOS isn\'t supported on this device"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satellite SOS isn\'t set up"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Make sure you\'re connected to the internet and try setup again"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satellite SOS isn\'t available"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satellite SOS isn\'t available in this country or region"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS not set up"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"To message by satellite, set Google Messages as your default messaging app"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS isn\'t available"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"To check if satellite SOS is available in this country or region, turn on location settings"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satellite messaging available"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"You can message by satellite if there\'s no mobile or Wi-Fi network. Google Messages must be your default messaging app."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satellite messaging not supported"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satellite messaging isn\'t supported on this device"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satellite messaging not set up"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Make sure you\'re connected to the internet and try setup again"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satellite messaging not available"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satellite messaging isn\'t available in this country or region"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satellite messaging not set up"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"To message by satellite, set Google Messages as your default messaging app"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satellite messaging not available"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"To check if satellite messaging is available in this country or region, turn on location settings"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognized."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognized."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 48f0e1a..a80d067 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sleeping"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Do Not Disturb (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Managed by <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> to <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send and receive messages without a mobile or Wi-Fi network"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Turn on \'Automatically select network\'"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Turn on \'Automatically select network\' in Settings so your phone can find a network that works with satellite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Turn on"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Go back"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 190e8ab..c123499 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sleeping"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Do Not Disturb (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Managed by <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> to <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send and receive messages without a mobile or Wi-Fi network"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Turn on \'Automatically select network\'"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Turn on \'Automatically select network\' in Settings so your phone can find a network that works with satellite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Turn on"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Go back"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index a48f5fa..26b4dfa 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1938,14 +1938,14 @@
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Noche, en la semana"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
- <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormir"</string>
+ <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sueño"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"No interrumpir (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Administradas por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activado"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desactivado"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Cualquier calendario"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> silencia algunos sonidos"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Existe un problema interno con el dispositivo, de modo que el dispositivo puede estar inestable hasta que restablezcas la configuración de fábrica."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envía y recibe mensajes sin una red móvil ni Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensajes"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Activa \"Seleccionar red de forma automática\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Activa \"Seleccionar red de forma automática\" en la configuración para que tu teléfono pueda encontrar una red que funcione con satélite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activar"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Atrás"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vuelve a configurar el Desbloqueo con huellas dactilares"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Ya no se puede reconocer <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Ya no se pueden reconocer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a573e9d..166e2da 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Durmiendo"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"No molestar (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gestionado por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activada"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desactivado"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Cualquier calendario"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> silencia algunos sonidos"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Se ha producido un problema interno en el dispositivo y es posible que este no sea estable hasta que restablezcas el estado de fábrica."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envía y recibe mensajes sin una red móvil ni Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre Mensajes"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Activa la opción Seleccionar red automáticamente"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Activa la opción Seleccionar red automáticamente en Ajustes para que tu teléfono pueda encontrar una red que funcione con satélite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activar"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Volver"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura Desbloqueo con huella digital de nuevo"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ya no puede reconocerse."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ya no pueden reconocerse."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 22c7777..fed97a1 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Nädalavahetus"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Sündmus"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Magamine"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Mitte segada (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Haldab <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Sees"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Väljas"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> kuni <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Mis tahes kalender"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vaigistab teatud helid"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Seadmes ilmnes sisemine probleem ja seade võib olla ebastabiilne seni, kuni lähtestate seadme tehase andmetele."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Sõnumite saatmine ja vastuvõtmine ilma mobiilside- või WiFi-võrguta"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ava rakendus Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Tööpõhimõtted"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Valiku „Vali võrk automaatselt“ sisselülitamine"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Lülitage seadetes sisse valik „Vali võrk automaatselt“, et telefon leiaks satelliidi abil töötava võrgu"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Lülita sisse"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Mine tagasi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ootel …"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Seadistage sõrmejäljega avamine uuesti"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Sõrmejälge <xliff:g id="FINGERPRINT">%s</xliff:g> ei saa enam tuvastada."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Sõrmejälgi <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei saa enam tuvastada."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 8d8ed8f..26e4114 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1532,7 +1532,7 @@
<string name="wallpaper_binding_label" msgid="1197440498000786738">"Horma-papera"</string>
<string name="chooser_wallpaper" msgid="3082405680079923708">"Aldatu horma-papera"</string>
<string name="notification_listener_binding_label" msgid="2702165274471499713">"Jakinarazpen-hautemailea"</string>
- <string name="vr_listener_binding_label" msgid="8013112996671206429">"Errealitate birtualeko hautemailea"</string>
+ <string name="vr_listener_binding_label" msgid="8013112996671206429">"EBko hautemailea"</string>
<string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Baldintza-hornitzailea"</string>
<string name="notification_ranker_binding_label" msgid="432708245635563763">"Jakinarazpenen sailkapen-zerbitzua"</string>
<string name="vpn_title" msgid="5906991595291514182">"VPN eginbidea aktibatuta"</string>
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Asteburua"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Gertaera"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Lo egiteko"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ez molestatzeko modua (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Kudeatzailea: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aktibatuta"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desaktibatuta"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Edozein egutegi"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> soinu batzuk isilarazten ari da"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Barneko arazo bat dago zure gailuan eta agian ezegonkor egongo da jatorrizko datuak berrezartzen dituzun arte."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Bidali eta jaso mezuak sare mugikorrik edo wifi-sarerik gabe"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ireki Mezuak"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Nola funtzionatzen du?"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Aktibatu \"Hautatu sarea automatikoki\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Aktibatu \"Hautatu sarea automatikoki\" ezarpenetan, telefonoak satelitearekin bateragarria den sare bat bilatu ahal izan dezan"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktibatu"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Egin atzera"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Zain…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ez da ezagutzen jada."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ez dira ezagutzen jada."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d6d950c..a8659eb 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1568,7 +1568,7 @@
<string name="gpsNotifMessage" msgid="7346649122793758032">"درخواستکننده <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
<string name="gpsVerifYes" msgid="3719843080744112940">"بله"</string>
<string name="gpsVerifNo" msgid="1671201856091564741">"نه"</string>
- <string name="sync_too_many_deletes" msgid="6999440774578705300">"از حد مجاز حذف فراتر رفت"</string>
+ <string name="sync_too_many_deletes" msgid="6999440774578705300">"از حد حذف کردن فراتر رفتید"</string>
<string name="sync_too_many_deletes_desc" msgid="7409327940303504440">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذفشده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. میخواهید چه کار بکنید؟"</string>
<string name="sync_really_delete" msgid="5657871730315579051">"حذف موارد"</string>
<string name="sync_undo_deletes" msgid="5786033331266418896">"واگرد موارد حذف شده"</string>
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"آخر هفته"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"رویداد"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"خوابیدن"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"مزاحم نشوید (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"تحتمدیریت <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"روشن"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"خاموش"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> تا <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"هر تقویمی"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> درحال قطع کردن بعضی از صداهاست"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"دستگاهتان یک مشکل داخلی دارد، و ممکن است تا زمانی که بازنشانی دادههای کارخانه انجام نگیرد، بیثبات بماند."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"ارسال و دریافت پیام بدون شبکه تلفن همراه یا Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیامنگار»"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"روش کار"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"روشن کردن «انتخاب خودکار شبکه»"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"برای اینکه تلفنتان بتواند شبکهای که با ماهواره کار میکند پیدا کند، «انتخاب خودکار شبکه» را در «تنظیمات» روشن کنید"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"روشن کردن"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"برگشتن"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"درحال تعلیق…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"راهاندازی مجدد «قفلگشایی با اثر انگشت»"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> دیگر قابلشناسایی نیست."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> دیگر قابلشناسایی نیستند."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index afc20f6..1f4372a 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Viikonloppuna"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Tapahtuma"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Nukkuminen"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Älä häiritse (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Ylläpitäjä: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Päällä"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Pois päältä"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kaikki kalenterit"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> mykistää joitakin ääniä"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Laitteellasi on sisäinen ongelma, joka aiheuttaa epävakautta. Voit korjata tilanteen palauttamalla tehdasasetukset."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Lähetä ja vastaanota viestejä ilman mobiili- tai Wi-Fi-verkkoa"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Avaa Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Näin se toimii"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Laita \"Valitse verkko automaattisesti\" päälle"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Laita \"Valitse verkko automaattisesti\" päälle asetuksista, jotta puhelin voi löytää satelliitin kanssa toimivan verkon."</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Laita päälle"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Takaisin"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Odottaa…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ota sormenjälkiavaus uudelleen käyttöön"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei enää ole tunnistettavissa."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät enää ole tunnistettavissa."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 6add38a..f7f1474 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semaine"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Événement"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sommeil"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ne pas déranger (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Géré par <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activé"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Désactivée"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> à <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"N\'importe quel agenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> désactive certains sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à ses paramètres par défaut."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envoyez et recevez des messages sans réseau cellulaire ou Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Activer « Sélectionner automatiquement le réseau »"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Activez « Sélectionner automatiquement le réseau » dans les paramètres pour que votre téléphone puisse trouver un réseau qui fonctionne par satellite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activer"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Retour"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurer le Déverrouillage par empreinte digitale à nouveau"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"L\'empreinte digitale <xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Les empreintes digitales <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 9de4334..bed2927 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Week-end"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Événement"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sommeil"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ne pas déranger (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Géré par <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activé"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Désactivé"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> à <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Tous les agendas"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> coupe certains sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne lié à votre appareil est survenu. Ce dernier risque d\'être instable jusqu\'à ce que vous rétablissiez la configuration d\'usine."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envoyer et recevoir des messages sans réseau mobile ou Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Activer \"Sélectionner automatiquement le réseau\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Activez \"Sélectionner automatiquement le réseau\" dans Paramètres pour que votre téléphone puisse trouver un réseau compatible avec un satellite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activer"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Retour"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Reconfigurer le déverrouillage par empreinte digitale"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 06c63ec..532c078 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -612,8 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que a aplicación determine a posición relativa entre os dispositivos próximos que usen banda ultralarga"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactuar con dispositivos wifi próximos"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permítelle á aplicación enviar anuncios e conectarse a dispositivos wifi próximos, e determinar a súa posición relativa"</string>
- <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información do servizo de pago de NFC preferido"</string>
- <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a aplicación obteña información do servizo de pago de NFC preferido, como as axudas rexistradas e o destino da ruta."</string>
+ <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información do servizo de pagos de NFC preferido"</string>
+ <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a aplicación obteña información do servizo de pagos de NFC preferido, como as axudas rexistradas e o destino da ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Near Field Communication"</string>
<string name="permdesc_nfc" msgid="8352737680695296741">"Permite á aplicación comunicarse con etiquetas, tarxetas e lectores Near Field Communication (NFC)."</string>
<string name="permlab_nfcTransactionEvent" msgid="5868209446710407679">"Evento de transacción no elemento seguro"</string>
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Mentres durmo"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Modo Non molestar (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Xestionada por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activada"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desactivada"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"De <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Calquera calendario"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando algúns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Produciuse un erro interno no teu dispositivo e quizais funcione de maneira inestable ata o restablecemento dos datos de fábrica."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envía e recibe mensaxes sen ter acceso a redes de telefonía móbil ou wifi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensaxes"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona?"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Activar Seleccionar rede automaticamente"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Activa a opción Seleccionar rede automaticamente en Configuración para que o teléfono busque unha rede que funcione co satélite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activar"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Volver"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura de novo o desbloqueo dactilar"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> xa non se recoñece."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> xa non se recoñecen."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index b0194ca..7e36c61 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"સપ્તાહાંત"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ઇવેન્ટ"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"નિષ્ક્રિય"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"ખલેલ પાડશો નહીં (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> દ્વારા મેનેજ કરવામાં આવે છે"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ચાલુ છે"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"બંધ છે"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>થી <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"કોઈપણ કૅલેન્ડર"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> અમુક અવાજોને મ્યૂટ કરે છે"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"તમારા ઉપકરણમાં આંતરિક સમસ્યા છે અને જ્યાં સુધી તમે ફેક્ટરી ડેટા ફરીથી સેટ કરશો નહીં ત્યાં સુધી તે અસ્થિર રહી શકે છે."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"મોબાઇલ કે વાઇ-ફાઇ નેટવર્ક વિના મેસેજ મોકલો અને મેળવો"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ખોલો"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"તેની કામ કરવાની રીત"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"ઑટોમૅટિક રીતે નેટવર્ક પસંદ કરો\" ચાલુ કરો"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"સેટિંગમાં \"ઑટોમૅટિક રીતે નેટવર્ક પસંદ કરો\" ચાલુ કરો, જેથી તમારો ફોન સૅટલાઇટ સાથે કામ કરતું નેટવર્ક શોધી શકે"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ચાલુ કરો"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"પાછા જાઓ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"બાકી..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"હવે <xliff:g id="FINGERPRINT">%s</xliff:g> ઓળખી શકાતી નથી."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"હવે <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ઓળખી શકાતી નથી."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 7e27cff..38e79b1 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1937,15 +1937,15 @@
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"हफ़्ते की रात"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"सप्ताहांत"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"इवेंट"</string>
- <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"सोने का समय"</string>
+ <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"स्लीपिंग मोड"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"\'परेशान न करें\' सुविधा (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"मैनेज करने वाला ऐप्लिकेशन: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"चालू है"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"बंद है"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
- <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"कोई भी कैलेंडर"</string>
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> से <xliff:g id="END">%2$s</xliff:g>"</string>
+ <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"किसी भी कैलेंडर के इवेंट के लिए"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> कुछ आवाज़ें म्यूट कर रहा है"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"आपके डिवाइस में कोई अंदरूनी समस्या है और यह तब तक ठीक नहीं होगी जब तक आप फ़ैक्टरी डेटा रीसेट नहीं करते."</string>
<string name="system_error_manufacturer" msgid="703545241070116315">"आपके डिवाइस के साथ कोई आंतरिक गड़बड़ी हुई. विवरणों के लिए अपने निर्माता से संपर्क करें."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"मोबाइल या वाई-फ़ाई नेटवर्क के बिना मैसेज भेजें और पाएं"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ऐप्लिकेशन खोलें"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यह सेटिंग कैसे काम करती है"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"नेटवर्क अपने-आप चुना जाए\" को चालू करें"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"सेटिंग में जाकर, \"नेटवर्क अपने-आप चुना जाए\" को चालू करें, ताकि आपका फ़ोन ऐसा नेटवर्क ढूंढ सके जो सैटलाइट के साथ काम करता है"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"चालू करें"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"रद्द करें"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रोसेस जारी है..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"अब <xliff:g id="FINGERPRINT">%s</xliff:g> की पहचान नहीं की जा सकती."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"अब <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> की पहचान नहीं की जा सकती."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 1066559..90e228e 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Događaj"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spavanje"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ne uznemiravaj (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Upravlja <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Uključeno"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Isključeno"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bilo koji kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvukove"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Na vašem uređaju postoji interni problem i možda neće biti stabilan dok ga ne vratite na tvorničko stanje."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Šaljite i primajte poruke kad nije dostupna mobilna ili Wi-Fi mreža"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Poruke"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako to funkcionira"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Uključite opciju Automatski odaberi mrežu"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Uključite opciju Automatski odaberi mrežu u postavkama da bi telefon mogao pronaći mrežu koja funkcionira sa satelitom"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Uključi"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Natrag"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovno postavite otključavanje otiskom prsta"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> više se ne prepoznaje."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više se ne prepoznaju."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index c76d9f4..d5a28f8 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Hétvége"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Esemény"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Alvás"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ne zavarjanak (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Kezelő: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Bekapcsolva"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Kikapcsolva"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bármilyen naptár"</string>
<string name="muted_by" msgid="91464083490094950">"A(z) <xliff:g id="THIRD_PARTY">%1$s</xliff:g> lenémít néhány hangot"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Belső probléma van az eszközzel, és instabil lehet, amíg vissza nem állítja a gyári adatokat."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Küldhet és fogadhat üzeneteket mobil- és Wi-Fi-hálózat nélkül is"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"A Messages megnyitása"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hogyan működik?"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Kapcsolja be a „Hálózat automatikus kiválasztása” beállítást"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Kapcsolja be a „Hálózat automatikus kiválasztása” beállítást a Beállításokban, hogy a telefon megtalálja a műholddal működő hálózatot"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Bekapcsolás"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Vissza"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Függőben…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"A Feloldás ujjlenyomattal funkció újbóli beállítása"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A következő már nem felismerhető: <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"A következők már nem felismerhetők: <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index c91918d..14534a7 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1112,7 +1112,7 @@
<string name="menu_sym_shortcut_label" msgid="4037566049061218776">"Sym+"</string>
<string name="menu_function_shortcut_label" msgid="2367112760987662566">"Function+"</string>
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"բացակ"</string>
- <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"մուտք"</string>
+ <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"enter"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ջնջել"</string>
<string name="search_go" msgid="2141477624421347086">"Որոնել"</string>
<string name="search_hint" msgid="455364685740251925">"Որոնում..."</string>
@@ -1600,7 +1600,7 @@
<string name="keyboardview_keycode_done" msgid="2524518019001653851">"Պատրաստ է"</string>
<string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Ռեժիմի փոփոխում"</string>
<string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Shift"</string>
- <string name="keyboardview_keycode_enter" msgid="168054869339091055">"Մուտք"</string>
+ <string name="keyboardview_keycode_enter" msgid="168054869339091055">"Enter"</string>
<string name="activitychooserview_choose_application" msgid="3500574466367891463">"Ընտրել ծրագիր"</string>
<string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Չհաջողվեց գործարկել <xliff:g id="APPLICATION_NAME">%s</xliff:g> ծրագիրը"</string>
<string name="shareactionprovider_share_with" msgid="2753089758467748982">"Կիսվել"</string>
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Շաբաթ-կիրակի"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Միջոցառում"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Քնի ժամ"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Չանհանգստացնել (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Կառավարվում է <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի կողմից"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Միացված է"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Անջատված է"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Ցանկացած օրացույց"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>-ն անջատում է որոշ ձայներ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Սարքում ներքին խնդիր է առաջացել և այն կարող է կրկնվել, մինչև չվերականգնեք գործարանային կարգավորումները:"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Ուղարկեք և ստացեք հաղորդագրություններ առանց բջջային կամ Wi-Fi ցանցի"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Բացել Messages-ը"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ինչպես է դա աշխատում"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Միացրեք «Ավտոմատ ընտրել ցանցը»"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Կարգավորումներում միացրեք «Ավտոմատ ընտրել ցանցը», որպեսզի ձեր հեռախոսը կարողանա արբանյակի հետ աշխատող ցանց գտնել"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Միացնել"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Հետ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Առկախ է…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Նորից կարգավորեք մատնահետքով ապակողպումը"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> մատնահետքն այլևս չի կարող ճանաչվել։"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> և <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> մատնահետքերն այլևս չեն կարող ճանաչվել։"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 4984630..360102f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Akhir pekan"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Acara"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Tidur"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Jangan Ganggu (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Dikelola oleh <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aktif"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Nonaktif"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> hingga <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kalender mana saja"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> mematikan beberapa suara"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Ada masalah dengan perangkat. Hal ini mungkin membuat perangkat jadi tidak stabil dan perlu dikembalikan ke setelan pabrik."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Mengirim dan menerima pesan tanpa jaringan seluler atau Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Message"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara kerjanya"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Aktifkan \"Pilih jaringan secara otomatis\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Aktifkan \"Pilih jaringan secara otomatis\" di Setelan agar ponsel dapat menemukan jaringan yang berfungsi dengan satelit"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktifkan"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Kembali"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Tertunda..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Siapkan Buka dengan Sidik Jari lagi"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dikenali lagi."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dikenali lagi."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 47a6c35..9d3e2e4 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Helgi"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Viðburður"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Svefn"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ónáðið ekki (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Stýrt af <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Kveikt"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Slökkt"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> til <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Öll dagatöl"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> þaggar í einhverjum hljóðum"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Innra vandamál kom upp í tækinu og það kann að vera óstöðugt þangað til þú núllstillir það."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Senda og fá skilaboð án tengingar við farsímakerfi eða Wi-Fi-net"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Opna Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Svona virkar þetta"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Kveiktu á „Velja net sjálfkrafa“"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Kveiktu á „Velja net sjálfkrafa“ í stillingunum til að gera símanum kleift að finna net sem virkar með gervihnetti"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Kveikja"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Til baka"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Í bið…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setja upp fingrafarskenni aftur"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT">%s</xliff:g> lengur."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> lengur."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 4070f11..ee7f08d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1939,6 +1939,7 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fine settimana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Notte"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Non disturbare (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gestione: app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
@@ -2431,6 +2432,54 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Attiva"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Indietro"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"In attesa…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Riconfigura lo Sblocco con l\'Impronta"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> non può più essere riconosciuto."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non possono più essere riconosciuti."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 8b0dd80..e3f2a7c 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"סוף השבוע"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"אירוע"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"שינה"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"נא לא להפריע (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"בניהול של <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"מצב פעיל"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"מצב מושבת"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> עד <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"כל יומן"</string>
<string name="muted_by" msgid="91464083490094950">"חלק מהצלילים מושתקים על ידי <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"קיימת בעיה פנימית במכשיר שלך, וייתכן שהוא לא יתפקד כראוי עד שיבוצע איפוס לנתוני היצרן."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"אפשר לשלוח ולקבל הודעות ללא רשת סלולרית או Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"לפתיחת Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"איך זה עובד"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"הפעלת האפשרות \'בחירה אוטומטית של הרשת\'"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"כדי למצוא רשת שעובדת עם לוויין בטלפון, צריך להפעיל את האפשרות \'בחירה אוטומטית של הרשת\' בהגדרות"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"הפעלה"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"חזרה"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"בהמתנה..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"הגדרה חוזרת של \'ביטול הנעילה בטביעת אצבע\'"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ואת <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 2f38929..0d3a80c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"週末"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"予定モード"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"おやすみモード"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"サイレント モード(<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> によって管理されています"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ON"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"OFF"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"すべてのカレンダー"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> により一部の音はミュートに設定"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"デバイスで内部的な問題が発生しました。データが初期化されるまで不安定になる可能性があります。"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"モバイル ネットワークや Wi-Fi ネットワークがなくてもメッセージを送受信できます"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"メッセージ アプリを開く"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"仕組み"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"[ネットワークを自動的に選択] を ON にする"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"設定で [ネットワークを自動的に選択] を ON にすると、衛星と通信可能なネットワークをスマートフォンが検出できるようになります"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ON にする"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"戻る"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"保留中..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"指紋認証をもう一度設定してください"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>を認識できなくなりました。"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>と<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>を認識できなくなりました。"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 2d9aecd..19177d6 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"შაბათ-კვირა"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"მოვლენა"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ძილისას"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"არ შემაწუხოთ (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"მართავს <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ჩართული"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"გამორთული"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ნებისმიერი კალენდარი"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ზოგიერთ ხმას ადუმებს"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ფიქსირდება თქვენი მ ოწყობილობის შიდა პრობლემა და შეიძლება არასტაბილური იყოს, სანამ ქარხნულ მონაცემების არ განაახლებთ."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"შეტყობინებების გაგზავნა და მიღება მობილური ან Wi-Fi ქსელის გარეშე"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages-ის გახსნა"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"მუშაობის პრინციპი"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"„ქსელის ავტომატურად არჩევის“ ჩართვა"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ჩართეთ „ქსელის ავტომატურად არჩევა“ პარამეტრებში, რათა თქვენმა ტელეფონმა სატელიტთან თავსებადი ქსელის პოვნა შეძლოს"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ჩართვა"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"უკან დაბრუნება"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"მომლოდინე..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ანაბეჭდით განბლოკვის ხელახლა დაყენება"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>-ისა და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 6986a7b..70774d6 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Демалыс күндері"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Іс-шара"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Ұйқы режимі"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Мазаламау (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> басқарады."</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Қосулы"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Өшірулі"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Кез келген күнтізбе"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> кейбір дыбыстарды өшіруде"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Хабарландыруларды мобильдік желіге немесе Wi-Fi желісіне қосылмай жіберіңіз және алыңыз."</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages қолданбасын ашу"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Бұл қалай орындалады?"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"Желіні автоматты түрде таңдау\" опциясын қосу"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Телефоныңыз жерсерікпен жұмыс істейтін желіні таба алуы үшін, \"Параметрлер\" бөлімінен \"Желіні автоматты түрде таңдау\" опциясын қосыңыз."</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Қосу"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Артқа"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Дайын емес…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Саусақ ізімен ашу функциясын қайта реттеу"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> бұдан былай танылмайды."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> бұдан былай танылмайды."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index b2bb78b..c758e05 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ចុងសប្ដាហ៍"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ព្រឹត្តិការណ៍"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"កំពុងដេក"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"កុំរំខាន (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"គ្រប់គ្រងដោយ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"បើក"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"បិទ"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ដល់ <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ប្រតិទិនណាមួយ"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> កំពុងបិទសំឡេងមួយចំនួន"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"មានបញ្ហាខាងក្នុងឧបករណ៍របស់អ្នក ហើយវាអ្នកមិនមានស្ថេរភាព រហូតទាល់តែអ្នកកំណត់ដូចដើមវិញទាំងស្រុង។"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"ផ្ញើ និងទទួលសារដោយគ្មានបណ្ដាញ Wi-Fi ឬបណ្ដាញទូរសព្ទចល័ត"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"បើកកម្មវិធី Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"របៀបដែលវាដំណើរការ"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"បើក \"ជ្រើសរើសបណ្ដាញដោយស្វ័យប្រវត្តិ\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"បើក \"ជ្រើសរើសបណ្ដាញដោយស្វ័យប្រវត្តិ\" នៅក្នុងការកំណត់ ដើម្បីឱ្យទូរសព្ទរបស់អ្នកអាចស្វែងរកបណ្ដាញ ដែលដំណើរការតាមរយៈផ្កាយរណប"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"បើក"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ថយក្រោយ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"កំពុងរង់ចាំ..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"រៀបចំការដោះសោដោយស្កេនស្នាមម្រាមដៃម្ដងទៀត"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT">%s</xliff:g> បានទៀតហើយ។"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> បានទៀតហើយ។"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 8332cfc..8efcd08 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ವಾರಾಂತ್ಯ"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ಈವೆಂಟ್"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ನಿದ್ರೆಯ ಸಮಯ"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗಿದೆ"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ಆನ್ ಆಗಿದೆ"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ಆಫ್ ಆಗಿದೆ"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ನಿಂದ <xliff:g id="END">%2$s</xliff:g> ವರೆಗೆ"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ಯಾವುದೇ ಕ್ಯಾಲೆಂಡರ್"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ಧ್ವನಿ ಮ್ಯೂಟ್ ಮಾಡುತ್ತಿದ್ದಾರೆ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ ಹಾಗೂ ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾವನ್ನು ರೀಸೆಟ್ ಮಾಡುವವರೆಗೂ ಅದು ಅಸ್ಥಿರವಾಗಬಹುದು."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"ಮೊಬೈಲ್ ಅಥವಾ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ ಇಲ್ಲದೆಯೇ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಿ ಮತ್ತು ಸ್ವೀಕರಿಸಿ"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ಅನ್ನು ತೆರೆಯಿರಿ"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ಇದು ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನೆಟ್ವರ್ಕ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ\" ಅನ್ನು ಆನ್ ಮಾಡಿ"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ \"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನೆಟ್ವರ್ಕ್ ಆಯ್ಕೆಮಾಡಿ\" ಅನ್ನು ಆನ್ ಮಾಡಿ ಇದರಿಂದ ನಿಮ್ಮ ಫೋನ್ ಸ್ಯಾಟಲೈಟ್ ಜೊತೆಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ನೆಟ್ವರ್ಕ್ ಅನ್ನು ಹುಡುಕಬಹುದು"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ಆನ್ ಮಾಡಿ"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ಹಿಂದಿರುಗಿ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ಬಾಕಿ ಉಳಿದಿದೆ..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 393c956..a069805 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"주말"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"캘린더 일정"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"수면 시간"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"방해 금지 모드(<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"관리자: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"사용"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"사용 중지"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"모든 캘린더"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>(이)가 일부 소리를 음소거함"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"사용 중인 기기 내부에 문제가 발생했습니다. 초기화할 때까지 불안정할 수 있습니다."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"모바일 또는 Wi-Fi 네트워크 없이 메시지 주고받기"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"메시지 열기"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"작동 방식"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\'네트워크 자동 선택\' 사용 설정"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"휴대전화에서 위성과 연결되는 네트워크를 찾을 수 있도록 \'설정\'에서 \'네트워크 자동 선택\'을 사용 설정하세요"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"사용"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"뒤로"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"대기 중…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"지문 잠금 해제 다시 설정"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> 지문을 더 이상 인식할 수 없습니다."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> 지문을 더 이상 인식할 수 없습니다."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index e44538b..ec0059b 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Дем алыш"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Иш-чара"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Уйку режими"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Тынчымды алба (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> башкарат"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Күйүк"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Өчүк"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>, <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Бардык жылнаамалар"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> айрым үндөрдү өчүрүүдө"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Түзмөгүңүздө ички көйгөй бар жана ал баштапкы абалга кайтарылмайынча туруктуу иштебей коюшу мүмкүн."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Мобилдик же Wi-Fi тармагына туташпай эле билдирүүлөрдү жөнөтүп, алыңыз"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Жазышуулар колдонмосун ачуу"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ал кантип иштейт"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"Тармакты автоматтык түрдө тандоо\" параметрин күйгүзүңүз"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Телефонуңуз спутник менен иштеген тармакты табышы үчүн, параметрлерден \"Тармакты автоматтык түрдө тандоону\" күйгүзүңүз"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Күйгүзүү"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Артка кайтуу"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Кезекте турат..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Манжа изи менен ачуу функциясын кайра тууралаңыз"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> мындан ары таанылбайт."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> мындан ары таанылбайт."</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 15138bb..3962f09 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ທ້າຍອາທິດ"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ການນັດໝາຍ"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ການນອນ"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"ຫ້າມລົບກວນ (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"ຈັດການໂດຍ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ເປີດຢູ່"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ປິດຢູ່"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ຫາ <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ປະຕິທິນໃດກໍໄດ້"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ປິດສຽງບາງຢ່າງໄວ້"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ມີບັນຫາພາຍໃນກັບອຸປະກອນຂອງທ່ານ, ແລະມັນອາດຈະບໍ່ສະຖຽນຈົນກວ່າທ່ານຕັ້ງເປັນຂໍ້ມູນໂຮງງານຄືນແລ້ວ."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"ຮັບ ແລະ ສົ່ງຂໍ້ຄວາມໂດຍບໍ່ຕ້ອງໃຊ້ເຄືອຂ່າຍໂທລະສັບມືຖື ຫຼື Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"ເປີດ Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ມັນເຮັດວຽກແນວໃດ"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"ເປີດໃຊ້ \"ເລືອກເຄືອຂ່າຍອັດຕະໂນມັດ\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ເປີດໃຊ້ \"ເລືອກເຄືອຂ່າຍອັດຕະໂນມັດ\" ໃນການຕັ້ງຄ່າເພື່ອໃຫ້ໂທລະສັບຂອງທ່ານສາມາດຊອກຫາເຄືອຂ່າຍທີ່ໃຊ້ໄດ້ກັບດາວທຽມ"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ເປີດໃຊ້"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ກັບຄືນ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ລໍຖ້າດຳເນີນການ..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍລາຍນິ້ວມືຄືນໃໝ່"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT">%s</xliff:g> ໄດ້ອີກຕໍ່ໄປ."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ໄດ້ອີກຕໍ່ໄປ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 51aa8a1..c88b663 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1940,13 +1940,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Savaitgalį"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Įvykis"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Miegas"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Netrukdymo režimas („<xliff:g id="APP_NAME">%1$s</xliff:g>“)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Tvarko „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Įjungti"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Išjungti"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bet kuris kalendorius"</string>
<string name="muted_by" msgid="91464083490094950">"„<xliff:g id="THIRD_PARTY">%1$s</xliff:g>“ nutildo kai kuriuos garsus"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Iškilo vidinė su jūsų įrenginiu susijusi problema, todėl įrenginys gali veikti nestabiliai, kol neatkursite gamyklinių duomenų."</string>
@@ -2428,15 +2428,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Siųskite ir gaukite pranešimus be mobiliojo ryšio ar „Wi-Fi“ tinklo"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Atidaryti programą „Messages“"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kaip tai veikia"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Parinkties „Automatiškai pasirinkti tinklą“ įjungimas"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Įjunkite „Automatiškai pasirinkti tinklą“ nustatymuose, kad telefonas galėtų rasti su palydovu suderinamą tinklą"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Įjungti"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Grįžti"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Laukiama..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Atrakinimo piršto atspaudu nustatymas dar kartą"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nebegalima atpažinti."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nebegalima atpažinti."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 43de9f5..38d1891 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Nedēļas nogalē"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Pasākums"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Gulēšana"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Netraucēt (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Pārvalda <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ieslēgta"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Izslēgta"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"no <xliff:g id="START">%1$s</xliff:g> līdz <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Jebkurš kalendārs"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> izslēdz noteiktas skaņas"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Jūsu ierīcē ir radusies iekšēja problēma, un ierīce var darboties nestabili. Lai to labotu, veiciet rūpnīcas datu atiestatīšanu."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Sūtiet un saņemiet ziņojumus bez mobilā vai Wi‑Fi tīkla."</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Atvērt lietotni Ziņojumi"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Darbības principi"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Ieslēdziet iestatījumu “Automātiski atlasīt tīklu”"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Iestatījumos ieslēdziet iespēju “Automātiski atlasīt tīklu”, lai tālrunis varētu atrast tīklu, kas ir saderīgs ar satelītu."</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ieslēgt"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Atpakaļ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Gaida…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Pirksta nospiedumu (<xliff:g id="FINGERPRINT">%s</xliff:g>) vairs nevar atpazīt."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Pirkstu nospiedumus (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) vairs nevar atpazīt."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index ea38037..87fd799 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Викенд"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Настан"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Спиење"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Не вознемирувај (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Управувано од <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Вклучено"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Исклучено"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> до <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Кој било календар"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> исклучи некои звуци"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Настана внатрешен проблем со уредот и може да биде нестабилен сè додека не ресетирате на фабричките податоци."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Испраќајте и примајте пораки без мобилна или Wi-Fi мрежа"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Отворете ја Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Дознајте како функционира"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Вклучете „Избирај мрежа автоматски“"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Вклучете „Избирај мрежа автоматски“ во „Поставки“ за да може телефонот да најде мрежа што функционира со сателит"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Вклучи"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Врати се назад"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Во фаза на чекање…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поставете „Отклучување со отпечаток“ повторно"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> веќе не може да се препознае."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> веќе не може да се препознаат."</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index ae6505d..086ebe1 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"വാരാന്ത്യം"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ഇവന്റ്"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ഉറക്കം"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"ശല്യപ്പെടുത്തരുത് (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യുന്നത്"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ഓണാണ്"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ഓഫാണ്"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> മുതൽ <xliff:g id="END">%2$s</xliff:g> വരെ"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"എല്ലാ കലണ്ടറിലും"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ചില ശബ്ദങ്ങൾ മ്യൂട്ട് ചെയ്യുന്നു"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു ആന്തരിക പ്രശ്നമുണ്ട്, ഫാക്ടറി വിവര പുനഃസജ്ജീകരണം ചെയ്യുന്നതുവരെ ഇതു അസ്ഥിരമായിരിക്കാനിടയുണ്ട്."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"മൊബൈൽ അല്ലെങ്കിൽ വൈഫൈ നെറ്റ്വർക്ക് ഇല്ലാതെ സന്ദേശങ്ങൾ അയയ്ക്കുകയും സ്വീകരിക്കുകയും ചെയ്യുക"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages തുറക്കുക"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ഇത് പ്രവർത്തിക്കുന്നത് എങ്ങനെയാണ്"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"സ്വയമേവ നെറ്റ്വർക്ക് തിരഞ്ഞെടുക്കുക\" ഓണാക്കുക"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ക്രമീകരണങ്ങളിൽ \"സ്വയമേവ നെറ്റ്വർക്ക് തിരഞ്ഞെടുക്കുക\" ഓണാക്കുക, അതുവഴി നിങ്ങളുടെ ഫോണിന് ഉപഗ്രഹത്തിനൊപ്പം പ്രവർത്തിക്കുന്ന ഒരു നെറ്റ്വർക്ക് കണ്ടെത്താനാകും"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ഓണാക്കുക"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"മടങ്ങുക"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"തീർപ്പാക്കിയിട്ടില്ല..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ഇനി തിരിച്ചറിയാനാകില്ല."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ഇനി തിരിച്ചറിയാനാകില്ല."</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 3d2eb04..42db4c9 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Амралтын өдөр"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Үйл явдал"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Унтлагын цаг"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Бүү саад бол (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g>-с удирддаг"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Асаалттай"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Унтраалттай"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>-с <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Дурын календарь"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> зарим дууны дууг хааж байна"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Таны төхөөрөмжид дотоод алдаа байна.Та төхөөрөмжөө үйлдвэрээс гарсан төлөвт шилжүүлэх хүртэл таны төхөөрөмж чинь тогтворгүй байж болох юм."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Хөдөлгөөнт холбооны эсвэл Wi-Fi сүлжээгүйгээр мессеж илгээх болон хүлээн авах"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Мессежийг нээх"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Энэ хэрхэн ажилладаг вэ?"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"Сүлжээг автоматаар сонгох\"-ыг асаах"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Тохиргоонд \"Сүлжээг автоматаар сонгох\"-ыг асааснаар таны утас хиймэл дагуултай ажилладаг сүлжээг олох боломжтой"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Асаах"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Буцах"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Хүлээгдэж буй..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>-г цаашид таних боломжгүй."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-г цаашид таних боломжгүй."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 9243f47..2cfeaa2 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"आठवड्याच्या शेवटी"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"इव्हेंट"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"झोपताना"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"व्यत्यय आणू नका (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> द्वारे व्यवस्थापित"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"सुरू आहे"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"बंद आहे"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ते <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"कोणतेही कॅलेंडर"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> काही ध्वनी म्यूट करत आहे"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"आपल्या डिव्हाइसमध्ये अंतर्गत समस्या आहे आणि तुमचा फॅक्टरी डेटा रीसेट होईपर्यंत ती अस्थिर असू शकते."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"मोबाइल किंवा वाय-फाय नेटवर्कशिवाय मेसेज पाठवणे आणि मिळवणे"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages उघडा"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ते कसे काम करते"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"नेटवर्क आपोआप निवडा\" सुरू करा"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"सेटिंग्ज मध्ये \"नेटवर्क आपोआप निवडा\" सुरू करा, जेणेकरून तुमचा फोन सॅटेलाइटसोबत काम करणारे नेटवर्क शोधू शकेल"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"सुरू करा"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"मागे जा"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रलंबित आहे..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिंट अनलॉक पुन्हा सेट करा"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> यापुढे ओळखता येणार नाही."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> आणि <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> यापुढे ओळखता येणार नाहीत."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 9bda173..6f5d5e7 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Hujung minggu"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Acara"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Tidur"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Jangan Ganggu (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Diurus oleh <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Hidup"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Mati"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> hingga <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Sebarang kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> meredamkan sesetengah bunyi"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Terdapat masalah dalaman dengan peranti anda. Peranti mungkin tidak stabil sehingga anda membuat tetapan semula data kilang."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Hantar dan terima mesej tanpa rangkaian mudah alih atau Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara ciri ini berfungsi"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Hidupkan \"Pilih rangkaian secara automatik\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Hidupkan \"Pilih rangkaian secara automatik\" dalam Tetapan supaya telefon anda boleh menemukan rangkaian yang berfungsi dengan satelit"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Hidupkan"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Kembali"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Belum selesai..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Sediakan Buka Kunci Cap Jari sekali lagi"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dicam lagi."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dicam lagi."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 2581a74..9e7e78f 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"စနေ၊ တနင်္ဂနွေ"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"အစီအစဉ်"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"အိပ်နေချိန်"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"မနှောင့်ယှက်ရ (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> က စီမံသည်"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ဖွင့်"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ပိတ်"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"၊ "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> မှ <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"မည်သည့်ပြက္ခဒိန်မဆို"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> သည် အချို့အသံကို ပိတ်နေသည်"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေပြီး၊ မူလစက်ရုံထုတ်အခြေအနေအဖြစ် ပြန်လည်ရယူနိုင်သည်အထိ အခြေအနေမတည်ငြိမ်နိုင်ပါ။"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက်မရှိဘဲ မက်ဆေ့ဂျ်များ ပို့နိုင်၊ လက်ခံနိုင်သည်"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ဖွင့်ရန်"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"အလုပ်လုပ်ပုံ"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"“ကွန်ရက် အလိုအလျောက်ရွေးရန်” ကို ဖွင့်ပါ"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"သင့်ဖုန်းက ဂြိုဟ်တုဖြင့် အလုပ်လုပ်သော ကွန်ရက်ကို ရှာနိုင်ရန်အတွက် ဆက်တင်များတွင် “ကွန်ရက် အလိုအလျောက်ရွေးရန်” ကို ဖွင့်ပါ"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ဖွင့်ရန်"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"နောက်သို့"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ဆိုင်းငံ့ထားသည်…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"‘လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 2228864..683ca26 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Helg"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Aktivitet"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sover"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ikke forstyrr (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Administreres av <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"På"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Av"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> til <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Hvilken som helst kalender"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> slår av noen lyder"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Det har oppstått et internt problem på enheten din, og den kan være ustabil til du tilbakestiller den til fabrikkdata."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send og motta meldinger uten mobil- eller wifi-nettverk"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Åpne Meldinger"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Slik fungerer det"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Slå på «Velg nettverk automatisk»"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Slå på «Velg nettverk automatisk» i innstillingene, slik at telefonen kan finne et nettverk som fungerer med satellitt"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Slå på"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Gå tilbake"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Venter …"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer opplåsingen med fingeravtrykk på nytt"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> gjenkjennes ikke lenger."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> gjenkjennes ikke lenger."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 5684d78..ffeecb1c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -807,7 +807,7 @@
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"सञ्जाल अवस्थाका पर्यवेक्षणका लागि सुन्नुहोस्"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"सञ्जाल अवस्थाका पर्यवेक्षण सुन्नका लागि एपलाई अनुमति दिन्छ।सामान्य एपलाई चाँहिदै नचाँहिन सक्छ।"</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"इनपुट डिभाइस क्यालिब्रेसन परिवर्तन गर्नुहोस्"</string>
- <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"एपलाई टच स्क्रीनको प्यारामिटरहरू क्यालिब्रेसन परिमार्जन गर्न अनुमति दिन्छ। साधारण एपहरूको लागि कहिल्यै आवश्यक पर्दैन।"</string>
+ <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"एपलाई टच स्क्रिनको प्यारामिटरहरू क्यालिब्रेसन परिमार्जन गर्न अनुमति दिन्छ। साधारण एपहरूको लागि कहिल्यै आवश्यक पर्दैन।"</string>
<string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"DRM प्रमाणपत्रको पहुँच"</string>
<string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"DRM प्रमाणपत्रहरू प्रावधान र प्रयोग गर्ने निवेदनको अनुमति दिन्छ। साधारण एपहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"Android Beam स्थानान्तरण अवस्था प्राप्त गर्नुहोस्"</string>
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"शनिवार"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"कार्यक्रम"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"शयन"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Do Not Disturb (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले व्यवस्थापन गरेको"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"अन छ"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"अफ छ"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> देखि <xliff:g id="END">%2$s</xliff:g> सम्म"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"कुनै पनि पात्रो"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ले केही ध्वनिहरू म्युट गर्दै छ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ, र तपाईंले फ्याक्ट्री डाटा रिसेट नगर्दासम्म यो अस्थिर रहन्छ।"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"मोबाइल वा Wi-Fi नेटवर्कविनै म्यासेजहरू पठाउनुहोस् र प्राप्त गर्नुहोस्"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages खोल्नुहोस्"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यसले काम गर्ने तरिका"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"स्वतः नेटवर्क चयन गर्नुहोस्\" अन गर्नुहोस्"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"तपाईंको फोनले स्याटलाइटसँग काम गर्ने नेटवर्क भेट्टाउन सकोस् भन्नका लागि सेटिङमा गई \"स्वतः नेटवर्क चयन गर्नुहोस्\" अन गर्नुहोस्"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"अन गर्नुहोस्"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"पछाडि जानुहोस्"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"विचाराधीन..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> अब पहिचान गर्न सकिँदैन।"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> अब पहिचान गर्न सकिँदैन।"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index ac18bcf..5f77e73 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Afspraak"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Slapen"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Niet storen (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Beheerd door <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aan"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Uit"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> tot <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Elke agenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> zet sommige geluiden uit"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Er is een intern probleem met je apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Stuur en krijg berichten zonder mobiel of wifi-netwerk"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Berichten openen"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe het werkt"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Netwerk automatisch selecteren aanzetten"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Zet Netwerk automatisch selecteren aan in Instellingen zodat je telefoon een netwerk kan vinden dat werkt met satellieten"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aanzetten"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Terug"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"In behandeling…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ontgrendelen met vingerafdruk weer instellen"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> wordt niet meer herkend."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> worden niet meer herkend."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index c860657..b4f924b 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1112,7 +1112,7 @@
<string name="menu_sym_shortcut_label" msgid="4037566049061218776">"Sym+"</string>
<string name="menu_function_shortcut_label" msgid="2367112760987662566">"Function+"</string>
<string name="menu_space_shortcut_label" msgid="5949311515646872071">"ସ୍ପେସ୍"</string>
- <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"ଏଣ୍ଟର୍"</string>
+ <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"ଏଣ୍ଟର"</string>
<string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ଡିଲିଟ କରନ୍ତୁ"</string>
<string name="search_go" msgid="2141477624421347086">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
<string name="search_hint" msgid="455364685740251925">"ସର୍ଚ୍ଚ କରନ୍ତୁ…"</string>
@@ -1600,7 +1600,7 @@
<string name="keyboardview_keycode_done" msgid="2524518019001653851">"ହୋଇଗଲା"</string>
<string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"ମୋଡ୍ ପରିବର୍ତ୍ତନ"</string>
<string name="keyboardview_keycode_shift" msgid="3026509237043975573">"ଶିଫ୍ଟ"</string>
- <string name="keyboardview_keycode_enter" msgid="168054869339091055">"ଏଣ୍ଟର୍"</string>
+ <string name="keyboardview_keycode_enter" msgid="168054869339091055">"ଏଣ୍ଟର"</string>
<string name="activitychooserview_choose_application" msgid="3500574466367891463">"ଗୋଟିଏ ଆପ୍ ବାଛନ୍ତୁ"</string>
<string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ଲଞ୍ଚ କରାଯାଇପାରିଲା ନାହିଁ"</string>
<string name="shareactionprovider_share_with" msgid="2753089758467748982">"ଏହାଙ୍କ ସହ ସେୟାର୍ କରନ୍ତୁ"</string>
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ସପ୍ତାହାନ୍ତ"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ଇଭେଣ୍ଟ"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ଶୋଇବା"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ଚାଲୁ ଅଛି"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ବନ୍ଦ ଅଛି"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>ରୁ <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ଯେକୌଣସି କ୍ୟାଲେଣ୍ଡର୍"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> କିଛି ସାଉଣ୍ଡକୁ ମ୍ୟୁଟ୍ କରୁଛି"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ଆପଣଙ୍କ ଡିଭାଇସ୍ରେ ଏକ ସମସ୍ୟା ରହିଛି ଏବଂ ଆପଣ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ୍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଏହା ଅସ୍ଥିର ରହିପାରେ।"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"ଏକ ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ବିନା ମେସେଜ ପଠାନ୍ତୁ ଏବଂ ପାଆନ୍ତୁ"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ଖୋଲନ୍ତୁ"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ଏହା କିପରି କାମ କରେ"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"ସ୍ୱତଃ ନେଟୱାର୍କକୁ ଚୟନ କରନ୍ତୁ\"କୁ ଚାଲୁ କରନ୍ତୁ"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ସେଟିଂସରେ \"ସ୍ୱତଃ ନେଟୱାର୍କକୁ ଚୟନ କରନ୍ତୁ\"କୁ ଚାଲୁ କରନ୍ତୁ, ଯାହା ଫଳରେ ଆପଣଙ୍କ ଫୋନ ସେଟେଲାଇଟ ସହିତ କାର୍ଯ୍ୟ କରୁଥିବା ଏକ ନେଟୱାର୍କକୁ ଖୋଜିପାରିବ"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ଚାଲୁ କରନ୍ତୁ"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ପଛକୁ ଫେରନ୍ତୁ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ବାକି ଅଛି…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 63ebeb8..fae806c 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ਹਫ਼ਤੇ ਦਾ ਅੰਤਲਾ ਦਿਨ"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ਇਵੈਂਟ"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ਸੌਣ ਵੇਲੇ"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ਚਾਲੂ ਹੈ"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ਬੰਦ ਹੈ"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> ਤੋਂ <xliff:g id="END">%2$s</xliff:g> ਤੱਕ"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ਕੋਈ ਵੀ ਕੈਲੰਡਰ"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ਕੁਝ ਧੁਨੀਆਂ ਨੂੰ ਮਿਊਟ ਕਰ ਰਹੀ ਹੈ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਹੈ ਅਤੇ ਇਹ ਅਸਥਿਰ ਹੋ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਨਹੀਂ ਕਰਦੇ।"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"ਮੋਬਾਈਲ ਜਾਂ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਤੋਂ ਬਿਨਾਂ ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ਐਪ ਖੋਲ੍ਹੋ"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ਇਹ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਨੈੱਟਵਰਕ ਚੁਣੋ\" ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ \"ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਨੈੱਟਵਰਕ ਚੁਣੋ\" ਨੂੰ ਚਾਲੂ ਕਰੋ, ਤਾਂ ਜੋ ਤੁਹਾਡਾ ਫ਼ੋਨ ਅਜਿਹਾ ਨੈੱਟਵਰਕ ਲੱਭ ਸਕੇ ਜੋ ਸੈਟੇਲਾਈਟ ਨਾਲ ਕੰਮ ਕਰਦਾ ਹੋਵੇ"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ਚਾਲੂ ਕਰੋ"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ਵਾਪਸ ਜਾਓ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ਵਿਚਾਰ-ਅਧੀਨ..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index fa2b493..cf758fe 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1940,13 +1940,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Wydarzenie"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sen"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Nie przeszkadzać (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Zarządzana przez aplikację <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Włączono"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Wyłączono"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"Od <xliff:g id="START">%1$s</xliff:g> do <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Dowolny kalendarz"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> wycisza niektóre dźwięki"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"W Twoim urządzeniu wystąpił problem wewnętrzny. Może być ono niestabilne, dopóki nie przywrócisz danych fabrycznych."</string>
@@ -2428,15 +2428,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Wysyłaj i odbieraj wiadomości bez sieci komórkowej czy Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otwórz Wiadomości"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to działa"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Włącz „Automatycznie wybieraj sieć”"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"W Ustawieniach włącz opcję „Automatycznie wybieraj sieć”, aby telefon mógł znaleźć sieć współpracującą z satelitą"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Włącz"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Wróć"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Oczekiwanie…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Skonfiguruj ponownie odblokowywanie odciskiem palca"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Ten odcisk palca (<xliff:g id="FINGERPRINT">%s</xliff:g>) nie jest już rozpoznawany."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Te odciski palców (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) nie są już rozpoznawane."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 76a8dc1..71b334e 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormir"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Não perturbe (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gerenciada pelo app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ativada"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desativada"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualquer agenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Enviar e receber mensagens sem uma rede móvel ou Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Ative a opção \"Selecionar a rede automaticamente\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Ative a opção \"Selecionar a rede automaticamente\" nas configurações para que o smartphone encontre uma rede que funcione com satélite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ativar"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Voltar"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 86e0fcd..4d5ff47 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1939,6 +1939,7 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormir"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Não incomodar (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gerido por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ativada"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desativada"</string>
@@ -2431,6 +2432,54 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ativar"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Retroceder"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configure o Desbloqueio por impressão digital novamente"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Já não é possível reconhecer <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Já não é possível reconhecer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 76a8dc1..71b334e 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormir"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Não perturbe (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gerenciada pelo app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ativada"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desativada"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualquer agenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Enviar e receber mensagens sem uma rede móvel ou Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Ative a opção \"Selecionar a rede automaticamente\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Ative a opção \"Selecionar a rede automaticamente\" nas configurações para que o smartphone encontre uma rede que funcione com satélite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ativar"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Voltar"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 384d1b3..6e43d31 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Eveniment"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Somn"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Nu deranja (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gestionat de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activată"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Dezactivată"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Orice calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> dezactivează anumite sunete"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"A apărut o problemă internă pe dispozitiv, iar acesta poate fi instabil până la revenirea la setările din fabrică."</string>
@@ -2183,7 +2183,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Conexiunea Bluetooth va rămâne activată în modul Avion"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"Se încarcă"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # fișier}few{{file_name} + # fișiere}other{{file_name} + # de fișiere}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nu există persoane recomandate pentru permiterea accesului"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nu există persoane recomandate pentru trimitere"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista de aplicații"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Permisiunea de înregistrare nu a fost acordată aplicației, dar aceasta poate să înregistreze conținut audio prin intermediul acestui dispozitiv USB."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Pornire"</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Trimite și primește mesaje fără o rețea mobilă sau Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Deschide Mesaje"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cum funcționează"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Activează opțiunea Selectează automat rețeaua"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Activează opțiunea Selectează automat rețeaua în Setări pentru ca telefonul să găsească o rețea compatibilă cu satelitul"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activează"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Înapoi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"În așteptare..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurează din nou Deblocarea cu amprenta"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu mai poate fi recunoscută."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu mai pot fi recunoscute."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index f7e3610..b23a44b 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1940,13 +1940,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Выходные"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Мероприятие"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Время сна"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Не беспокоить (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Под управлением приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Включено"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Отключено"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Любой календарь"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> приглушает некоторые звуки."</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Произошла внутренняя ошибка, и устройство может работать нестабильно, пока вы не выполните сброс настроек."</string>
@@ -2428,15 +2428,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Отправляйте и получайте сообщения без подключения к мобильной сети или Wi-Fi."</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Открыть Сообщения"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Узнать принцип работы"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Включите автоматический выбор сети"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Чтобы ваш телефон мог найти сеть, которая поддерживает спутниковую связь, включите в настройках параметр \"Выбирать сеть автоматически\"."</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Включить"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Назад"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Обработка…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Настройте разблокировку по отпечатку пальца заново"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Отпечаток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больше нельзя распознать."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Отпечатки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больше нельзя распознать."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index ea404f1..db82c6c 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"සති අන්තය"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"සිදුවීම"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"නිදා ගනිමින්"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"බාධා නොකරන්න (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> විසින් කළමනාකරණය කරයි"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ක්රියාත්මකයි"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ක්රියාවිරහිතයි"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="END">%2$s</xliff:g> සිට <xliff:g id="START">%1$s</xliff:g> දක්වා"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ඕනෑම දින දර්ශනයක්"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> සමහර ශබ්ද නිහඬ කරමින්"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"ඔබේ උපාංගය සමගින් ගැටලුවක් ඇති අතර, ඔබේ කර්මාන්තශාලා දත්ත යළි සකසන තෙක් එය අස්ථායි විය හැකිය."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"ජංගම හෝ Wi-Fi ජාලයකින් තොරව පණිවිඩ යැවීම සහ ලැබීම"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages විවෘත කරන්න"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"එය ක්රියා කරන ආකාරය"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"ස්වයංක්රීයව ජාලය තෝරන්න\" ක්රියාත්මක කරන්න"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ඔබේ දුරකථනයට චන්ද්රිකාව සමග ක්රියා කරන ජාලයක් සොයා ගැනීමට හැකි වන පරිදි සැකසීම් තුළ \"ස්වයංක්රීයව ජාලය තෝරන්න\" ක්රියාත්මක කරන්න"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ක්රියාත්මක කරන්න"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ආපසු යන්න"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"පොරොත්තුයි..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ඇඟිලි සලකුණු අගුලු හැරීම නැවත සකසන්න"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index eeb3081..cbabfb6 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1940,13 +1940,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Víkend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Udalosť"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spánok"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Režim bez vyrušení (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Spravované aplikáciou <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Zapnuté"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Vypnuté"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Ľubovoľný kalendár"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vypína niektoré zvuky"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Vo vašom zariadení došlo k internému problému. Môže byť nestabilné, kým neobnovíte jeho výrobné nastavenia."</string>
@@ -2428,15 +2428,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Odosielajte a prijímajte správy bez mobilnej siete či siete Wi‑Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvoriť Správy"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ako to funguje"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Zapnite Vyberať sieť automaticky"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Zapnite v Nastaveniach možnosť Vyberať sieť automaticky, aby telefón mohol nájsť sieť, ktorá spolupracuje so satelitom"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Zapnúť"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Prejsť späť"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Nespracovaná…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Znova nastavte odomknutie odtlačkom prsta"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> sa už nedari rozpoznať."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> sa už nedari rozpoznať."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 514ad16..d7178c8 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1940,13 +1940,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Konec tedna"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Dogodek"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spanje"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ne moti (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Upravlja <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Vklopljeno"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Izklopljeno"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> do <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kateri koli koledar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> izklaplja nekatere zvoke"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Vaša naprava ima notranjo napako in bo morda nestabilna, dokler je ne ponastavite na tovarniške nastavitve."</string>
@@ -2428,15 +2428,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Pošiljanje in prejemanje sporočil brez mobilnega omrežja ali omrežja Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Odpri Sporočila"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako deluje"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Vklopite »Samodejno izberi omrežje«"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"V nastavitvah vklopite možnost »Samodejno izberi omrežje«, da bo telefon lahko našel omrežje, ki deluje s satelitsko povezavo"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Vklopi"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Nazaj"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"V teku …"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vnovična nastavitev odklepanja s prstnim odtisom"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Odtisa »<xliff:g id="FINGERPRINT">%s</xliff:g>« ni več mogoče prepoznati."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Odtisov »<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>« in »<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>« ni več mogoče prepoznati."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 8d535b9..42356bf 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fundjava"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Ngjarje"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Në gjumë"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Mos shqetëso (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Menaxhohet nga <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aktivizuar"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Çaktivizuar"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Çdo kalendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> po çaktivizon disa tinguj"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Ka një problem të brendshëm me pajisjen tënde. Ajo mund të jetë e paqëndrueshme derisa të rivendosësh të dhënat në gjendje fabrike."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Dërgo dhe merr mesazhe pa një rrjet celular ose Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Hap \"Mesazhet\""</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Si funksionon"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Aktivizo \"Zgjidh automatikisht rrjetin\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Aktivizo \"Zgjidh automatikisht rrjetin\" te \"Cilësimet\" që telefoni yt të mund të gjejë një rrjet që funksionon me satelitin"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivizo"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Kthehu prapa"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Në pritje..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\""</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk mund të njihet më."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk mund të njihen më."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index af75a5c..10fa5f8 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1939,13 +1939,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Викенд"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Догађај"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Спавање"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Не узнемиравај (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Управља: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Укључено"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Искључено"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Било који календар"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> искључује неке звуке"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Дошло је до интерног проблема у вези са уређајем и можда ће бити нестабилан док не обавите ресетовање на фабричка подешавања."</string>
@@ -2427,15 +2427,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Шаљите и примајте поруке без мобилне или WiFi мреже"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Отвори Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Принцип рада"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Укључите опцију Аутоматски изабери мрежу"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Укључите опцију Аутоматски изабери мрежу у Подешавањима да би телефон могао да пронађе мрежу која ради са сателитом"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Укључи"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Назад"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"На чекању..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поново подесите откључавање отиском прста"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> више не може да се препозна."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> више не могу да се препознају."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 0cff2e5..857b060 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"I helgen"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Händelse"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sover"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Stör ej (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Hanteras av <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"På"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Av"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> till <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Alla kalendrar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> stänger av vissa ljud"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Ett internt problem har uppstått i enheten, och det kan hända att problemet kvarstår tills du återställer standardinställningarna."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Skicka och ta emot meddelanden utan ett mobil- eller wifi-nätverk"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Öppna Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Så fungerar det"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Aktivera Välj nätverk automatiskt"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Aktivera Välj nätverk automatiskt i inställningarna så att telefonen kan hitta ett nätverk som fungerar med satellit"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivera"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Tillbaka"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Väntar …"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurera fingeravtryckslås igen"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index bf51892..d46fa08 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Wikendi"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Tukio"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Kulala"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Usinisumbue (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Inadhibitiwa na <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Imewashwa"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Imezimwa"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> hadi <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kalenda yoyote"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> inazima baadhi ya sauti"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Kuna hitilafu ya ndani ya kifaa chako, na huenda kisiwe thabiti mpaka urejeshe mipangilio ya kiwandani."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Tuma na upokee ujumbe bila kutumia mtandao wa simu wala Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Fungua Programu ya Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Utaratibu wake"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Washa kipengele cha \"Chagua mtandao kiotomatiki\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Washa kipengele cha \"Chagua mtandao kiotomatiki\" katika Mipangilio ili simu yako iweze kupata mtandao unaotumia setilaiti"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Washa"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Rudi nyuma"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Inashughulikiwa..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Weka tena mipangilio ya Kufungua kwa Alama ya Kidole"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> haitambuliki tena."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> havitambuliki tena."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 8ff19a9..32fefac 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1937,14 +1937,14 @@
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"வார இரவு"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"வார இறுதி"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"நிகழ்வு"</string>
- <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"உறக்கத்தில்"</string>
+ <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"உறங்குதல்"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"தொந்தரவு செய்ய வேண்டாம் (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"நிர்வகிப்பது: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ஆன்"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ஆஃப்"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> முதல் <xliff:g id="END">%2$s</xliff:g> வரை"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ஏதேனும் கேலெண்டர்"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> சில ஒலிகளை முடக்குகிறது"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"சாதனத்தில் அகச் சிக்கல் இருக்கிறது, அதனை ஆரம்பநிலைக்கு மீட்டமைக்கும் வரை நிலையற்று இயங்கலாம்."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"மொபைல்/வைஃபை நெட்வொர்க் இல்லாமல் மெசேஜ்களை அனுப்பலாம், பெறலாம்"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ஆப்ஸைத் திறக்கவும்"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"இது செயல்படும் விதம்"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"நெட்வொர்க்கைத் தானாகத் தேர்ந்தெடு\" என்பதை இயக்குங்கள்"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"அமைப்புகளில் \"நெட்வொர்க்கைத் தானாகத் தேர்ந்தெடு\" என்பதை இயக்கினால் செயற்கைக்கோள் மூலம் இயங்கும் நெட்வொர்க்கை உங்கள் மொபைல் கண்டறிய முடியும்"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"இயக்கு"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"பின்செல்"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"நிலுவையிலுள்ளது..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>ஐ இனி அடையாளம் காண முடியாது."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ஆகியவற்றை இனி அடையாளம் காண முடியாது."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 1d9e00c..8500e9d 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"వారాంతం"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ఈవెంట్"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"స్లీప్ మోడ్"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"అంతరాయం కలిగించవద్దు (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ద్వారా మేనేజ్ చేయబడుతోంది"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ఆన్లో ఉంది"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ఆఫ్లో ఉంది"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> నుండి <xliff:g id="END">%2$s</xliff:g> వరకు"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ఏదైనా క్యాలెండర్"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> కొన్ని ధ్వనులను మ్యూట్ చేస్తోంది"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"మీ పరికరంతో అంతర్గత సమస్య ఏర్పడింది మరియు మీరు ఫ్యాక్టరీ డేటా రీసెట్ చేసే వరకు అస్థిరంగా ఉంటుంది."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"మొబైల్ లేదా Wi-Fi నెట్వర్క్ లేకుండా మెసేజ్లను పంపండి, స్వీకరించండి"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Messagesను తెరవండి"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ఇది ఎలా పని చేస్తుంది"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"నెట్వర్క్ను ఆటోమేటిక్గా ఎంచుకోండి\" అనే ఆప్షన్ను ఆన్ చేయండి"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"సెట్టింగ్లలో \"నెట్వర్క్ను ఆటోమేటిక్గా ఎంచుకోండి\" అనే ఆప్షన్ను ఆన్ చేయండి, తద్వారా మీ ఫోన్ శాటిలైట్తో పనిచేసే నెట్వర్క్ను కనుగొనగలదు"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ఆన్ చేయండి"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"వెనుకకు వెళ్లండి"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"పెండింగ్లో ఉంది..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"వేలిముద్ర అన్లాక్ను మళ్లీ సెటప్ చేయండి"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>ను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>లను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 90a90ee..a1c7b4f 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"สุดสัปดาห์"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"กิจกรรม"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"นอนหลับ"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"ห้ามรบกวน (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"จัดการโดย <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"เปิด"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ปิด"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>ถึง<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ปฏิทินทั้งหมด"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> กำลังปิดเสียงบางรายการ"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"อุปกรณ์ของคุณเกิดปัญหาภายในเครื่อง อุปกรณ์อาจทำงานไม่เสถียรจนกว่าคุณจะรีเซ็ตข้อมูลเป็นค่าเริ่มต้น"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"รับและส่งข้อความโดยไม่ต้องใช้เครือข่ายมือถือหรือ Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"เปิด Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"วิธีการทำงาน"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"เปิด \"เลือกเครือข่ายโดยอัตโนมัติ\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"เปิด \"เลือกเครือข่ายโดยอัตโนมัติ\" ในการตั้งค่าเพื่อให้โทรศัพท์ค้นหาเครือข่ายที่ใช้งานร่วมกับดาวเทียมได้"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"เปิด"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ย้อนกลับ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"รอดำเนินการ..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ตั้งค่าการปลดล็อกด้วยลายนิ้วมืออีกครั้ง"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT">%s</xliff:g> อีกต่อไป"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> อีกต่อไป"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index f4df0e2..f15d952 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Pag-sleep"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Huwag Istorbohin (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Pinapamahalaan ng <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Naka-on"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Naka-off"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>, <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> patungong <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Anumang kalendaryo"</string>
<string name="muted_by" msgid="91464083490094950">"Minu-mute ng <xliff:g id="THIRD_PARTY">%1$s</xliff:g> ang ilang tunog"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"May internal na problema sa iyong device, at maaaring hindi ito maging stable hanggang sa i-reset mo ang factory data."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Magpadala at tumanggap ng mga mensahe nang walang mobile o Wi-Fi network"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Buksan ang Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Paano ito gumagana"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"I-on ang \"Awtomatikong pumili ng network\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"I-on ang \"Awtomatikong piliin ang network\" sa Mga Setting para mahanap ng iyong telepono ang isang network na gumagana sa satellite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"I-on"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Bumalik"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Nakabinbin..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"I-set up ulit ang Pag-unlock Gamit ang Fingerprint"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Hindi na makilala ang <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Hindi na makilala ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 77c3ee2..39a005f 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Hafta sonu"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Etkinlik"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Uyku"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Rahatsız Etmeyin (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> tarafından yönetiliyor"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Açık"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Kapalı"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Tüm takvimler"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> bazı sesleri kapatıyor"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Cihazınızla ilgili dahili bir sorun oluştu ve fabrika verilerine sıfırlama işlemi gerçekleştirilene kadar kararsız çalışabilir."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Mobil veya kablosuz ağ kullanmadan mesaj gönderip alın"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajlar\'ı aç"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"İşleyiş şekli"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"Ağı otomatik seç\"i etkinleştirin"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Telefonunuzun uyduyla çalışan bir ağ bulabilmesi için Ayarlar\'da \"Ağı otomatik seç\"i etkinleştirin"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Etkinleştir"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Geri dön"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Bekliyor..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Parmak İzi Kilidi\'ni tekrar kurun"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artık tanınamayacak."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artık tanınamayacak."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 2f1a1d5..3b9cd19 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1940,13 +1940,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"На вихідних"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Подія"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Під час сну"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Не турбувати (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Керує додаток <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Увімкнено"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Вимкнено"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"З усіх календарів"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> вимикає деякі звуки"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Через внутрішню помилку ваш пристрій може працювати нестабільно. Відновіть заводські налаштування."</string>
@@ -2428,15 +2428,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Надсилайте й отримуйте текстові повідомлення без мобільної мережі або Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Відкрийте Повідомлення"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як це працює"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Увімкніть опцію \"Вибирати мережу автоматично\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"У налаштуваннях увімкніть опцію \"Вибирати мережу автоматично\", щоб телефон міг знайти мережу, яка працює через супутник"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Увімкнути"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Назад"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Обробка…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Налаштуйте розблокування відбитком пальця повторно"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Відбиток пальця <xliff:g id="FINGERPRINT">%s</xliff:g> більше не розпізнається."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Відбитки пальців <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> і <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> більше не розпізнаються."</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 6c78283..679f102 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ویک اینڈ"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ایونٹ"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"سونا"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"ڈسٹرب نہ کریں (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے زیر انتظام ہے"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"آن ہے"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"آف ہے"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> تا <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"کوئی بھی کیلنڈر"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> کچھ آوازوں کو خاموش کر رہا ہے"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"آپ کے آلہ میں ایک داخلی مسئلہ ہے اور جب تک آپ فیکٹری ڈیٹا کو دوبارہ ترتیب نہیں دے دیتے ہیں، ہوسکتا ہے کہ یہ غیر مستحکم رہے۔"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"موبائل یا Wi-Fi نیٹ ورک کے بغیر پیغامات بھیجیں اور موصول کریں"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"پیغامات ایپ کو کھولیں"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"اس کے کام کرنے کا طریقہ"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"\"خودکار طور پر نیٹ ورک منتخب کریں\" کو آن کریں"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"ترتیبات میں \"خودکار طور پر نیٹ ورک منتخب کریں\" کو آن کریں تاکہ آپ کا فون سیٹلائٹ کے ساتھ کام کرنے والے نیٹ ورک کو تلاش کر سکے"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"آن کریں"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"واپس جائیں"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"زیر التواء..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"فنگر پرنٹ اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> مزید پہچانا نہیں جا سکتا۔"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> کو مزید پہچانا نہیں جا سکتا۔"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index ac70b93..d7620e1 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Dam olish kunlari"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Tadbir"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Uyquda"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Bezovta qilinmasin (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> tomonidan boshqariladi"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Yoniq"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Oʻchiq"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Har qanday taqvim"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ayrim tovushlarni ovozsiz qilgan"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. U zavod sozlamalari tiklanmaguncha barqaror ishlamasligi mumkin."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Mobil yoki Wi-Fi tarmoq blan aloqa yoʻqligida xabar yuboring va qabul qiling"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Xabarlar ilovasini ochish"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ishlash tartibi"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"“Tarmoqni avtomatik tanlash” sozlamasini yoqing"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Telefoningiz sputnik bilan ishlaydigan tarmoqni topishi uchun Sozlamalar orqali “Tarmoqni avtomatik tanlash” sozlamasini yoqing"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Yoqish"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Orqaga"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Kutilmoqda..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmoq izi bilan ochish funksiyasini qayta sozlang"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> endi tanilmaydi."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> endi tanilmaydi."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index d4551b1..663078b 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Cuối tuần"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Sự kiện"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Ngủ"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Không làm phiền (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Do <xliff:g id="APP_NAME">%1$s</xliff:g> quản lý"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Bật"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Tắt"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> đến <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bất kỳ lịch nào"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> đang tắt một số âm thanh"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Đã xảy ra sự cố nội bộ với thiết bị của bạn và thiết bị có thể sẽ không ổn định cho tới khi bạn thiết lập lại dữ liệu ban đầu."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Gửi và nhận tin nhắn mà không cần mạng di động hoặc Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Mở ứng dụng Tin nhắn"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cách hoạt động"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Bật tính năng \"Tự động chọn mạng\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Bật tính năng \"Tự động chọn mạng\" trong phần Cài đặt để điện thoại có thể tìm thấy mạng hoạt động với vệ tinh"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Bật"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Quay lại"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Đang chờ xử lý..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Thiết lập lại tính năng Mở khoá bằng vân tay"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Không nhận dạng được <xliff:g id="FINGERPRINT">%s</xliff:g> nữa."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Không nhận dạng được <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nữa."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 22f80bd..6007d1e 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"周末"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"活动"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"睡眠"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"勿扰 (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"由<xliff:g id="APP_NAME">%1$s</xliff:g>管理"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"已启用"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"已停用"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>到<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"所有日历"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>正在将某些音效设为静音"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"您的设备内部出现了问题。如果不将设备恢复出厂设置,设备运行可能会不稳定。"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"即使没有移动网络或 WLAN 网络,也能收发消息"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"打开“信息”应用"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"运作方式"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"开启“自动选择网络”"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"在“设置”中开启“自动选择网络”,以便手机找到可与卫星配合使用的网络"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"开启"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"返回"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待归档…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新设置指纹解锁功能"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"系统无法再识别<xliff:g id="FINGERPRINT">%s</xliff:g>。"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"系统无法再识别<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 3f4c175..fcf50e4 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"週末"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"活動"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"睡眠"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"請勿騷擾 (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"由<xliff:g id="APP_NAME">%1$s</xliff:g>管理"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"已開啟"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"已關閉"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>至<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"任何日曆"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>正將某些音效設為靜音"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"你裝置的系統發生問題,回復原廠設定後即可解決該問題。"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"在沒有流動網絡或 Wi-Fi 網絡的情況下收發短訊"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"開啟「自動選取網絡」"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"前往設定開啟「自動選取網絡」,讓手機可以尋找可使用衛星的網絡"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"開啟"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"返回"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定「指紋解鎖」功能"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"無法再辨識<xliff:g id="FINGERPRINT">%s</xliff:g>。"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"無法再辨識<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 90cede8..e186e7c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"週末"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"活動"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"睡眠"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"零打擾 (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"由「<xliff:g id="APP_NAME">%1$s</xliff:g>」管理"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"已啟用"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"已停用"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g>到<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"任何日曆"</string>
<string name="muted_by" msgid="91464083490094950">"「<xliff:g id="THIRD_PARTY">%1$s</xliff:g>」正在關閉部分音效"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"你的裝置發生內部問題,必須將裝置恢復原廠設定才能解除不穩定狀態。"</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"即使沒有行動或 Wi-Fi 網路,還是可以收發訊息"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」應用程式"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"開啟「自動選取網路」"</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"請前往「設定」開啟「自動選取網路」,讓手機可以找到支援衛星的網路"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"開啟"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"返回"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定指紋解鎖"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"系統無法再辨識「<xliff:g id="FINGERPRINT">%s</xliff:g>」。"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"系統無法再辨識「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 5448fcd..69ec5ed 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1938,13 +1938,13 @@
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Ngempelasonto"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Umcimbi"</string>
<string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Ulele"</string>
+ <string name="zen_mode_implicit_name" msgid="177586786232302019">"Ungaphazamisi (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Iphethwe yi-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Kuvuliwe"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Kuvaliwe"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>, <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"U-<xliff:g id="START">%1$s</xliff:g> ukuya ku-<xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Noma iyiphi ikhalenda"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ithulisa eminye imisindo"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Kukhona inkinga yangaphakathi ngedivayisi yakho, futhi ingase ibe engazinzile kuze kube yilapho usetha kabusha yonke idatha."</string>
@@ -2426,15 +2426,59 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Thumela futhi wamukele imilayezo ngaphandle kwenethiwekhi yeselula noma yeWiFi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Vula Imilayezo"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Indlela esebenza ngayo"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Vula okuthi \"Khetha inethiwekhi ngokuzenzekela\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Vula okuthi \"Khetha inethiwekhi ngokuzenzekela\" kumasethingi ukuze ifoni yakho ithole inethiwekhi esebenza nesathelayithi"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Vula"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Iya emuva"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ilindile..."</string>
+ <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
+ <skip />
+ <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
+ <skip />
+ <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
+ <skip />
+ <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
+ <skip />
+ <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
+ <skip />
+ <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
+ <skip />
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setha Ukuvula ngesigxivizo somunwe futhi"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> angeke isaziwa."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> angeke isaziwa."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 092d2a72..e6dedce 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4418,6 +4418,10 @@
<declare-styleable name="InputMethod_Subtype">
<!-- The name of the subtype. -->
<attr name="label" />
+ <!-- The layout label of the subtype.
+ {@link android.view.inputmethod.InputMethodSubtype#getLayoutDisplayName} returns the
+ value specified in this attribute. -->
+ <attr name="layoutLabel" format="reference" />
<!-- The icon of the subtype. -->
<attr name="icon" />
<!-- The locale of the subtype. This string should be a locale (for example en_US and fr_FR)
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 0c28ea4..70cc5f1 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -125,6 +125,8 @@
<public name="supplementalDescription"/>
<!-- @FlaggedApi("android.security.enable_intent_matching_flags") -->
<public name="intentMatchingFlags"/>
+ <!-- @FlaggedApi(android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP_API) -->
+ <public name="layoutLabel"/>
</staging-public-group>
<staging-public-group type="id" first-id="0x01b60000">
diff --git a/core/res/res/values/stoppable_fgs_system_apps.xml b/core/res/res/values/stoppable_fgs_system_apps.xml
new file mode 100644
index 0000000..165ff61
--- /dev/null
+++ b/core/res/res/values/stoppable_fgs_system_apps.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+ <!-- A list of system apps whose FGS can be stopped in the task manager. -->
+ <string-array translatable="false" name="stoppable_fgs_system_apps">
+ </string-array>
+ <!-- stoppable_fgs_system_apps which is supposed to be overridden by vendor -->
+ <string-array translatable="false" name="vendor_stoppable_fgs_system_apps">
+ </string-array>
+</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e23e665..c13fdb1 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1766,6 +1766,11 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=140]-->
<string name="permdesc_nearby_wifi_devices">Allows the app to advertise, connect, and determine the relative position of nearby Wi\u2011Fi devices</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50]-->
+ <string name="permlab_ranging">determine relative position between nearby devices</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=120]-->
+ <string name="permdesc_ranging">Allow the app to determine relative position between nearby devices</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_preferredPaymentInfo">Preferred NFC Payment Service Information</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fec8bbb..db81a3b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1306,6 +1306,8 @@
<java-symbol type="array" name="vendor_policy_exempt_apps" />
<java-symbol type="array" name="cloneable_apps" />
<java-symbol type="array" name="config_securityStatePackages" />
+ <java-symbol type="array" name="stoppable_fgs_system_apps" />
+ <java-symbol type="array" name="vendor_stoppable_fgs_system_apps" />
<java-symbol type="drawable" name="default_wallpaper" />
<java-symbol type="drawable" name="default_lock_wallpaper" />
@@ -5647,7 +5649,6 @@
<java-symbol type="drawable" name="ic_zen_mode_type_schedule_calendar" />
<java-symbol type="drawable" name="ic_zen_mode_type_schedule_time" />
<java-symbol type="drawable" name="ic_zen_mode_type_theater" />
- <java-symbol type="drawable" name="ic_zen_mode_type_unknown" />
<java-symbol type="drawable" name="ic_zen_mode_type_special_dnd" />
<!-- System notification for background user sound -->
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 24f6cea..8d045f8 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -26,6 +26,7 @@
import static android.view.Display.INVALID_DISPLAY;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -59,6 +60,7 @@
import android.app.servertransaction.StopActivityItem;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -67,7 +69,11 @@
import android.hardware.display.VirtualDisplay;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.Looper;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -129,6 +135,9 @@
@Rule(order = 1)
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
private ActivityWindowInfoListener mActivityWindowInfoListener;
private WindowTokenClientController mOriginalWindowTokenClientController;
private Configuration mOriginalAppConfig;
@@ -912,6 +921,32 @@
}
/**
+ * Verifies that {@link ActivityThread#handleApplicationInfoChanged} does send updates to the
+ * system context, when given the system application info.
+ */
+ @RequiresFlagsEnabled(android.content.res.Flags.FLAG_SYSTEM_CONTEXT_HANDLE_APP_INFO_CHANGED)
+ @Test
+ public void testHandleApplicationInfoChanged_systemContext() {
+ Looper.prepare();
+ final var systemThread = ActivityThread.createSystemActivityThreadForTesting();
+
+ final Context systemContext = systemThread.getSystemContext();
+ final var appInfo = systemContext.getApplicationInfo();
+ // sourceDir must not be null, and contain at least a '/', for handleApplicationInfoChanged.
+ appInfo.sourceDir = "/";
+
+ // Create a copy of the application info.
+ final var newAppInfo = new ApplicationInfo(appInfo);
+ newAppInfo.sourceDir = "/";
+ assertWithMessage("New application info is a separate instance")
+ .that(systemContext.getApplicationInfo()).isNotSameInstanceAs(newAppInfo);
+
+ systemThread.handleApplicationInfoChanged(newAppInfo);
+ assertWithMessage("Application info was updated successfully")
+ .that(systemContext.getApplicationInfo()).isSameInstanceAs(newAppInfo);
+ }
+
+ /**
* Calls {@link ActivityThread#handleActivityConfigurationChanged(ActivityClientRecord,
* Configuration, int, ActivityWindowInfo)} to try to push activity configuration to the
* activity for the given sequence number.
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
index 31a4f16..911b7ce 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
@@ -120,7 +120,8 @@
doReturn(newDisplayInfo).when(mIDisplayManager).getDisplayInfo(123);
mDisplayManager.registerDisplayListener(mListener, mHandler,
- DisplayManager.EVENT_FLAG_DISPLAY_CHANGED, null /* packageName */);
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED,
+ null /* packageName */);
mController.onDisplayChanged(123);
mHandler.runWithScissors(() -> { }, 0);
diff --git a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java
index 5a0dacb..9552c88 100644
--- a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java
+++ b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java
@@ -55,9 +55,10 @@
@RunWith(AndroidJUnit4.class)
public class DisplayManagerGlobalTest {
- private static final long ALL_DISPLAY_EVENTS = DisplayManager.EVENT_FLAG_DISPLAY_ADDED
- | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED;
+ private static final long ALL_DISPLAY_EVENTS =
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED;
@Mock
private IDisplayManager mDisplayManager;
@@ -127,19 +128,22 @@
int displayId = 1;
mDisplayManagerGlobal.registerDisplayListener(mListener, mHandler,
- ALL_DISPLAY_EVENTS & ~DisplayManager.EVENT_FLAG_DISPLAY_ADDED, null);
+ ALL_DISPLAY_EVENTS
+ & ~DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED, null);
callback.onDisplayEvent(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
waitForHandler();
Mockito.verifyZeroInteractions(mListener);
mDisplayManagerGlobal.registerDisplayListener(mListener, mHandler,
- ALL_DISPLAY_EVENTS & ~DisplayManager.EVENT_FLAG_DISPLAY_CHANGED, null);
+ ALL_DISPLAY_EVENTS
+ & ~DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED, null);
callback.onDisplayEvent(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
waitForHandler();
Mockito.verifyZeroInteractions(mListener);
mDisplayManagerGlobal.registerDisplayListener(mListener, mHandler,
- ALL_DISPLAY_EVENTS & ~DisplayManager.EVENT_FLAG_DISPLAY_REMOVED, null);
+ ALL_DISPLAY_EVENTS
+ & ~DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED, null);
callback.onDisplayEvent(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
waitForHandler();
Mockito.verifyZeroInteractions(mListener);
@@ -162,22 +166,25 @@
public void testDisplayManagerGlobalRegistersWithDisplayManager_WhenThereAreListeners()
throws RemoteException {
mDisplayManagerGlobal.registerDisplayListener(mListener, mHandler,
- DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS, null);
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED,
+ null);
InOrder inOrder = Mockito.inOrder(mDisplayManager);
inOrder.verify(mDisplayManager)
.registerCallbackWithEventMask(mCallbackCaptor.capture(),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED));
mDisplayManagerGlobal.registerNativeChoreographerForRefreshRateCallbacks();
inOrder.verify(mDisplayManager)
.registerCallbackWithEventMask(mCallbackCaptor.capture(),
- eq(ALL_DISPLAY_EVENTS | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(ALL_DISPLAY_EVENTS
+ | DisplayManagerGlobal
+ .INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED));
mDisplayManagerGlobal.unregisterNativeChoreographerForRefreshRateCallbacks();
inOrder.verify(mDisplayManager)
.registerCallbackWithEventMask(mCallbackCaptor.capture(),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED));
mDisplayManagerGlobal.unregisterDisplayListener(mListener);
inOrder.verify(mDisplayManager)
@@ -196,10 +203,12 @@
// One listener listens on add/remove, and the other one listens on change.
mDisplayManagerGlobal.registerDisplayListener(mListener, mHandler,
- DisplayManager.EVENT_FLAG_DISPLAY_ADDED
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED, null /* packageName */);
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED,
+ null /* packageName */);
mDisplayManagerGlobal.registerDisplayListener(mListener2, mHandler,
- DisplayManager.EVENT_FLAG_DISPLAY_CHANGED, null /* packageName */);
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED,
+ null /* packageName */);
mDisplayManagerGlobal.handleDisplayChangeFromWindowManager(321);
waitForHandler();
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index 3b27fc0..e4e965f 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -21,6 +21,8 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.timeout;
@@ -61,9 +63,13 @@
private UiDevice mUiDevice;
private Executor mExec = Executors.newSingleThreadExecutor();
@Mock
- private PowerManager.OnThermalStatusChangedListener mListener1;
+ private PowerManager.OnThermalStatusChangedListener mStatusListener1;
@Mock
- private PowerManager.OnThermalStatusChangedListener mListener2;
+ private PowerManager.OnThermalStatusChangedListener mStatusListener2;
+ @Mock
+ private PowerManager.OnThermalHeadroomChangedListener mHeadroomListener1;
+ @Mock
+ private PowerManager.OnThermalHeadroomChangedListener mHeadroomListener2;
private static final long CALLBACK_TIMEOUT_MILLI_SEC = 5000;
private native Parcel nativeObtainPowerSaveStateParcel(boolean batterySaverEnabled,
boolean globalBatterySaverEnabled, int locationMode, int soundTriggerMode,
@@ -245,53 +251,90 @@
// Initial override status is THERMAL_STATUS_NONE
int status = PowerManager.THERMAL_STATUS_NONE;
// Add listener1
- mPm.addThermalStatusListener(mExec, mListener1);
- verify(mListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ mPm.addThermalStatusListener(mExec, mStatusListener1);
+ verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).onThermalStatusChanged(status);
- reset(mListener1);
+ reset(mStatusListener1);
status = PowerManager.THERMAL_STATUS_SEVERE;
mUiDevice.executeShellCommand("cmd thermalservice override-status "
+ Integer.toString(status));
- verify(mListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).onThermalStatusChanged(status);
- reset(mListener1);
+ reset(mStatusListener1);
// Add listener1 again
try {
- mPm.addThermalStatusListener(mListener1);
+ mPm.addThermalStatusListener(mStatusListener1);
fail("Expected exception not thrown");
} catch (IllegalArgumentException expectedException) {
}
// Add listener2 on main thread.
- mPm.addThermalStatusListener(mListener2);
- verify(mListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ mPm.addThermalStatusListener(mStatusListener2);
+ verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).onThermalStatusChanged(status);
- reset(mListener2);
+ reset(mStatusListener2);
status = PowerManager.THERMAL_STATUS_MODERATE;
mUiDevice.executeShellCommand("cmd thermalservice override-status "
+ Integer.toString(status));
- verify(mListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).onThermalStatusChanged(status);
- verify(mListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).onThermalStatusChanged(status);
- reset(mListener1);
- reset(mListener2);
+ reset(mStatusListener1);
+ reset(mStatusListener2);
// Remove listener1
- mPm.removeThermalStatusListener(mListener1);
+ mPm.removeThermalStatusListener(mStatusListener1);
// Remove listener1 again
try {
- mPm.removeThermalStatusListener(mListener1);
+ mPm.removeThermalStatusListener(mStatusListener1);
fail("Expected exception not thrown");
} catch (IllegalArgumentException expectedException) {
}
status = PowerManager.THERMAL_STATUS_LIGHT;
mUiDevice.executeShellCommand("cmd thermalservice override-status "
+ Integer.toString(status));
- verify(mListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(0)).onThermalStatusChanged(status);
- verify(mListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).onThermalStatusChanged(status);
}
+ /**
+ * Confirm that we can add/remove thermal headroom listener.
+ */
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_THERMAL_THRESHOLDS_CALLBACK)
+ public void testThermalHeadroomCallback() throws Exception {
+ float headroom = mPm.getThermalHeadroom(0);
+ // If the device doesn't support thermal headroom, return early
+ if (Float.isNaN(headroom)) {
+ return;
+ }
+ // Add listener1
+ mPm.addThermalHeadroomListener(mExec, mHeadroomListener1);
+ verify(mHeadroomListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onThermalHeadroomChanged(anyInt(), anyInt(), anyInt(), any());
+ reset(mHeadroomListener1);
+ // Add listener1 again
+ try {
+ mPm.addThermalHeadroomListener(mHeadroomListener1);
+ fail("Expected exception not thrown");
+ } catch (IllegalArgumentException expectedException) {
+ }
+ // Add listener2 on main thread.
+ mPm.addThermalHeadroomListener(mHeadroomListener2);
+ verify(mHeadroomListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onThermalHeadroomChanged(anyInt(), anyInt(), anyInt(), any());
+ reset(mHeadroomListener2);
+ // Remove listener1
+ mPm.removeThermalHeadroomListener(mHeadroomListener1);
+ // Remove listener1 again
+ try {
+ mPm.removeThermalHeadroomListener(mHeadroomListener1);
+ fail("Expected exception not thrown");
+ } catch (IllegalArgumentException expectedException) {
+ }
+ }
+
@Test
public void testGetThermalHeadroom() throws Exception {
float headroom = mPm.getThermalHeadroom(0);
diff --git a/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java b/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
index 00ffda8..a47a3e0 100644
--- a/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
+++ b/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
@@ -161,7 +161,7 @@
mBackAnimationController.onBackInvoked();
// verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
// getInputMethodManager is called from ImeBackAnimationController)
- verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
+ verify(mViewRootInsetsControllerHost, times(2)).getInputMethodManager();
// verify that ImeBackAnimationController does not take control over IME insets
verify(mInsetsController, never()).controlWindowInsetsAnimation(anyInt(), any(), any(),
anyBoolean(), anyLong(), any(), anyInt(), anyBoolean());
@@ -180,7 +180,7 @@
mBackAnimationController.onBackInvoked();
// verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
// getInputMethodManager is called from ImeBackAnimationController)
- verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
+ verify(mViewRootInsetsControllerHost, times(2)).getInputMethodManager();
// verify that ImeBackAnimationController does not take control over IME insets
verify(mInsetsController, never()).controlWindowInsetsAnimation(anyInt(), any(), any(),
anyBoolean(), anyLong(), any(), anyInt(), anyBoolean());
@@ -300,7 +300,7 @@
mBackAnimationController.onBackInvoked();
// verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
// getInputMethodManager is called from ImeBackAnimationController)
- verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
+ verify(mViewRootInsetsControllerHost, times(2)).getInputMethodManager();
});
}
diff --git a/core/tests/coretests/src/android/view/RoundScrollbarRendererTest.java b/core/tests/coretests/src/android/view/RoundScrollbarRendererTest.java
index 262bd5c..0f17f9c 100644
--- a/core/tests/coretests/src/android/view/RoundScrollbarRendererTest.java
+++ b/core/tests/coretests/src/android/view/RoundScrollbarRendererTest.java
@@ -16,7 +16,11 @@
package android.view;
+import static android.view.RoundScrollbarRenderer.BLUECHIP_ENABLED_SYSPROP;
+
import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -30,11 +34,8 @@
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
+import android.os.SystemProperties;
import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.view.flags.Flags;
import androidx.test.core.app.ApplicationProvider;
@@ -42,7 +43,6 @@
import androidx.test.filters.SmallTest;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -66,9 +66,6 @@
private static final float DEFAULT_ALPHA = 0.5f;
private static final Rect BOUNDS = new Rect(0, 0, 200, 200);
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
@Mock private Canvas mCanvas;
@Captor private ArgumentCaptor<Paint> mPaintCaptor;
private RoundScrollbarRenderer mScrollbar;
@@ -88,8 +85,8 @@
}
@Test
- @RequiresFlagsDisabled(Flags.FLAG_USE_REFACTORED_ROUND_SCROLLBAR)
public void testScrollbarDrawn_legacy() {
+ assumeFalse(usingRefactoredScrollbar());
mScrollbar.drawRoundScrollbars(mCanvas, DEFAULT_ALPHA, BOUNDS, /* drawToLeft= */ false);
// The arc will be drawn twice, i.e. once for track and once for thumb
@@ -105,8 +102,8 @@
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_USE_REFACTORED_ROUND_SCROLLBAR)
public void testScrollbarDrawn() {
+ assumeTrue(usingRefactoredScrollbar());
mScrollbar.drawRoundScrollbars(mCanvas, DEFAULT_ALPHA, BOUNDS, /* drawToLeft= */ false);
// The arc will be drawn thrice, i.e. twice for track and once for thumb
@@ -143,4 +140,9 @@
return super.computeVerticalScrollExtent();
}
}
+
+ private static boolean usingRefactoredScrollbar() {
+ return Flags.useRefactoredRoundScrollbar()
+ && SystemProperties.getBoolean(BLUECHIP_ENABLED_SYSPROP, false);
+ }
}
diff --git a/core/tests/vibrator/src/android/os/VibratorTest.java b/core/tests/vibrator/src/android/os/VibratorTest.java
index 6210a00..09bfadb 100644
--- a/core/tests/vibrator/src/android/os/VibratorTest.java
+++ b/core/tests/vibrator/src/android/os/VibratorTest.java
@@ -110,8 +110,9 @@
@Test
public void onVibratorStateChanged_noVibrator_registersNoListenerToVibratorManager() {
+ int[] vibratorIds = new int[0];
VibratorManager mockVibratorManager = mock(VibratorManager.class);
- when(mockVibratorManager.getVibratorIds()).thenReturn(new int[0]);
+ when(mockVibratorManager.getVibratorIds()).thenReturn(vibratorIds);
Vibrator.OnVibratorStateChangedListener mockListener =
mock(Vibrator.OnVibratorStateChangedListener.class);
@@ -119,7 +120,7 @@
new SystemVibrator.MultiVibratorStateListener(
mTestLooper.getNewExecutor(), mockListener);
- multiVibratorListener.register(mockVibratorManager);
+ multiVibratorListener.register(mockVibratorManager, vibratorIds);
// Never tries to register a listener to an individual vibrator.
assertFalse(multiVibratorListener.hasRegisteredListeners());
@@ -128,8 +129,9 @@
@Test
public void onVibratorStateChanged_singleVibrator_forwardsAllCallbacks() {
+ int[] vibratorIds = new int[] { 1 };
VibratorManager mockVibratorManager = mock(VibratorManager.class);
- when(mockVibratorManager.getVibratorIds()).thenReturn(new int[] { 1 });
+ when(mockVibratorManager.getVibratorIds()).thenReturn(vibratorIds);
when(mockVibratorManager.getVibrator(anyInt())).thenReturn(NullVibrator.getInstance());
Vibrator.OnVibratorStateChangedListener mockListener =
@@ -138,7 +140,7 @@
new SystemVibrator.MultiVibratorStateListener(
mTestLooper.getNewExecutor(), mockListener);
- multiVibratorListener.register(mockVibratorManager);
+ multiVibratorListener.register(mockVibratorManager, vibratorIds);
assertTrue(multiVibratorListener.hasRegisteredListeners());
multiVibratorListener.onVibrating(/* vibratorIdx= */ 0, /* vibrating= */ false);
@@ -156,8 +158,9 @@
@Test
public void onVibratorStateChanged_multipleVibrators_triggersOnlyWhenAllVibratorsInitialized() {
+ int[] vibratorIds = new int[] { 1, 2 };
VibratorManager mockVibratorManager = mock(VibratorManager.class);
- when(mockVibratorManager.getVibratorIds()).thenReturn(new int[] { 1, 2 });
+ when(mockVibratorManager.getVibratorIds()).thenReturn(vibratorIds);
when(mockVibratorManager.getVibrator(anyInt())).thenReturn(NullVibrator.getInstance());
Vibrator.OnVibratorStateChangedListener mockListener =
@@ -166,7 +169,7 @@
new SystemVibrator.MultiVibratorStateListener(
mTestLooper.getNewExecutor(), mockListener);
- multiVibratorListener.register(mockVibratorManager);
+ multiVibratorListener.register(mockVibratorManager, vibratorIds);
assertTrue(multiVibratorListener.hasRegisteredListeners());
multiVibratorListener.onVibrating(/* vibratorIdx= */ 0, /* vibrating= */ false);
@@ -181,8 +184,9 @@
@Test
public void onVibratorStateChanged_multipleVibrators_stateChangeIsDeduped() {
+ int[] vibratorIds = new int[] { 1, 2 };
VibratorManager mockVibratorManager = mock(VibratorManager.class);
- when(mockVibratorManager.getVibratorIds()).thenReturn(new int[] { 1, 2 });
+ when(mockVibratorManager.getVibratorIds()).thenReturn(vibratorIds);
when(mockVibratorManager.getVibrator(anyInt())).thenReturn(NullVibrator.getInstance());
Vibrator.OnVibratorStateChangedListener mockListener =
@@ -191,7 +195,7 @@
new SystemVibrator.MultiVibratorStateListener(
mTestLooper.getNewExecutor(), mockListener);
- multiVibratorListener.register(mockVibratorManager);
+ multiVibratorListener.register(mockVibratorManager, vibratorIds);
assertTrue(multiVibratorListener.hasRegisteredListeners());
multiVibratorListener.onVibrating(/* vibratorIdx= */ 0, /* vibrating= */ false); // none
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 56e55df..7ced809 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -402,6 +402,9 @@
<permission name="android.permission.SHOW_CUSTOMIZED_RESOLVER"/>
<!-- Permission required for access VIBRATOR_STATE. -->
<permission name="android.permission.ACCESS_VIBRATOR_STATE"/>
+ <!-- Permission required for vendor vibration effects and sessions. -->
+ <permission name="android.permission.VIBRATE_VENDOR_EFFECTS"/>
+ <permission name="android.permission.START_VIBRATION_SESSIONS"/>
<!-- Permission required for UsageStatsTest CTS test. -->
<permission name="android.permission.MANAGE_NOTIFICATIONS"/>
<!-- Permission required for CompanionDeviceManager CTS test. -->
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 93d94c9..b4899f9 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -19,6 +19,8 @@
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
+import com.android.internal.camera.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -63,6 +65,7 @@
RAW_DEPTH10,
PRIVATE,
HEIC,
+ HEIC_ULTRAHDR,
JPEG_R
})
public @interface Format {
@@ -832,6 +835,16 @@
public static final int HEIC = 0x48454946;
/**
+ * High Efficiency Image File Format (HEIF) with embedded HDR gain map
+ *
+ * <p>This format defines the HEIC brand of High Efficiency Image File
+ * Format as described in ISO/IEC 23008-12:2024 with HDR gain map according
+ * to ISO/CD 21496‐1.</p>
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_HEIF_GAINMAP)
+ public static final int HEIC_ULTRAHDR = 0x1006;
+
+ /**
* Use this function to retrieve the number of bits per pixel of an
* ImageFormat.
*
@@ -926,6 +939,11 @@
if (android.media.codec.Flags.p210FormatSupport() && format == YCBCR_P210) {
return true;
}
+ if (Flags.cameraHeifGainmap()){
+ if (format == HEIC_ULTRAHDR) {
+ return true;
+ }
+ }
return false;
}
}
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index b7a1c13..8bb32568 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -19,7 +19,7 @@
import static com.android.text.flags.Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE;
import static com.android.text.flags.Flags.FLAG_LETTER_SPACING_JUSTIFICATION;
import static com.android.text.flags.Flags.FLAG_DEPRECATE_ELEGANT_TEXT_HEIGHT_API;
-
+import static com.android.text.flags.Flags.FLAG_VERTICAL_TEXT_LAYOUT;
import android.annotation.ColorInt;
import android.annotation.ColorLong;
@@ -35,6 +35,7 @@
import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontVariationAxis;
+import android.graphics.text.TextRunShaper;
import android.os.Build;
import android.os.LocaleList;
import android.text.GraphicsOperations;
@@ -269,7 +270,24 @@
public static final int EMBEDDED_BITMAP_TEXT_FLAG = 0x400;
/** @hide bit mask for the flag forcing freetype's autohinter on for text */
public static final int AUTO_HINTING_TEXT_FLAG = 0x800;
- /** @hide bit mask for the flag enabling vertical rendering for text */
+
+ /**
+ * A flat that controls text to be written in vertical orientation
+ *
+ * <p>
+ * This flag is used for telling the underlying text layout engine that the text is for vertical
+ * direction. By enabling this flag, text measurement, drawing and shaping APIs works for
+ * vertical text layout. For example, {@link Canvas#drawText(String, float, float, Paint)} draws
+ * text from top to bottom. {@link Paint#measureText(String)} returns vertical advances instead
+ * of horizontal advances. {@link TextRunShaper} shapes text vertically and report glyph IDs for
+ * vertical layout.
+ *
+ * <p>
+ * Do not set this flag for making {@link android.text.Layout}. The {@link android.text.Layout}
+ * class and its subclasses are designed for horizontal text only and does not work for vertical
+ * text.
+ */
+ @FlaggedApi(FLAG_VERTICAL_TEXT_LAYOUT)
public static final int VERTICAL_TEXT_FLAG = 0x1000;
/**
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
index 4385327..4d7be39 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
@@ -16,6 +16,7 @@
package androidx.window.extensions.area;
+import static android.hardware.devicestate.DeviceState.PROPERTY_EMULATED_ONLY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
@@ -569,7 +570,8 @@
private boolean isDeviceFolded() {
if (Flags.deviceStatePropertyApi()) {
return mCurrentDeviceState.hasProperty(
- PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY);
+ PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY)
+ && !mCurrentDeviceState.hasProperty(PROPERTY_EMULATED_ONLY);
} else {
return ArrayUtils.contains(mFoldedDeviceStates, mCurrentDeviceState.getIdentifier());
}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
index 08d647d..0d742cc 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
@@ -47,6 +47,7 @@
import com.android.wm.shell.taskview.TaskView
import com.android.wm.shell.taskview.TaskViewTaskController
import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
import com.google.common.util.concurrent.MoreExecutors.directExecutor
import java.util.Collections
import java.util.concurrent.Executor
@@ -147,6 +148,7 @@
@After
fun tearDown() {
testableRegionSamplingHelper?.stopAndDestroy()
+ getInstrumentation().waitForIdleSync()
}
@Test
@@ -218,8 +220,8 @@
@Test
fun testEventLogging_dismissBubbleViaAppMenu() {
getInstrumentation().runOnMainSync { bubbleExpandedView.handleView.performClick() }
- val dismissMenuItem =
- bubbleExpandedView.findViewWithTag<View>(BubbleBarMenuView.DISMISS_ACTION_TAG)
+ val dismissMenuItem = bubbleExpandedView.menuView()
+ .actionViewWithText(context.getString(R.string.bubble_dismiss_text))
assertThat(dismissMenuItem).isNotNull()
getInstrumentation().runOnMainSync { dismissMenuItem.performClick() }
assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
@@ -228,6 +230,42 @@
assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
}
+ @Test
+ fun testEventLogging_openAppSettings() {
+ getInstrumentation().runOnMainSync { bubbleExpandedView.handleView.performClick() }
+ val appMenuItem = bubbleExpandedView.menuView()
+ .actionViewWithText(context.getString(R.string.bubbles_app_settings, bubble.appName))
+ getInstrumentation().runOnMainSync { appMenuItem.performClick() }
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.logs[0].eventId)
+ .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_APP_MENU_GO_TO_SETTINGS.id)
+ assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
+ }
+
+ @Test
+ fun testEventLogging_unBubbleConversation() {
+ getInstrumentation().runOnMainSync { bubbleExpandedView.handleView.performClick() }
+ val menuItem = bubbleExpandedView.menuView()
+ .actionViewWithText(context.getString(R.string.bubbles_dont_bubble_conversation))
+ getInstrumentation().runOnMainSync { menuItem.performClick() }
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.logs[0].eventId)
+ .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_APP_MENU_OPT_OUT.id)
+ assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
+ }
+
+ private fun BubbleBarExpandedView.menuView(): BubbleBarMenuView {
+ return findViewByPredicate { it is BubbleBarMenuView }
+ }
+
+ private fun BubbleBarMenuView.actionViewWithText(text: CharSequence): View {
+ val views = ArrayList<View>()
+ findViewsWithText(views, text, View.FIND_VIEWS_WITH_TEXT)
+ assertWithMessage("Expecting a single action with text '$text'").that(views).hasSize(1)
+ // findViewsWithText returns the TextView, but the click listener is on the parent container
+ return views.first().parent as View
+ }
+
private inner class FakeBubbleTaskViewFactory : BubbleTaskViewFactory {
override fun create(): BubbleTaskView {
val taskViewTaskController = mock<TaskViewTaskController>()
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
index 2fbf089..00d9a93 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
@@ -19,12 +19,15 @@
import android.app.ActivityManager
import android.content.Context
import android.content.pm.LauncherApps
+import android.graphics.PointF
import android.os.Handler
import android.os.UserManager
import android.view.IWindowManager
import android.view.LayoutInflater
+import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
+import androidx.core.animation.AnimatorTestRule
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -48,6 +51,7 @@
import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
import com.android.wm.shell.bubbles.FakeBubbleFactory
import com.android.wm.shell.bubbles.UiEventSubject.Companion.assertThat
+import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix
import com.android.wm.shell.bubbles.properties.BubbleProperties
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
import com.android.wm.shell.common.DisplayController
@@ -57,6 +61,7 @@
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.TaskStackListenerImpl
import com.android.wm.shell.shared.TransactionPool
+import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
import com.android.wm.shell.shared.bubbles.BubbleBarLocation
import com.android.wm.shell.sysui.ShellCommandHandler
import com.android.wm.shell.sysui.ShellController
@@ -66,8 +71,10 @@
import com.android.wm.shell.taskview.TaskViewTransitions
import com.android.wm.shell.transition.Transitions
import com.google.common.truth.Truth.assertThat
+import org.junit.After
import java.util.Collections
import org.junit.Before
+import org.junit.ClassRule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
@@ -79,18 +86,28 @@
@RunWith(AndroidJUnit4::class)
class BubbleBarLayerViewTest {
+ companion object {
+ @JvmField @ClassRule
+ val animatorTestRule: AnimatorTestRule = AnimatorTestRule()
+ }
+
private val context = ApplicationProvider.getApplicationContext<Context>()
private lateinit var bubbleBarLayerView: BubbleBarLayerView
private lateinit var uiEventLoggerFake: UiEventLoggerFake
+ private lateinit var bubbleController: BubbleController
+
+ private lateinit var bubblePositioner: BubblePositioner
+
private lateinit var bubble: Bubble
@Before
fun setUp() {
ProtoLog.REQUIRE_PROTOLOGTOOL = false
ProtoLog.init()
+ PhysicsAnimatorTestUtils.prepareForTest()
uiEventLoggerFake = UiEventLoggerFake()
val bubbleLogger = BubbleLogger(uiEventLoggerFake)
@@ -100,7 +117,7 @@
val windowManager = context.getSystemService(WindowManager::class.java)
- val bubblePositioner = BubblePositioner(context, windowManager)
+ bubblePositioner = BubblePositioner(context, windowManager)
bubblePositioner.setShowingInBubbleBar(true)
val bubbleData =
@@ -113,7 +130,7 @@
bgExecutor,
)
- val bubbleController =
+ bubbleController =
createBubbleController(
bubbleData,
windowManager,
@@ -151,6 +168,12 @@
bubble = FakeBubbleFactory.createChatBubbleWithViewInfo(context, viewInfo = viewInfo)
}
+ @After
+ fun tearDown() {
+ PhysicsAnimatorTestUtils.tearDown()
+ getInstrumentation().waitForIdleSync()
+ }
+
private fun createBubbleController(
bubbleData: BubbleData,
windowManager: WindowManager?,
@@ -224,6 +247,70 @@
assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
}
+ @Test
+ fun testEventLogging_dragExpandedViewLeft() {
+ bubblePositioner.bubbleBarLocation = BubbleBarLocation.RIGHT
+
+ getInstrumentation().runOnMainSync {
+ bubbleBarLayerView.showExpandedView(bubble)
+ }
+ waitForExpandedViewAnimation()
+
+ val handleView = bubbleBarLayerView.findViewById<View>(R.id.bubble_bar_handle_view)
+ assertThat(handleView).isNotNull()
+
+ // Drag from right to left
+ handleView.dispatchTouchEvent(0L, MotionEvent.ACTION_DOWN, rightEdge())
+ handleView.dispatchTouchEvent(10L, MotionEvent.ACTION_MOVE, leftEdge())
+ handleView.dispatchTouchEvent(20L, MotionEvent.ACTION_UP, leftEdge())
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.logs[0].eventId)
+ .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_EXP_VIEW.id)
+ assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
+ }
+
+ @Test
+ fun testEventLogging_dragExpandedViewRight() {
+ bubblePositioner.bubbleBarLocation = BubbleBarLocation.LEFT
+
+ getInstrumentation().runOnMainSync {
+ bubbleBarLayerView.showExpandedView(bubble)
+ }
+ waitForExpandedViewAnimation()
+
+ val handleView = bubbleBarLayerView.findViewById<View>(R.id.bubble_bar_handle_view)
+ assertThat(handleView).isNotNull()
+
+ // Drag from left to right
+ handleView.dispatchTouchEvent(0L, MotionEvent.ACTION_DOWN, leftEdge())
+ handleView.dispatchTouchEvent(10L, MotionEvent.ACTION_MOVE, rightEdge())
+ handleView.dispatchTouchEvent(20L, MotionEvent.ACTION_UP, rightEdge())
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.logs[0].eventId)
+ .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_EXP_VIEW.id)
+ assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
+ }
+
+ private fun leftEdge(): PointF {
+ val screenSize = bubblePositioner.availableRect
+ return PointF(screenSize.left.toFloat(), screenSize.height() / 2f)
+ }
+
+ private fun rightEdge(): PointF {
+ val screenSize = bubblePositioner.availableRect
+ return PointF(screenSize.right.toFloat(), screenSize.height() / 2f)
+ }
+
+ private fun waitForExpandedViewAnimation() {
+ // wait for idle to allow the animation to start
+ getInstrumentation().waitForIdleSync()
+ getInstrumentation().runOnMainSync { animatorTestRule.advanceTimeBy(200) }
+ PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(
+ AnimatableScaleMatrix.SCALE_X, AnimatableScaleMatrix.SCALE_Y)
+ }
+
private inner class FakeBubbleTaskViewFactory(private val mainExecutor: ShellExecutor) :
BubbleTaskViewFactory {
override fun create(): BubbleTaskView {
@@ -290,4 +377,9 @@
}
}
}
+
+ private fun View.dispatchTouchEvent(eventTime: Long, action: Int, point: PointF) {
+ val event = MotionEvent.obtain(0L, eventTime, action, point.x, point.y, 0)
+ getInstrumentation().runOnMainSync { dispatchTouchEvent(event) }
+ }
}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
index ecb2b25..d4cbe6e 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
@@ -74,6 +74,7 @@
@Before
fun setUp() {
ProtoLog.REQUIRE_PROTOLOGTOOL = false
+ ProtoLog.init()
container = FrameLayout(context)
val windowManager = context.getSystemService(WindowManager::class.java)
positioner = BubblePositioner(context, windowManager)
@@ -85,7 +86,7 @@
isSmallTablet = false,
isLandscape = true,
isRtl = false,
- insets = Insets.of(10, 20, 30, 40)
+ insets = Insets.of(10, 20, 30, 40),
)
positioner.update(deviceConfig)
positioner.bubbleBarTopOnScreen =
@@ -407,12 +408,26 @@
assertThat(testListener.locationReleases).containsExactly(RIGHT)
}
+ /** Send drag start event when on left */
+ @Test
+ fun start_onLeft_sendStartEventOnLeft() {
+ getInstrumentation().runOnMainSync { controller.onDragStart(initialLocationOnLeft = true) }
+ assertThat(testListener.locationStart).containsExactly(LEFT)
+ }
+
+ /** Send drag start event when on right */
+ @Test
+ fun start_onRight_sendStartEventOnRight() {
+ getInstrumentation().runOnMainSync { controller.onDragStart(initialLocationOnLeft = false) }
+ assertThat(testListener.locationStart).containsExactly(RIGHT)
+ }
+
private fun getExpectedDropTargetBoundsOnLeft(): Rect =
Rect().also {
positioner.getBubbleBarExpandedViewBounds(
true /* onLeft */,
false /* isOverflowExpanded */,
- it
+ it,
)
}
@@ -421,7 +436,7 @@
positioner.getBubbleBarExpandedViewBounds(
false /* onLeft */,
false /* isOverflowExpanded */,
- it
+ it,
)
}
@@ -446,8 +461,14 @@
}
internal class TestLocationChangeListener : BaseBubblePinController.LocationChangeListener {
+ val locationStart = mutableListOf<BubbleBarLocation>()
val locationChanges = mutableListOf<BubbleBarLocation>()
val locationReleases = mutableListOf<BubbleBarLocation>()
+
+ override fun onStart(location: BubbleBarLocation) {
+ locationStart.add(location)
+ }
+
override fun onChange(location: BubbleBarLocation) {
locationChanges.add(location)
}
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 95c2bb5..c007c6c 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Maak in blaaier oop"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nuwe venster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Bestuur vensters"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Maak toe"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Maak kieslys oop"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimeer skerm"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gryp skerm vas"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App kan nie hierheen geskuif word nie"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Meesleurend"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Stel terug"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimeer"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Stel terug"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Spring na links"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In die app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"In jou blaaier"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index ba74e34..ef4a47a 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"በአሳሽ ውስጥ ክፈት"</string>
<string name="new_window_text" msgid="6318648868380652280">"አዲስ መስኮት"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"መስኮቶችን አስተዳድር"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ዝጋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ምናሌን ክፈት"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"የማያ ገጹ መጠን አሳድግ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ማያ ገጹን አሳድግ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"መተግበሪያ ወደዚህ መንቀሳቀስ አይችልም"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"አስማጭ"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ወደነበረበት መልስ"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"አሳድግ"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ወደነበረበት መልስ"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ወደ ግራ አሳድግ"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"በመተግበሪያው ውስጥ"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"በአሳሽዎ ውስጥ"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"እሺ"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index a8febc8..7ddd4d1 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"فتح في المتصفِّح"</string>
<string name="new_window_text" msgid="6318648868380652280">"نافذة جديدة"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"إدارة النوافذ"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"إغلاق"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"إغلاق القائمة"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"فتح القائمة"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"في التطبيق"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"في المتصفِّح"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"حسنًا"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 8c924e3..85cf31f 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ব্ৰাউজাৰত খোলক"</string>
<string name="new_window_text" msgid="6318648868380652280">"নতুন ৱিণ্ড’"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ৱিণ্ড’ পৰিচালনা কৰক"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"বন্ধ কৰক"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"মেনু খোলক"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"এপ্টোত"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"আপোনাৰ ব্ৰাউজাৰত"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ঠিক আছে"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index aa232e3..d27607a 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Brauzerdə açın"</string>
<string name="new_window_text" msgid="6318648868380652280">"Yeni pəncərə"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pəncərələri idarə edin"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Bağlayın"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menyunu açın"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı maksimum böyüdün"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranı çəkin"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Tətbiqi bura köçürmək mümkün deyil"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"İmmersiv"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Bərpa edin"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Böyüdün"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Bərpa edin"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Sola tərəf çəkin"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Tətbiqdə"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Brauzerinizdə"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
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 256344a..f251791 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Otvorite u pregledaču"</string>
<string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljajte prozorima"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvorite meni"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Povećaj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Uklopi ekran"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija ne može da se premesti ovde"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imerzivne"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vrati"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Uvećajte"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vratite"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Prikačite levo"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"U aplikaciji"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"U pregledaču"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Potvrdi"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 701c510..3393af6 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Адкрыць у браўзеры"</string>
<string name="new_window_text" msgid="6318648868380652280">"Новае акно"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Кіраваць вокнамі"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Закрыць"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Адкрыць меню"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Разгарнуць на ўвесь экран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Размясціць на палавіне экрана"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Нельга перамясціць сюды праграму"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"З эфектам прысутнасці"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Аднавіць"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Разгарнуць"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Аднавіць"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Размясціць злева"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"У праграме"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"У браўзеры"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ОК"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 9ab86f4..c2236a0 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Отваряне в браузър"</string>
<string name="new_window_text" msgid="6318648868380652280">"Нов прозорец"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управление на прозорците"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Затваряне"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отваряне на менюто"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Увеличаване на екрана"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Прилепване на екрана"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложението не може да бъде преместено тук"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалистично"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Възстановяване"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Увеличаване"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Възстановяване"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Прилепване наляво"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"В приложението"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"В браузъра ви"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 22a445f..ae30266 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ব্রাউজারে খুলুন"</string>
<string name="new_window_text" msgid="6318648868380652280">"নতুন উইন্ডো"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"উইন্ডো ম্যানেজ করুন"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"বন্ধ করুন"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"\'মেনু\' বন্ধ করুন"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"মেনু খুলুন"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"অ্যাপের মধ্যে"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"আপনার ব্রাউজারে"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ঠিক আছে"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 73f30d7..3a1512f 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -127,14 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Otvaranje u pregledniku"</string>
<string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje prozorima"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zatvaranje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvaranje menija"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiziraj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snimi ekran"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ne možete premjestiti aplikaciju ovdje"</string>
- <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Interaktivno"</string>
- <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vrati"</string>
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Uvjerljivo"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vraćanje"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimiziranje"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vraćanje"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pomicanje ulijevo"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"U aplikaciji"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"U pregledniku"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Uredu"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 499ed32..3992387 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Obre al navegador"</string>
<string name="new_window_text" msgid="6318648868380652280">"Finestra nova"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestiona les finestres"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Tanca"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Obre el menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximitza la pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajusta la pantalla"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"L\'aplicació no es pot moure aquí"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiu"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaura"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximitza"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaura"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajusta a l\'esquerra"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"A l\'aplicació"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Al navegador"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"D\'acord"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index 6a5780e..9d5ec76 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Otevřít v prohlížeči"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nové okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Spravovat okna"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zavřít"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otevřít nabídku"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"V aplikaci"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"V prohlížeči"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 430cf96..91a294d 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Åbn i browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nyt vindue"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Administrer vinduer"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Luk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Åbn menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimér skærm"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tilpas skærm"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apps kan ikke flyttes hertil"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Opslugende"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Gendan"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimér"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Gendan"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Fastgør til venstre"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"I appen"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"I din browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index cafaa89..9004b19 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Im Browser öffnen"</string>
<string name="new_window_text" msgid="6318648868380652280">"Neues Fenster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Fenster verwalten"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Schließen"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menü öffnen"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Bildschirm maximieren"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Bildschirm teilen"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Die App kann nicht hierher verschoben werden"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiv"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Wiederherstellen"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximieren"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Wiederherstellen"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Links andocken"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In der App"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"In deinem Browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Ok"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index d02fae2..601c0ce 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -127,6 +127,7 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Άνοιγμα σε πρόγραμμα περιήγησης"</string>
<string name="new_window_text" msgid="6318648868380652280">"Νέο παράθυρο"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Διαχείριση παραθύρων"</string>
+ <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Αλλαγή λόγου διαστάσεων"</string>
<string name="close_text" msgid="4986518933445178928">"Κλείσιμο"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Άνοιγμα μενού"</string>
@@ -144,4 +145,5 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Στην εφαρμογή"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Στο πρόγραμμα περιήγησής σας"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ΟΚ"</string>
+ <string name="desktop_windowing_app_to_web_education_text" msgid="1599668769538703570">"Ανοίξτε γρήγορα εφαρμογές στο πρόγραμμα περιήγησής σας εδώ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index f991145..85d5646 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"New window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"In your browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 2d123ec..dac1b9a 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -127,6 +127,7 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"New Window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage Windows"</string>
+ <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open Menu"</string>
@@ -144,4 +145,5 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"In your browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <string name="desktop_windowing_app_to_web_education_text" msgid="1599668769538703570">"Quickly open apps in your browser here"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index f991145..85d5646 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"New window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"In your browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index f991145..85d5646 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"New window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"In your browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 210b708..f6a9b6d 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir en el navegador"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nueva ventana"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Administrar ventanas"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir el menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"No se puede mover la app aquí"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Inmersivo"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restablecer"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restablecer"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajustar a la izquierda"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"En la app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"En un navegador"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Aceptar"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 3c7bfe5..2c90290 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir en el navegador"</string>
<string name="new_window_text" msgid="6318648868380652280">"Ventana nueva"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestionar ventanas"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"La aplicación no se puede mover aquí"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Inmersivo"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Acoplar a la izquierda"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"En la aplicación"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"En el navegador"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Aceptar"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index d17ee02..3d1977b 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Avamine brauseris"</string>
<string name="new_window_text" msgid="6318648868380652280">"Uus aken"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Akende haldamine"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Sule"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ava menüü"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Kuva täisekraanil"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Kuva poolel ekraanil"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Rakendust ei saa siia teisaldada"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Kaasahaarav"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Taasta"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimeeri"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Taasta"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Tõmmake vasakule"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Rakenduses"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Brauseris"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index f9419bc..2e1822d 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Ireki arakatzailean"</string>
<string name="new_window_text" msgid="6318648868380652280">"Leiho berria"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Kudeatu leihoak"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Itxi"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Itxi menua"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ireki menua"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Handitu pantaila"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zatitu pantaila"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikazioa ezin da hona ekarri"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Murgiltzailea"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Leheneratu"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizatu"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Leheneratu"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ezarri ezkerrean"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Aplikazioan"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Arakatzailean"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Ados"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index a3d3cbc..b14a1ff 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"باز کردن در مرورگر"</string>
<string name="new_window_text" msgid="6318648868380652280">"پنجره جدید"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"مدیریت کردن پنجرهها"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"بستن"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"باز کردن منو"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"بزرگ کردن صفحه"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"بزرگ کردن صفحه"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"برنامه را نمیتوان به اینجا منتقل کرد"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"فراگیر"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"بازیابی"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"بزرگ کردن"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"بازیابی کردن"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"کشیدن بهچپ"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"در برنامه"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"در مرورگر"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"تأیید"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index ee5dd65..53b22ab 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Avaa selaimessa"</string>
<string name="new_window_text" msgid="6318648868380652280">"Uusi ikkuna"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Hallinnoi ikkunoita"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Sulje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Avaa valikko"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Suurenna näyttö"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Jaa näyttö"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Sovellusta ei voi siirtää tänne"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiivinen"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Palauta"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Suurenna"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Palauta"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Siirrä vasemmalle"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Sovelluksessa"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Selaimella"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index dc47891..36fc2c2 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Ouvrir dans le navigateur"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nouvelle fenêtre"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gérer les fenêtres"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ouvrir le menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Agrandir l\'écran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aligner l\'écran"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersif"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurer"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Agrandir"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurer"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Épingler à gauche"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Dans l\'appli"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Dans votre navigateur"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index a52ab49..6c475a8 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Ouvrir dans un navigateur"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nouvelle fenêtre"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gérer les fenêtres"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ouvrir le menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mettre en plein écran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fractionner l\'écran"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersif"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurer"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Agrandir"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurer"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ancrer à gauche"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Dans l\'application"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Dans votre navigateur"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 97d5e51..c78cba6 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
<string name="new_window_text" msgid="6318648868380652280">"Ventá nova"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Xestionar as ventás"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Pechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar pantalla"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Non se pode mover aquí a aplicación"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Envolvente"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Axustar á esquerda"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Na aplicación"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"No navegador"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Aceptar"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 362ff8d..16188cb 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"બ્રાઉઝરમાં ખોલો"</string>
<string name="new_window_text" msgid="6318648868380652280">"નવી વિન્ડો"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"વિન્ડો મેનેજ કરો"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"બંધ કરો"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"મેનૂ ખોલો"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"સ્ક્રીન કરો મોટી કરો"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"સ્ક્રીન સ્નૅપ કરો"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ઍપ અહીં ખસેડી શકાતી નથી"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ઇમર્સિવ"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"રિસ્ટોર કરો"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"મોટું કરો"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"રિસ્ટોર કરો"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ડાબે સ્નૅપ કરો"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ઍપમાં"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"તમારા બ્રાઉઝરમાં"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ઓકે"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 527793e..51ca24c 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउज़र में खोलें"</string>
<string name="new_window_text" msgid="6318648868380652280">"नई विंडो"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"विंडो मैनेज करें"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"बंद करें"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेन्यू खोलें"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ऐप्लिकेशन में"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"आपके ब्राउज़र में"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ठीक है"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 659d1ec..70ecca8 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Otvori u pregledniku"</string>
<string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje prozorima"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvaranje izbornika"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"U aplikaciji"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"U pregledniku"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"U redu"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 943b5eb..a46c14f 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Megnyitás böngészőben"</string>
<string name="new_window_text" msgid="6318648868380652280">"Új ablak"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Ablakok kezelése"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Bezárás"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menü megnyitása"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Képernyő méretének maximalizálása"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Igazodás a képernyő adott részéhez"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Az alkalmazás nem helyezhető át ide"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Magával ragadó"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Visszaállítás"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Teljes méret"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Visszaállítás"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Balra igazítás"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Az alkalmazásban"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"A böngészőben"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 6bcfc9a..b7105c9 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -92,8 +92,8 @@
<string name="bubble_shortcut_label" msgid="666269077944378311">"Ամպիկներ"</string>
<string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Ցույց տալ ամպիկներ"</string>
<string name="restart_button_description" msgid="4564728020654658478">"Հպեք՝ հավելվածը վերագործարկելու և ավելի հարմար տեսք ընտրելու համար"</string>
- <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Փոխել հավելվածի կողմերի հարաբերակցությունը Կարգավորումներում"</string>
- <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Փոխել չափերի հարաբերակցությունը"</string>
+ <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Փոխել հավելվածի կողմերի հարաբերությունը Կարգավորումներում"</string>
+ <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Փոխել չափերի հարաբերությունը"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Տեսախցիկի հետ կապված խնդիրնե՞ր կան։\nՀպեք՝ վերակարգավորելու համար։"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Չհաջողվե՞ց շտկել։\nՀպեք՝ փոփոխությունները չեղարկելու համար։"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Տեսախցիկի հետ կապված խնդիրներ չկա՞ն։ Փակելու համար հպեք։"</string>
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Բացել դիտարկիչում"</string>
<string name="new_window_text" msgid="6318648868380652280">"Նոր պատուհան"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Կառավարել պատուհանները"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Փակել"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Բացել ընտրացանկը"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ծավալել էկրանը"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ծալել էկրանը"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Հավելվածը հնարավոր չէ տեղափոխել այստեղ"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Ներկայության էֆեկտով"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Վերականգնել"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Ծավալել"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Վերականգնել"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ամրացնել ձախ կողմում"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Հավելվածում"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Ձեր դիտարկիչում"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Եղավ"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 96a3ebc..4a40027 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Buka di browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"Jendela Baru"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Kelola Jendela"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buka Menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Perbesar Layar"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gabungkan Layar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikasi tidak dapat dipindahkan ke sini"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imersif"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Pulihkan"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimalkan"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Pulihkan"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Maksimalkan ke kiri"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Di aplikasi"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Di browser Anda"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Oke"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index ca1bc15..d3f2c3d 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Opna í vafra"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nýr gluggi"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Stjórna gluggum"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Loka"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Opna valmynd"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Í forritinu"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Í vafranum"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Í lagi"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 87919b5..e4f78ad 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Apri nel browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nuova finestra"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestisci finestre"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Chiudi"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Apri il menu"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"All\'interno dell\'app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Nel browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Ok"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 17ffe8e..b042ee4 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"פתיחה בדפדפן"</string>
<string name="new_window_text" msgid="6318648868380652280">"חלון חדש"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ניהול החלונות"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"סגירה"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"סגירת התפריט"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"פתיחת התפריט"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"הגדלת המסך"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"כיווץ המסך"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"לא ניתן להעביר את האפליקציה לכאן"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"סוחף"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"שחזור"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"הגדלה"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"שחזור"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"הצמדה לשמאל"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"באפליקציה"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"בדפדפן"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"אישור"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index c7a77d9..6d5954f 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ブラウザで開く"</string>
<string name="new_window_text" msgid="6318648868380652280">"新しいウィンドウ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ウィンドウを管理する"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"閉じる"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"メニューを開く"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"アプリ内"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"ブラウザ内"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 39362ef..f38f68f 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ბრაუზერში გახსნა"</string>
<string name="new_window_text" msgid="6318648868380652280">"ახალი ფანჯარა"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ფანჯრების მართვა"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"დახურვა"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"მენიუს გახსნა"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"აპში"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"თქვენს ბრაუზერში"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"კარგი"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 45f85b9..b4be01a 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Браузерден ашу"</string>
<string name="new_window_text" msgid="6318648868380652280">"Жаңа терезе"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Терезелерді басқару"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Жабу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Мәзірді ашу"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды ұлғайту"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды бөлу"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Қолданба бұл жерге қойылмайды."</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Әсерлі"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Қалпына келтіру"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Жаю"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Қалпына келтіру"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Солға тіркеу"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Қолданбада"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Браузерде"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Жарайды"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 9c4ae05..2424a42 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"បើកក្នុងកម្មវិធីរុករកតាមអ៊ីនធឺណិត"</string>
<string name="new_window_text" msgid="6318648868380652280">"វិនដូថ្មី"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"គ្រប់គ្រងវិនដូ"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"បិទ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"បិទម៉ឺនុយ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"បើកម៉ឺនុយ"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"នៅក្នុងកម្មវិធី"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"នៅក្នុងកម្មវិធីរុករកតាមអ៊ីនធឺណិតរបស់អ្នក"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"យល់ព្រម"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index f365cfb..56a5d64 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ಬ್ರೌಸರ್ನಲ್ಲಿ ತೆರೆಯಿರಿ"</string>
<string name="new_window_text" msgid="6318648868380652280">"ಹೊಸ ವಿಂಡೋ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ವಿಂಡೋಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ಮುಚ್ಚಿ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ಮೆನು ತೆರೆಯಿರಿ"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ಆ್ಯಪ್ನಲ್ಲಿ"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"ನಿಮ್ಮ ಬ್ರೌಸರ್ನಲ್ಲಿ"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ಸರಿ"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 2bf1b05..d45d515 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"브라우저에서 열기"</string>
<string name="new_window_text" msgid="6318648868380652280">"새 창"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"창 관리"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"닫기"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"메뉴 열기"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"화면 최대화"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"화면 분할"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"앱을 여기로 이동할 수 없음"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"몰입형"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"복원"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"최대화하기"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"복원"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"왼쪽으로 맞추기"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"앱에서"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"브라우저에서"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"확인"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 392ae4c..501b2a7 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Серепчиден ачуу"</string>
<string name="new_window_text" msgid="6318648868380652280">"Жаңы терезе"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Терезелерди тескөө"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Жабуу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Менюну ачуу"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды чоңойтуу"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды сүрөткө тартып алуу"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Колдонмону бул жерге жылдырууга болбойт"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Сүңгүтүүчү"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Калыбына келтирүү"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Чоңойтуу"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Калыбына келтирүү"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Солго жылдыруу"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Колдонмодо"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Серепчиңизде"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Жарайт"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 4e4b678..b48b070 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -127,16 +127,15 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ເປີດໃນໂປຣແກຣມທ່ອງເວັບ"</string>
<string name="new_window_text" msgid="6318648868380652280">"ໜ້າຈໍໃໝ່"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ຈັດການໜ້າຈໍ"</string>
+ <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ປ່ຽນອັດຕາສ່ວນຮູບ"</string>
<string name="close_text" msgid="4986518933445178928">"ປິດ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ເປີດເມນູ"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ປັບຈໍໃຫຍ່ສຸດ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ສະແນັບໜ້າຈໍ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ບໍ່ສາມາດຍ້າຍແອັບມາບ່ອນນີ້ໄດ້"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ສົມຈິງ"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ກູ້ຄືນ"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ຂະຫຍາຍໃຫຍ່ສຸດ"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ກູ້ຄືນ"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ແນບຊ້າຍ"</string>
@@ -146,4 +145,5 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ໃນແອັບ"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"ໃນໂປຣແກຣມທ່ອງເວັບຂອງທ່ານ"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ຕົກລົງ"</string>
+ <string name="desktop_windowing_app_to_web_education_text" msgid="1599668769538703570">"ເປີດແອັບຢ່າງວ່ອງໄວໃນໂປຣແກຣມທ່ອງເວັບຂອງທ່ານບ່ອນນີ້"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 5a7f58e..7e1aac0 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Atidaryti naršyklėje"</string>
<string name="new_window_text" msgid="6318648868380652280">"Naujas langas"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Tvarkyti langus"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Uždaryti"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Atidaryti meniu"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Programoje"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Naršyklėje"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Gerai"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 60912f62..1ad0454 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Atvērt pārlūkā"</string>
<string name="new_window_text" msgid="6318648868380652280">"Jauns logs"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pārvaldīt logus"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Aizvērt"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Atvērt izvēlni"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizēt ekrānu"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fiksēt ekrānu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Lietotni nevar pārvietot šeit."</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Iekļaujoši"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Atjaunot"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimizēt"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Atjaunot"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Piestiprināt pa kreisi"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Lietotnē"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Pārlūkprogrammā"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Labi"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 7c0c856..444372e 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Отвори во прелистувач"</string>
<string name="new_window_text" msgid="6318648868380652280">"Нов прозорец"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управувајте со прозорци"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Затворете"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отвори го менито"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Максимизирај го екранот"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Подели го екранот на половина"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликацијата не може да се премести овде"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалистично"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Врати"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Максимизирај"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Врати"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Фотографирај лево"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Во апликацијата"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Во прелистувачот"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Во ред"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index e14ab8b..cd2f635 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ബ്രൗസറിൽ തുറക്കുക"</string>
<string name="new_window_text" msgid="6318648868380652280">"പുതിയ വിന്ഡോ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"വിൻഡോകൾ മാനേജ് ചെയ്യുക"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"അടയ്ക്കുക"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"മെനു തുറക്കുക"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"സ്ക്രീൻ വലുതാക്കുക"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"സ്ക്രീൻ സ്നാപ്പ് ചെയ്യുക"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ആപ്പ് ഇവിടേക്ക് നീക്കാനാകില്ല"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ഇമേഴ്സീവ്"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"പുനഃസ്ഥാപിക്കുക"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"വലുതാക്കുക"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"പുനഃസ്ഥാപിക്കുക"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ഇടതുവശത്തേക്ക് സ്നാപ്പ് ചെയ്യുക"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ആപ്പിൽ"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"നിങ്ങളുടെ ബ്രൗസറിൽ"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ശരി"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index d406b99..1bec287 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Хөтчид нээх"</string>
<string name="new_window_text" msgid="6318648868380652280">"Шинэ цонх"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Windows-г удирдах"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Хаах"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Цэсийг нээх"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Дэлгэцийг томруулах"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Дэлгэцийг таллах"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Аппыг ийш зөөх боломжгүй"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Бодит мэт"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Сэргээх"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Томруулах"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Сэргээх"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Зүүн тийш зэрэгцүүлэх"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Аппад"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Хөтчидөө"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index 871bc3f..f36c40f 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउझरमध्ये उघडा"</string>
<string name="new_window_text" msgid="6318648868380652280">"नवीन विंडो"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"विंडो व्यवस्थापित करा"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"बंद करा"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेनू उघडा"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ॲपमध्ये"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"तुमच्या ब्राउझरमध्ये"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ओके"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 71666ca..6b4361a 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Buka dalam penyemak imbas"</string>
<string name="new_window_text" msgid="6318648868380652280">"Tetingkap Baharu"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Urus Tetingkap"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buka Menu"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Pada apl"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Pada penyemak imbas"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index ae34624..d47c196 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ဘရောင်ဇာတွင် ဖွင့်ရန်"</string>
<string name="new_window_text" msgid="6318648868380652280">"ဝင်းဒိုးအသစ်"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ဝင်းဒိုးများ စီမံရန်"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ပိတ်ရန်"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"မီနူး ဖွင့်ရန်"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"စခရင်ကို ချဲ့မည်"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"စခရင်ကို ချုံ့မည်"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"အက်ပ်ကို ဤနေရာသို့ ရွှေ့၍မရပါ"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"သုံးဘက်မြင်"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ပြန်ပြောင်းရန်"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ချဲ့ရန်"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ပြန်ပြောင်းရန်"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ဘယ်တွင် ချဲ့ရန်"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"အက်ပ်တွင်"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"သင်၏ဘရောင်ဇာတွင်"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 9270dc8..937d6d4 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Åpne i nettleseren"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nytt vindu"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Administrer vinduene"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Lukk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Åpne menyen"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimer skjermen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fest skjermen"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Appen kan ikke flyttes hit"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Oppslukende"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Gjenopprett"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimer"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Gjenopprett"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Fest til venstre"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"I appen"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"I nettleseren"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 7015b2c..36e54a5 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउजरमा खोल्नुहोस्"</string>
<string name="new_window_text" msgid="6318648868380652280">"नयाँ विन्डो"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"विन्डोहरू व्यवस्थापन गर्नुहोस्"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"बन्द गर्नुहोस्"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेनु खोल्नुहोस्"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"एपमा"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"तपाईंको ब्राउजरमा"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ठिक छ"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 45305d6..8db3a0e 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -127,16 +127,15 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Openen in browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nieuw venster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Vensters beheren"</string>
+ <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Beeldverhouding wijzigen"</string>
<string name="close_text" msgid="4986518933445178928">"Sluiten"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menu openen"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Scherm maximaliseren"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Scherm halveren"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Kan de app niet hierheen verplaatsen"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersief"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Herstellen"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximaliseren"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Herstellen"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Links uitlijnen"</string>
@@ -146,4 +145,5 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In de app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"In je browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <string name="desktop_windowing_app_to_web_education_text" msgid="1599668769538703570">"Open hier snel apps in je browser"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 2d30441..9d9b773 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ବ୍ରାଉଜରରେ ଖୋଲନ୍ତୁ"</string>
<string name="new_window_text" msgid="6318648868380652280">"ନୂଆ ୱିଣ୍ଡୋ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ମେନୁ ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ମେନୁ ଖୋଲନ୍ତୁ"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ସ୍କ୍ରିନକୁ ବଡ଼ କରନ୍ତୁ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ସ୍କ୍ରିନକୁ ସ୍ନାପ କରନ୍ତୁ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ଆପକୁ ଏଠାକୁ ମୁଭ କରାଯାଇପାରିବ ନାହିଁ"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ଇମର୍ସିଭ"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ବଡ଼ କରନ୍ତୁ"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ବାମରେ ସ୍ନାପ କରନ୍ତୁ"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ଆପରେ"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"ଆପଣଙ୍କ ବ୍ରାଉଜରରେ"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ଠିକ ଅଛି"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 26ba461..af13301 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"ਬ੍ਰਾਊਜ਼ਰ ਵਿੱਚ ਖੋਲ੍ਹੋ"</string>
<string name="new_window_text" msgid="6318648868380652280">"ਨਵੀਂ ਵਿੰਡੋ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ਵਿੰਡੋਆਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ਬੰਦ ਕਰੋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ਮੀਨੂ ਖੋਲ੍ਹੋ"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ਸਕ੍ਰੀਨ ਦਾ ਆਕਾਰ ਵਧਾਓ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ਸਕ੍ਰੀਨ ਨੂੰ ਸਨੈਪ ਕਰੋ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ਐਪ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਲਿਜਾਇਆ ਜਾ ਸਕਦਾ"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ਇਮਰਸਿਵ"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ਵੱਡਾ ਕਰੋ"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ਖੱਬੇ ਪਾਸੇ ਸਨੈਪ ਕਰੋ"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ਐਪ ਵਿੱਚ"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"ਤੁਹਾਡੇ ਬ੍ਰਾਊਜ਼ਰ ਵਿੱਚ"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ਠੀਕ ਹੈ"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 5f78b13..27080fb 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Otwórz w przeglądarce"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nowe okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Zarządzaj oknami"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zamknij"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zamknij menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otwórz menu"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"W aplikacji"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"W przeglądarce"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 8c7f9e7..9039cc2 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gerenciar janelas"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imersivo"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajustar à esquerda"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"No app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"No navegador"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index cd78ef9..559eea2 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -127,6 +127,7 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Faça a gestão das janelas"</string>
+ <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Alterar formato"</string>
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir menu"</string>
@@ -144,4 +145,5 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Na app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"No navegador"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <string name="desktop_windowing_app_to_web_education_text" msgid="1599668769538703570">"Abra rapidamente apps no navegador aqui"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 8c7f9e7..9039cc2 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gerenciar janelas"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imersivo"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajustar à esquerda"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"No app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"No navegador"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index e3fe280..52e45bc 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Deschide în browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"Fereastră nouă"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestionează ferestrele"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Închide"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Deschide meniul"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizează fereastra"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Micșorează fereastra și fixeaz-o"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplicația nu poate fi mutată aici"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Captivant"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restabilește"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizează"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restabilește"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Trage la stânga"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"În aplicație"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"În browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 442fca3..6d32b64 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Открыть в браузере"</string>
<string name="new_window_text" msgid="6318648868380652280">"Новое окно"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управление окнами"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Закрыть"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Открыть меню"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Развернуть на весь экран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Свернуть"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложение нельзя сюда переместить"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Погружение"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Восстановить"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Развернуть"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Восстановить"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Привязать слева"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"В приложении"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"В браузере"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ОК"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 8a7ad3b..7c7f85d 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"බ්රව්සරයේ විවෘත කරන්න"</string>
<string name="new_window_text" msgid="6318648868380652280">"නව කවුළුව"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"කවුළු කළමනාකරණය කරන්න"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"වසන්න"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"මෙනුව විවෘත කරන්න"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"තිරය උපරිම කරන්න"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ස්නැප් තිරය"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"යෙදුම මෙතැනට ගෙන යා නොහැක"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ගිලෙන සුළු"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ප්රතිසාධනය කරන්න"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"විහිදන්න"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ප්රතිසාධනය කරන්න"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"වමට ස්නැප් කරන්න"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"යෙදුම තුළ"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"ඔබේ බ්රව්සරය තුළ"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"හරි"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 4234e80..c89f699 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Otvoriť v prehliadači"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nové okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Správa okien"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zavrieť"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvoriť ponuku"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovať obrazovku"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zobraziť polovicu obrazovky"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikácia sa sem nedá presunúť"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Pútavé"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnoviť"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximalizovať"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Obnoviť"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Prichytiť vľavo"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"V aplikácii"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"V prehliadači"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index ae7e524..b064ce5 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Odpri v brskalniku"</string>
<string name="new_window_text" msgid="6318648868380652280">"Novo okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje oken"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zapri"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Odpri meni"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"V aplikaciji"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"V brskalniku"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"V redu"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index de6f681..b1de743 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Hape në shfletues"</string>
<string name="new_window_text" msgid="6318648868380652280">"Dritare e re"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Menaxho dritaret"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Mbyll"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Hap menynë"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizo ekranin"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Regjistro ekranin"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacioni nuk mund të zhvendoset këtu"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Përfshirës"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restauro"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimizo"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restauro"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Zhvendos majtas"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Në aplikacion"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Në shfletuesin tënd"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Në rregull"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 901d6d9..50faf80 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Отворите у прегледачу"</string>
<string name="new_window_text" msgid="6318648868380652280">"Нови прозор"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управљајте прозорима"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Затворите"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отворите мени"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Повећај екран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Уклопи екран"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликација не може да се премести овде"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Имерзивне"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Врати"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Увећајте"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Вратите"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Прикачите лево"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"У апликацији"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"У прегледачу"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Потврди"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 6566801..51ef239 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Öppna i webbläsaren"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nytt fönster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Hantera fönster"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Stäng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Öppna menyn"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximera skärmen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fäst skärmen"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Det går inte att flytta appen hit"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Uppslukande"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Återställ"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Utöka"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Återställ"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Fäst till vänster"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"I appen"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"I webbläsaren"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index a952011..ff5d423 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Fungua katika kivinjari"</string>
<string name="new_window_text" msgid="6318648868380652280">"Dirisha Jipya"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Dhibiti Windows"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Funga"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Fungua Menyu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Panua Dirisha kwenye Skrini"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Panga Madirisha kwenye Skrini"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Imeshindwa kuhamishia programu hapa"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Shirikishi"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Rejesha"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Panua"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Rejesha"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Telezesha kushoto"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Kwenye programu"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Kwenye kivinjari chako"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Sawa"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 2c73d3a..953c64d 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"உலாவியில் திறக்கும்"</string>
<string name="new_window_text" msgid="6318648868380652280">"புதிய சாளரம்"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"சாளரங்களை நிர்வகிக்கலாம்"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"மூடும்"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"மெனுவைத் திறக்கும்"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ஆப்ஸில்"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"உங்கள் பிரவுசரில்"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"சரி"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index b17d4d1..2efb0ba 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"బ్రౌజర్లో తెరవండి"</string>
<string name="new_window_text" msgid="6318648868380652280">"కొత్త విండో"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"విండోలను మేనేజ్ చేయండి"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"మూసివేయండి"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"మెనూను తెరవండి"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"యాప్లో"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"మీ బ్రౌజర్లో"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"సరే"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 43cee41..3d775d2 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"เปิดในเบราว์เซอร์"</string>
<string name="new_window_text" msgid="6318648868380652280">"หน้าต่างใหม่"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"จัดการหน้าต่าง"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ปิด"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ปิดเมนู"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"เปิดเมนู"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ในแอป"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"ในเบราว์เซอร์"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ตกลง"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 4284995..a57cb8b 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Buksan sa browser"</string>
<string name="new_window_text" msgid="6318648868380652280">"Bagong Window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pamahalaan ang Mga Window"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Isara"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buksan ang Menu"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Sa app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Sa iyong browser"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 7eac4a8..bea4a35 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Tarayıcıda aç"</string>
<string name="new_window_text" msgid="6318648868380652280">"Yeni Pencere"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pencereleri yönet"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Kapat"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menüyü aç"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı Büyüt"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranın Yarısına Tuttur"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Uygulama buraya taşınamıyor"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Etkileyici"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Geri yükle"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Ekranı kapla"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Geri yükle"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Sola tuttur"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Uygulamada"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Tarayıcınızda"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"Tamam"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 5fb14bf..91f665e 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Відкрити у вебпереглядачі"</string>
<string name="new_window_text" msgid="6318648868380652280">"Нове вікно"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Керувати вікнами"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Закрити"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрити меню"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Відкрити меню"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Розгорнути екран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Зафіксувати екран"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Сюди не можна перемістити додаток"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалістичність"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Відновити"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Розгорнути"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Відновити"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Закріпити ліворуч"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"У додатку"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"У вебпереглядачі"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index bb0358f..6125bfd 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"براؤزر میں کھولیں"</string>
<string name="new_window_text" msgid="6318648868380652280">"نئی ونڈو"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Windows کا نظم کریں"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"بند کریں"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"مینیو بند کریں"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"مینو کھولیں"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"اسکرین کو بڑا کریں"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"اسکرین کا اسناپ شاٹ لیں"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ایپ کو یہاں منتقل نہیں کیا جا سکتا"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"عمیق"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"بحال کریں"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"بڑا کریں"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"بحال کریں"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"دائیں منتقل کریں"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ایپ میں"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"آپ کے براؤزر میں"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"ٹھیک ہے"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 0648dd1..63e818c 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Brauzerda ochish"</string>
<string name="new_window_text" msgid="6318648868380652280">"Yangi oyna"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Oynalarni boshqarish"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Yopish"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menyuni ochish"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranni yoyish"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranni biriktirish"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ilova bu yerga surilmaydi"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiv"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Tiklash"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Yoyish"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Tiklash"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Chapga tortish"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Ilovada"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Brauzerda"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index dda2225..7114f1d 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Mở trong trình duyệt"</string>
<string name="new_window_text" msgid="6318648868380652280">"Cửa sổ mới"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Quản lý cửa sổ"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Đóng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Mở Trình đơn"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mở rộng màn hình"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Điều chỉnh kích thước màn hình"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Không di chuyển được ứng dụng đến đây"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Hiển thị tối đa"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Khôi phục"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Phóng to tối đa"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Khôi phục"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Di chuyển nhanh sang trái"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Trong ứng dụng"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Trên trình duyệt"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"OK"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 2fb3f5a..15c45d9 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -127,6 +127,8 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"在浏览器中打开"</string>
<string name="new_window_text" msgid="6318648868380652280">"新窗口"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理窗口"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"关闭"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"关闭菜单"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"打开菜单"</string>
@@ -144,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"在此应用内"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"在浏览器中"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"确定"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 1d7fb4c..f7f4a2a 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"在瀏覽器中開啟"</string>
<string name="new_window_text" msgid="6318648868380652280">"新視窗"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理視窗"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"打開選單"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至這裡"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"身歷其境"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"還原"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"最大化"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"還原"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"貼齊左邊"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"在應用程式內"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"在瀏覽器中"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"確定"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 8083e37..000944b 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"在瀏覽器中開啟"</string>
<string name="new_window_text" msgid="6318648868380652280">"新視窗"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理視窗"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"開啟選單"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至此處"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"沉浸"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"還原"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"最大化"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"還原"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"靠左對齊"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"使用應用程式"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"使用瀏覽器"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"確定"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 092efd6..63eeb5f 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -127,16 +127,16 @@
<string name="open_in_browser_text" msgid="9181692926376072904">"Vula kubhrawuza"</string>
<string name="new_window_text" msgid="6318648868380652280">"Iwindi Elisha"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Phatha Amawindi"</string>
+ <!-- no translation found for change_aspect_ratio_text (9104456064548212806) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Vala"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Vula Imenyu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Khulisa Isikrini Sifike Ekugcineni"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Thwebula Isikrini"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"I-app ayikwazi ukuhanjiswa lapha"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Okugxilile"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Buyisela"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Khulisa"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Buyisela"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Chofoza kwesobunxele"</string>
@@ -146,4 +146,6 @@
<string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Ku-app"</string>
<string name="open_by_default_dialog_in_browser_text" msgid="8042769465958497081">"Kubhrawuza yakho"</string>
<string name="open_by_default_dialog_dismiss_button_text" msgid="3487238795534582291">"KULUNGILE"</string>
+ <!-- no translation found for desktop_windowing_app_to_web_education_text (1599668769538703570) -->
+ <skip />
</resources>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.java
deleted file mode 100644
index 65e079e..0000000
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.shared;
-
-import android.annotation.IntDef;
-import android.app.ActivityManager;
-import android.app.WindowConfiguration;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.wm.shell.shared.split.SplitBounds;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Simple container for recent tasks. May contain either a single or pair of tasks.
- */
-public class GroupedRecentTaskInfo implements Parcelable {
-
- public static final int TYPE_SINGLE = 1;
- public static final int TYPE_SPLIT = 2;
- public static final int TYPE_FREEFORM = 3;
-
- @IntDef(prefix = {"TYPE_"}, value = {
- TYPE_SINGLE,
- TYPE_SPLIT,
- TYPE_FREEFORM
- })
- public @interface GroupType {}
-
- @NonNull
- private final ActivityManager.RecentTaskInfo[] mTasks;
- @Nullable
- private final SplitBounds mSplitBounds;
- @GroupType
- private final int mType;
- // TODO(b/348332802): move isMinimized inside each Task object instead once we have a
- // replacement for RecentTaskInfo
- private final int[] mMinimizedTaskIds;
-
- /**
- * Create new for a single task
- */
- public static GroupedRecentTaskInfo forSingleTask(
- @NonNull ActivityManager.RecentTaskInfo task) {
- return new GroupedRecentTaskInfo(new ActivityManager.RecentTaskInfo[]{task}, null,
- TYPE_SINGLE, null /* minimizedFreeformTasks */);
- }
-
- /**
- * Create new for a pair of tasks in split screen
- */
- public static GroupedRecentTaskInfo forSplitTasks(@NonNull ActivityManager.RecentTaskInfo task1,
- @NonNull ActivityManager.RecentTaskInfo task2, @Nullable SplitBounds splitBounds) {
- return new GroupedRecentTaskInfo(new ActivityManager.RecentTaskInfo[]{task1, task2},
- splitBounds, TYPE_SPLIT, null /* minimizedFreeformTasks */);
- }
-
- /**
- * Create new for a group of freeform tasks
- */
- public static GroupedRecentTaskInfo forFreeformTasks(
- @NonNull ActivityManager.RecentTaskInfo[] tasks,
- @NonNull Set<Integer> minimizedFreeformTasks) {
- return new GroupedRecentTaskInfo(
- tasks,
- null /* splitBounds */,
- TYPE_FREEFORM,
- minimizedFreeformTasks.stream().mapToInt(i -> i).toArray());
- }
-
- private GroupedRecentTaskInfo(
- @NonNull ActivityManager.RecentTaskInfo[] tasks,
- @Nullable SplitBounds splitBounds,
- @GroupType int type,
- @Nullable int[] minimizedFreeformTaskIds) {
- mTasks = tasks;
- mSplitBounds = splitBounds;
- mType = type;
- mMinimizedTaskIds = minimizedFreeformTaskIds;
- ensureAllMinimizedIdsPresent(tasks, minimizedFreeformTaskIds);
- }
-
- private static void ensureAllMinimizedIdsPresent(
- @NonNull ActivityManager.RecentTaskInfo[] tasks,
- @Nullable int[] minimizedFreeformTaskIds) {
- if (minimizedFreeformTaskIds == null) {
- return;
- }
- if (!Arrays.stream(minimizedFreeformTaskIds).allMatch(
- taskId -> Arrays.stream(tasks).anyMatch(task -> task.taskId == taskId))) {
- throw new IllegalArgumentException("Minimized task IDs contain non-existent Task ID.");
- }
- }
-
- GroupedRecentTaskInfo(Parcel parcel) {
- mTasks = parcel.createTypedArray(ActivityManager.RecentTaskInfo.CREATOR);
- mSplitBounds = parcel.readTypedObject(SplitBounds.CREATOR);
- mType = parcel.readInt();
- mMinimizedTaskIds = parcel.createIntArray();
- }
-
- /**
- * Get primary {@link ActivityManager.RecentTaskInfo}
- */
- @NonNull
- public ActivityManager.RecentTaskInfo getTaskInfo1() {
- return mTasks[0];
- }
-
- /**
- * Get secondary {@link ActivityManager.RecentTaskInfo}.
- *
- * Used in split screen.
- */
- @Nullable
- public ActivityManager.RecentTaskInfo getTaskInfo2() {
- if (mTasks.length > 1) {
- return mTasks[1];
- }
- return null;
- }
-
- /**
- * Get all {@link ActivityManager.RecentTaskInfo}s grouped together.
- */
- @NonNull
- public List<ActivityManager.RecentTaskInfo> getTaskInfoList() {
- return Arrays.asList(mTasks);
- }
-
- /**
- * Return {@link SplitBounds} if this is a split screen entry or {@code null}
- */
- @Nullable
- public SplitBounds getSplitBounds() {
- return mSplitBounds;
- }
-
- /**
- * Get type of this recents entry. One of {@link GroupType}
- */
- @GroupType
- public int getType() {
- return mType;
- }
-
- public int[] getMinimizedTaskIds() {
- return mMinimizedTaskIds;
- }
-
- @Override
- public String toString() {
- StringBuilder taskString = new StringBuilder();
- for (int i = 0; i < mTasks.length; i++) {
- if (i == 0) {
- taskString.append("Task");
- } else {
- taskString.append(", Task");
- }
- taskString.append(i + 1).append(": ").append(getTaskInfo(mTasks[i]));
- }
- if (mSplitBounds != null) {
- taskString.append(", SplitBounds: ").append(mSplitBounds);
- }
- taskString.append(", Type=");
- switch (mType) {
- case TYPE_SINGLE:
- taskString.append("TYPE_SINGLE");
- break;
- case TYPE_SPLIT:
- taskString.append("TYPE_SPLIT");
- break;
- case TYPE_FREEFORM:
- taskString.append("TYPE_FREEFORM");
- break;
- }
- taskString.append(", Minimized Task IDs: ");
- taskString.append(Arrays.toString(mMinimizedTaskIds));
- return taskString.toString();
- }
-
- private String getTaskInfo(ActivityManager.RecentTaskInfo taskInfo) {
- if (taskInfo == null) {
- return null;
- }
- return "id=" + taskInfo.taskId
- + " baseIntent=" + (taskInfo.baseIntent != null
- ? taskInfo.baseIntent.getComponent()
- : "null")
- + " winMode=" + WindowConfiguration.windowingModeToString(
- taskInfo.getWindowingMode());
- }
-
- @Override
- public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeTypedArray(mTasks, flags);
- parcel.writeTypedObject(mSplitBounds, flags);
- parcel.writeInt(mType);
- parcel.writeIntArray(mMinimizedTaskIds);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final @android.annotation.NonNull Creator<GroupedRecentTaskInfo> CREATOR =
- new Creator<GroupedRecentTaskInfo>() {
- public GroupedRecentTaskInfo createFromParcel(Parcel source) {
- return new GroupedRecentTaskInfo(source);
- }
- public GroupedRecentTaskInfo[] newArray(int size) {
- return new GroupedRecentTaskInfo[size];
- }
- };
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.aidl
similarity index 95%
rename from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.aidl
index e21bf8f..93e635d 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.aidl
@@ -16,4 +16,4 @@
package com.android.wm.shell.shared;
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+parcelable GroupedTaskInfo;
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
new file mode 100644
index 0000000..03e0ab0
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.shared;
+
+import android.annotation.IntDef;
+import android.app.ActivityManager.RecentTaskInfo;
+import android.app.TaskInfo;
+import android.app.WindowConfiguration;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.wm.shell.shared.split.SplitBounds;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Simple container for recent tasks which should be presented as a single task within the
+ * Overview UI.
+ */
+public class GroupedTaskInfo implements Parcelable {
+
+ public static final int TYPE_FULLSCREEN = 1;
+ public static final int TYPE_SPLIT = 2;
+ public static final int TYPE_FREEFORM = 3;
+
+ @IntDef(prefix = {"TYPE_"}, value = {
+ TYPE_FULLSCREEN,
+ TYPE_SPLIT,
+ TYPE_FREEFORM
+ })
+ public @interface GroupType {}
+
+ /**
+ * The type of this particular task info, can be one of TYPE_FULLSCREEN, TYPE_SPLIT or
+ * TYPE_FREEFORM.
+ */
+ @GroupType
+ protected final int mType;
+
+ /**
+ * The list of tasks associated with this single recent task info.
+ * TYPE_FULLSCREEN: Contains the stack of tasks associated with a single "task" in overview
+ * TYPE_SPLIT: Contains the two split roots of each side
+ * TYPE_FREEFORM: Contains the set of tasks currently in freeform mode
+ */
+ @NonNull
+ protected final List<TaskInfo> mTasks;
+
+ /**
+ * Only set for TYPE_SPLIT.
+ *
+ * Information about the split bounds.
+ */
+ @Nullable
+ protected final SplitBounds mSplitBounds;
+
+ /**
+ * Only set for TYPE_FREEFORM.
+ *
+ * TODO(b/348332802): move isMinimized inside each Task object instead once we have a
+ * replacement for RecentTaskInfo
+ */
+ @Nullable
+ protected final int[] mMinimizedTaskIds;
+
+ /**
+ * Create new for a stack of fullscreen tasks
+ */
+ public static GroupedTaskInfo forFullscreenTasks(@NonNull TaskInfo task) {
+ return new GroupedTaskInfo(List.of(task), null, TYPE_FULLSCREEN,
+ null /* minimizedFreeformTasks */);
+ }
+
+ /**
+ * Create new for a pair of tasks in split screen
+ */
+ public static GroupedTaskInfo forSplitTasks(@NonNull TaskInfo task1,
+ @NonNull TaskInfo task2, @Nullable SplitBounds splitBounds) {
+ return new GroupedTaskInfo(List.of(task1, task2), splitBounds, TYPE_SPLIT,
+ null /* minimizedFreeformTasks */);
+ }
+
+ /**
+ * Create new for a group of freeform tasks
+ */
+ public static GroupedTaskInfo forFreeformTasks(
+ @NonNull List<TaskInfo> tasks,
+ @NonNull Set<Integer> minimizedFreeformTasks) {
+ return new GroupedTaskInfo(tasks, null /* splitBounds */, TYPE_FREEFORM,
+ minimizedFreeformTasks.stream().mapToInt(i -> i).toArray());
+ }
+
+ private GroupedTaskInfo(
+ @NonNull List<TaskInfo> tasks,
+ @Nullable SplitBounds splitBounds,
+ @GroupType int type,
+ @Nullable int[] minimizedFreeformTaskIds) {
+ mTasks = tasks;
+ mSplitBounds = splitBounds;
+ mType = type;
+ mMinimizedTaskIds = minimizedFreeformTaskIds;
+ ensureAllMinimizedIdsPresent(tasks, minimizedFreeformTaskIds);
+ }
+
+ private void ensureAllMinimizedIdsPresent(
+ @NonNull List<TaskInfo> tasks,
+ @Nullable int[] minimizedFreeformTaskIds) {
+ if (minimizedFreeformTaskIds == null) {
+ return;
+ }
+ if (!Arrays.stream(minimizedFreeformTaskIds).allMatch(
+ taskId -> tasks.stream().anyMatch(task -> task.taskId == taskId))) {
+ throw new IllegalArgumentException("Minimized task IDs contain non-existent Task ID.");
+ }
+ }
+
+ protected GroupedTaskInfo(@NonNull Parcel parcel) {
+ mTasks = new ArrayList();
+ final int numTasks = parcel.readInt();
+ for (int i = 0; i < numTasks; i++) {
+ mTasks.add(new TaskInfo(parcel));
+ }
+ mSplitBounds = parcel.readTypedObject(SplitBounds.CREATOR);
+ mType = parcel.readInt();
+ mMinimizedTaskIds = parcel.createIntArray();
+ }
+
+ /**
+ * Get primary {@link RecentTaskInfo}
+ */
+ @NonNull
+ public TaskInfo getTaskInfo1() {
+ return mTasks.getFirst();
+ }
+
+ /**
+ * Get secondary {@link RecentTaskInfo}.
+ *
+ * Used in split screen.
+ */
+ @Nullable
+ public TaskInfo getTaskInfo2() {
+ if (mTasks.size() > 1) {
+ return mTasks.get(1);
+ }
+ return null;
+ }
+
+ /**
+ * Get all {@link RecentTaskInfo}s grouped together.
+ */
+ @NonNull
+ public List<TaskInfo> getTaskInfoList() {
+ return mTasks;
+ }
+
+ /**
+ * Return {@link SplitBounds} if this is a split screen entry or {@code null}
+ */
+ @Nullable
+ public SplitBounds getSplitBounds() {
+ return mSplitBounds;
+ }
+
+ /**
+ * Get type of this recents entry. One of {@link GroupType}
+ */
+ @GroupType
+ public int getType() {
+ return mType;
+ }
+
+ @Nullable
+ public int[] getMinimizedTaskIds() {
+ return mMinimizedTaskIds;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof GroupedTaskInfo)) {
+ return false;
+ }
+ GroupedTaskInfo other = (GroupedTaskInfo) obj;
+ return mType == other.mType
+ && Objects.equals(mTasks, other.mTasks)
+ && Objects.equals(mSplitBounds, other.mSplitBounds)
+ && Arrays.equals(mMinimizedTaskIds, other.mMinimizedTaskIds);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mType, mTasks, mSplitBounds, Arrays.hashCode(mMinimizedTaskIds));
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder taskString = new StringBuilder();
+ for (int i = 0; i < mTasks.size(); i++) {
+ if (i == 0) {
+ taskString.append("Task");
+ } else {
+ taskString.append(", Task");
+ }
+ taskString.append(i + 1).append(": ").append(getTaskInfo(mTasks.get(i)));
+ }
+ if (mSplitBounds != null) {
+ taskString.append(", SplitBounds: ").append(mSplitBounds);
+ }
+ taskString.append(", Type=");
+ switch (mType) {
+ case TYPE_FULLSCREEN:
+ taskString.append("TYPE_FULLSCREEN");
+ break;
+ case TYPE_SPLIT:
+ taskString.append("TYPE_SPLIT");
+ break;
+ case TYPE_FREEFORM:
+ taskString.append("TYPE_FREEFORM");
+ break;
+ }
+ taskString.append(", Minimized Task IDs: ");
+ taskString.append(Arrays.toString(mMinimizedTaskIds));
+ return taskString.toString();
+ }
+
+ private String getTaskInfo(TaskInfo taskInfo) {
+ if (taskInfo == null) {
+ return null;
+ }
+ return "id=" + taskInfo.taskId
+ + " baseIntent=" + (taskInfo.baseIntent != null
+ ? taskInfo.baseIntent.getComponent()
+ : "null")
+ + " winMode=" + WindowConfiguration.windowingModeToString(
+ taskInfo.getWindowingMode());
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ // We don't use the parcel list methods because we want to only write the TaskInfo state
+ // and not the subclasses (Recents/RunningTaskInfo) whose fields are all deprecated
+ parcel.writeInt(mTasks.size());
+ for (int i = 0; i < mTasks.size(); i++) {
+ mTasks.get(i).writeTaskToParcel(parcel, flags);
+ }
+ parcel.writeTypedObject(mSplitBounds, flags);
+ parcel.writeInt(mType);
+ parcel.writeIntArray(mMinimizedTaskIds);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Creator<GroupedTaskInfo> CREATOR = new Creator() {
+ @Override
+ public GroupedTaskInfo createFromParcel(Parcel in) {
+ return new GroupedTaskInfo(in);
+ }
+
+ @Override
+ public GroupedTaskInfo[] newArray(int size) {
+ return new GroupedTaskInfo[size];
+ }
+ };
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/PhysicsAnimatorTestUtils.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/PhysicsAnimatorTestUtils.kt
index fc3dc14..f93b35e 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/PhysicsAnimatorTestUtils.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/animation/PhysicsAnimatorTestUtils.kt
@@ -20,7 +20,7 @@
import android.util.ArrayMap
import androidx.dynamicanimation.animation.FloatPropertyCompat
import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils.prepareForTest
-import java.util.*
+import java.util.ArrayDeque
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.collections.ArrayList
@@ -74,14 +74,17 @@
@JvmStatic
fun tearDown() {
- val latch = CountDownLatch(1)
- animationThreadHandler.post {
+ if (Looper.myLooper() == animationThreadHandler.looper) {
animatorTestHelpers.keys.forEach { it.cancel() }
- latch.countDown()
+ } else {
+ val latch = CountDownLatch(1)
+ animationThreadHandler.post {
+ animatorTestHelpers.keys.forEach { it.cancel() }
+ latch.countDown()
+ }
+ latch.await(5, TimeUnit.SECONDS)
}
- latch.await()
-
animatorTestHelpers.clear()
animators.clear()
allAnimatedObjects.clear()
@@ -348,8 +351,9 @@
* Returns all of the values that have ever been reported to update listeners, per property.
*/
@Suppress("UNCHECKED_CAST")
- fun <T : Any> getAnimationUpdateFrames(animator: PhysicsAnimator<T>):
- UpdateFramesPerProperty<T> {
+ fun <T : Any> getAnimationUpdateFrames(
+ animator: PhysicsAnimator<T>
+ ): UpdateFramesPerProperty<T> {
return animatorTestHelpers[animator]?.getUpdates() as UpdateFramesPerProperty<T>
}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BaseBubblePinController.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BaseBubblePinController.kt
index 7086691..bd129a2 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BaseBubblePinController.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BaseBubblePinController.kt
@@ -56,6 +56,7 @@
onLeft = initialLocationOnLeft
screenCenterX = screenSizeProvider.invoke().x / 2
dismissZone = getExclusionRect()
+ listener?.onStart(if (initialLocationOnLeft) LEFT else RIGHT)
}
/** View has moved to [x] and [y] screen coordinates */
@@ -109,6 +110,7 @@
/** Get width for exclusion rect where dismiss takes over drag */
protected abstract fun getExclusionRectWidth(): Float
+
/** Get height for exclusion rect where dismiss takes over drag */
protected abstract fun getExclusionRectHeight(): Float
@@ -184,6 +186,9 @@
/** Receive updates on location changes */
interface LocationChangeListener {
+ /** Bubble bar dragging has started. Includes the initial location of the bar */
+ fun onStart(location: BubbleBarLocation) {}
+
/**
* Bubble bar has been dragged to a new [BubbleBarLocation]. And the drag is still in
* progress.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index b9a3050..c92a278 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -21,6 +21,7 @@
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION;
+import static android.window.BackEvent.EDGE_NONE;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
@@ -533,7 +534,15 @@
if (keyAction == MotionEvent.ACTION_DOWN) {
if (!mBackGestureStarted) {
- mShouldStartOnNextMoveEvent = true;
+ if (swipeEdge == EDGE_NONE) {
+ // start animation immediately for non-gestural sources (without ACTION_MOVE
+ // events)
+ mThresholdCrossed = true;
+ onGestureStarted(touchX, touchY, swipeEdge);
+ mShouldStartOnNextMoveEvent = false;
+ } else {
+ mShouldStartOnNextMoveEvent = true;
+ }
}
} else if (keyAction == MotionEvent.ACTION_MOVE) {
if (!mBackGestureStarted && mShouldStartOnNextMoveEvent) {
@@ -1074,6 +1083,11 @@
mCurrentTracker.updateStartLocation();
BackMotionEvent startEvent = mCurrentTracker.createStartEvent(mApps[0]);
dispatchOnBackStarted(mActiveCallback, startEvent);
+ // TODO(b/373544911): onBackStarted is dispatched here so that
+ // WindowOnBackInvokedDispatcher knows about the back navigation and intercepts touch
+ // events while it's active. It would be cleaner and safer to disable multitouch
+ // altogether (same as in gesture-nav).
+ dispatchOnBackStarted(mBackNavigationInfo.getOnBackInvokedCallback(), startEvent);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 0ce651c..2a50e4d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -241,12 +241,14 @@
if (mListener != null) {
mListener.onUnBubbleConversation(bubble.getKey());
}
+ mBubbleLogger.log(bubble, BubbleLogger.Event.BUBBLE_BAR_APP_MENU_OPT_OUT);
}
@Override
public void onOpenAppSettings(Bubble bubble) {
mManager.collapseStack();
mContext.startActivityAsUser(bubble.getSettingsIntent(mContext), bubble.getUser());
+ mBubbleLogger.log(bubble, BubbleLogger.Event.BUBBLE_BAR_APP_MENU_GO_TO_SETTINGS);
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index 402818c..999ce17 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -124,18 +124,7 @@
mBubbleExpandedViewPinController = new BubbleExpandedViewPinController(
context, this, mPositioner);
- mBubbleExpandedViewPinController.setListener(
- new BaseBubblePinController.LocationChangeListener() {
- @Override
- public void onChange(@NonNull BubbleBarLocation bubbleBarLocation) {
- mBubbleController.animateBubbleBarLocation(bubbleBarLocation);
- }
-
- @Override
- public void onRelease(@NonNull BubbleBarLocation location) {
- mBubbleController.setBubbleBarLocation(location);
- }
- });
+ mBubbleExpandedViewPinController.setListener(new LocationChangeListener());
setOnClickListener(view -> hideModalOrCollapse());
}
@@ -238,11 +227,7 @@
DragListener dragListener = inDismiss -> {
if (inDismiss && mExpandedBubble != null) {
mBubbleController.dismissBubble(mExpandedBubble.getKey(), DISMISS_USER_GESTURE);
- if (mExpandedBubble instanceof Bubble) {
- // Only a bubble can be dragged to dismiss
- mBubbleLogger.log((Bubble) mExpandedBubble,
- BubbleLogger.Event.BUBBLE_BAR_BUBBLE_DISMISSED_DRAG_EXP_VIEW);
- }
+ logBubbleEvent(BubbleLogger.Event.BUBBLE_BAR_BUBBLE_DISMISSED_DRAG_EXP_VIEW);
}
};
mDragController = new BubbleBarExpandedViewDragController(
@@ -423,10 +408,47 @@
}
}
+ /**
+ * Log the event only if {@link #mExpandedBubble} is a {@link Bubble}.
+ * <p>
+ * Skips logging if it is {@link BubbleOverflow}.
+ */
+ private void logBubbleEvent(BubbleLogger.Event event) {
+ if (mExpandedBubble != null && mExpandedBubble instanceof Bubble bubble) {
+ mBubbleLogger.log(bubble, event);
+ }
+ }
+
@Nullable
@VisibleForTesting
public BubbleBarExpandedViewDragController getDragController() {
return mDragController;
}
+ private class LocationChangeListener implements
+ BaseBubblePinController.LocationChangeListener {
+
+ private BubbleBarLocation mInitialLocation;
+
+ @Override
+ public void onStart(@NonNull BubbleBarLocation location) {
+ mInitialLocation = location;
+ }
+
+ @Override
+ public void onChange(@NonNull BubbleBarLocation bubbleBarLocation) {
+ mBubbleController.animateBubbleBarLocation(bubbleBarLocation);
+ }
+
+ @Override
+ public void onRelease(@NonNull BubbleBarLocation location) {
+ mBubbleController.setBubbleBarLocation(location);
+ if (location != mInitialLocation) {
+ BubbleLogger.Event event = location.isOnLeft(isLayoutRtl())
+ ? BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_EXP_VIEW
+ : BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_EXP_VIEW;
+ logBubbleEvent(event);
+ }
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
index 52b807a..0ee20ef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
@@ -16,7 +16,6 @@
package com.android.wm.shell.bubbles.bar;
import android.annotation.ColorInt;
-import android.annotation.Nullable;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
@@ -43,8 +42,6 @@
*/
public class BubbleBarMenuView extends LinearLayout {
- public static final Object DISMISS_ACTION_TAG = new Object();
-
private ViewGroup mBubbleSectionView;
private ViewGroup mActionsSectionView;
private ImageView mBubbleIconView;
@@ -123,9 +120,6 @@
R.layout.bubble_bar_menu_item, mActionsSectionView, false);
itemView.update(action.mIcon, action.mTitle, action.mTint);
itemView.setOnClickListener(action.mOnClick);
- if (action.mTag != null) {
- itemView.setTag(action.mTag);
- }
mActionsSectionView.addView(itemView);
}
}
@@ -166,8 +160,6 @@
private Icon mIcon;
private @ColorInt int mTint;
private String mTitle;
- @Nullable
- private Object mTag;
private OnClickListener mOnClick;
MenuAction(Icon icon, String title, OnClickListener onClick) {
@@ -180,14 +172,5 @@
this.mTint = tint;
this.mOnClick = onClick;
}
-
- MenuAction(Icon icon, String title, @ColorInt int tint, @Nullable Object tag,
- OnClickListener onClick) {
- this.mIcon = icon;
- this.mTitle = title;
- this.mTint = tint;
- this.mTag = tag;
- this.mOnClick = onClick;
- }
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
index 5ed01b6..5148107 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
@@ -212,7 +212,6 @@
Icon.createWithResource(resources, R.drawable.ic_remove_no_shadow),
resources.getString(R.string.bubble_dismiss_text),
tintColor,
- BubbleBarMenuView.DISMISS_ACTION_TAG,
view -> {
hideMenu(true /* animated */);
if (mListener != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
index b83b5f3..8ef20d1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
@@ -44,7 +44,8 @@
private const val TAG = "PipUtils"
// Minimum difference between two floats (e.g. aspect ratios) to consider them not equal.
- private const val EPSILON = 1e-7
+ // TODO b/377530560: Restore epsilon once a long term fix is merged for non-config-at-end issue.
+ private const val EPSILON = 0.05f
/**
* @return the ComponentName and user id of the top non-SystemUI activity in the pinned stack.
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 886330f..0200e18 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
@@ -286,7 +286,7 @@
// we need to ignore all the incoming TaskInfo until the education
// completes. If we come from a double tap we follow the normal flow.
final boolean topActivityPillarboxed =
- taskInfo.appCompatTaskInfo.isTopActivityPillarboxed();
+ taskInfo.appCompatTaskInfo.isTopActivityPillarboxShaped();
final boolean isFirstTimeHorizontalReachabilityEdu = topActivityPillarboxed
&& !mCompatUIConfiguration.hasSeenHorizontalReachabilityEducation(taskInfo);
final boolean isFirstTimeVerticalReachabilityEdu = !topActivityPillarboxed
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 706a678..a472f79 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
@@ -779,7 +779,8 @@
ShellTaskOrganizer shellTaskOrganizer,
ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
ReturnToDragStartAnimator returnToDragStartAnimator,
- @DynamicOverride DesktopRepository desktopRepository) {
+ @DynamicOverride DesktopRepository desktopRepository,
+ DesktopModeEventLogger desktopModeEventLogger) {
return new DesktopTilingDecorViewModel(
context,
displayController,
@@ -789,7 +790,8 @@
shellTaskOrganizer,
toggleResizeDesktopTaskTransitionHandler,
returnToDragStartAnimator,
- desktopRepository
+ desktopRepository,
+ desktopModeEventLogger
);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
index 48bb2a8..cefcb75 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
@@ -205,6 +205,11 @@
finishTransaction: SurfaceControl.Transaction,
finishCallback: TransitionFinishCallback,
): Boolean {
+ val launchChange = findDesktopTaskChange(info, pending.launchingTask)
+ if (launchChange == null) {
+ logV("No launch Change, returning")
+ return false
+ }
// Check if there's also an immersive change during this launch.
val immersiveExitChange = pending.exitingImmersiveTask?.let { exitingTask ->
findDesktopTaskChange(info, exitingTask)
@@ -212,8 +217,6 @@
val minimizeChange = pending.minimizingTask?.let { minimizingTask ->
findDesktopTaskChange(info, minimizingTask)
}
- val launchChange = findDesktopTaskChange(info, pending.launchingTask)
- ?: error("Should have pending launching task change")
var subAnimationCount = -1
var combinedWct: WindowContainerTransaction? = null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index edcc877..c7cf310 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -275,7 +275,7 @@
}
// Then check if the activity is portrait when letterboxed
- appCompatTaskInfo.isTopActivityLetterboxed -> appCompatTaskInfo.isTopActivityPillarboxed
+ appCompatTaskInfo.isTopActivityLetterboxed -> appCompatTaskInfo.isTopActivityPillarboxShaped
// Then check if the activity is portrait
appBounds != null -> appBounds.height() > appBounds.width()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index f8d2011..b618bf1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -53,6 +53,7 @@
import android.window.WindowContainerTransaction;
import com.android.internal.protolog.ProtoLog;
+import com.android.window.flags.Flags;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
@@ -72,6 +73,9 @@
public class KeyguardTransitionHandler
implements Transitions.TransitionHandler, KeyguardChangeListener,
TaskStackListenerCallback {
+ private static final boolean ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS =
+ Flags.ensureKeyguardDoesTransitionStarting();
+
private static final String TAG = "KeyguardTransition";
private final Transitions mTransitions;
@@ -194,7 +198,7 @@
// Occlude/unocclude animations are only played if the keyguard is locked.
if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0) {
- if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_OCCLUDING) != 0) {
+ if (isKeyguardOccluding(info)) {
if (hasOpeningDream(info)) {
return startAnimation(mOccludeByDreamTransition, "occlude-by-dream",
transition, info, startTransaction, finishTransaction, finishCallback);
@@ -202,7 +206,7 @@
return startAnimation(mOccludeTransition, "occlude",
transition, info, startTransaction, finishTransaction, finishCallback);
}
- } else if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_UNOCCLUDING) != 0) {
+ } else if (isKeyguardUnoccluding(info)) {
return startAnimation(mUnoccludeTransition, "unocclude",
transition, info, startTransaction, finishTransaction, finishCallback);
}
@@ -325,6 +329,36 @@
return false;
}
+ private static boolean isKeyguardOccluding(@NonNull TransitionInfo info) {
+ if (!ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) {
+ return (info.getFlags() & TRANSIT_FLAG_KEYGUARD_OCCLUDING) != 0;
+ }
+
+ for (int i = 0; i < info.getChanges().size(); i++) {
+ TransitionInfo.Change change = info.getChanges().get(i);
+ if (change.hasFlags(TransitionInfo.FLAG_IS_TASK_DISPLAY_AREA)
+ && change.getMode() == TRANSIT_TO_FRONT) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean isKeyguardUnoccluding(@NonNull TransitionInfo info) {
+ if (!ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) {
+ return (info.getFlags() & TRANSIT_FLAG_KEYGUARD_UNOCCLUDING) != 0;
+ }
+
+ for (int i = 0; i < info.getChanges().size(); i++) {
+ TransitionInfo.Change change = info.getChanges().get(i);
+ if (change.hasFlags(TransitionInfo.FLAG_IS_TASK_DISPLAY_AREA)
+ && change.getMode() == TRANSIT_TO_BACK) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void finishAnimationImmediately(IBinder transition, StartedTransition playing) {
final IBinder fakeTransition = new Binder();
final TransitionInfo fakeInfo = new TransitionInfo(TRANSIT_SLEEP, 0x0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java
index 24077a3..0264820 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java
@@ -24,7 +24,6 @@
import android.view.SurfaceControl;
import com.android.wm.shell.R;
-import com.android.wm.shell.transition.Transitions;
/**
* Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition.
@@ -180,8 +179,7 @@
// destination are different.
final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH;
final Rect crop = mTmpDestinationRect;
- crop.set(0, 0, Transitions.SHELL_TRANSITIONS_ROTATION ? destH
- : destW, Transitions.SHELL_TRANSITIONS_ROTATION ? destW : destH);
+ crop.set(0, 0, destW, destH);
// Inverse scale for crop to fit in screen coordinates.
crop.scale(1 / scale);
crop.offset(insets.left, insets.top);
@@ -200,8 +198,8 @@
}
}
mTmpTransform.setScale(scale, scale);
- mTmpTransform.postRotate(degrees);
mTmpTransform.postTranslate(positionX, positionY);
+ mTmpTransform.postRotate(degrees);
tx.setMatrix(leash, mTmpTransform, mTmpFloat9).setCrop(leash, crop);
return this;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipExpandAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipExpandAnimator.java
index 3f9b0c3..fb1aba3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipExpandAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipExpandAnimator.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.pip2.animation;
+import static android.view.Surface.ROTATION_90;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.RectEvaluator;
@@ -73,6 +75,7 @@
mAnimationStartCallback.run();
}
if (mStartTransaction != null) {
+ onExpandAnimationUpdate(mStartTransaction, 0f);
mStartTransaction.apply();
}
}
@@ -81,13 +84,7 @@
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (mFinishTransaction != null) {
- // finishTransaction might override some state (eg. corner radii) so we want to
- // manually set the state to the end of the animation
- mPipSurfaceTransactionHelper.scaleAndCrop(mFinishTransaction, mLeash,
- mSourceRectHint, mBaseBounds, mAnimatedRect, getInsets(1f),
- false /* isInPipDirection */, 1f)
- .round(mFinishTransaction, mLeash, false /* applyCornerRadius */)
- .shadow(mFinishTransaction, mLeash, false /* applyCornerRadius */);
+ onExpandAnimationUpdate(mFinishTransaction, 1f);
}
if (mAnimationEndCallback != null) {
mAnimationEndCallback.run();
@@ -102,14 +99,7 @@
final SurfaceControl.Transaction tx =
mSurfaceControlTransactionFactory.getTransaction();
final float fraction = getAnimatedFraction();
-
- // TODO (b/350801661): implement fixed rotation
- Rect insets = getInsets(fraction);
- mPipSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mSourceRectHint,
- mBaseBounds, mAnimatedRect,
- insets, false /* isInPipDirection */, fraction)
- .round(tx, mLeash, false /* applyCornerRadius */)
- .shadow(tx, mLeash, false /* applyCornerRadius */);
+ onExpandAnimationUpdate(tx, fraction);
tx.apply();
}
};
@@ -167,6 +157,32 @@
mAnimationEndCallback = runnable;
}
+ private void onExpandAnimationUpdate(SurfaceControl.Transaction tx, float fraction) {
+ Rect insets = getInsets(fraction);
+ if (mRotation == Surface.ROTATION_0) {
+ mPipSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mSourceRectHint, mBaseBounds,
+ mAnimatedRect, insets, false /* isInPipDirection */, fraction);
+ } else {
+ // Fixed rotation case.
+ Rect start = mStartBounds;
+ Rect end = mEndBounds;
+ float degrees, x, y;
+ x = fraction * (end.left - start.left) + start.left;
+ y = fraction * (end.top - start.top) + start.top;
+
+ if (mRotation == ROTATION_90) {
+ degrees = 90 * fraction;
+ } else {
+ degrees = -90 * fraction;
+ }
+ mPipSurfaceTransactionHelper.rotateAndScaleWithCrop(tx, mLeash, mBaseBounds,
+ mAnimatedRect, insets, degrees, x, y,
+ true /* isExpanding */, mRotation == ROTATION_90);
+ }
+ mPipSurfaceTransactionHelper.round(tx, mLeash, false /* applyCornerRadius */)
+ .shadow(tx, mLeash, false /* applyShadowRadius */);
+ }
+
private Rect getInsets(float fraction) {
final Rect startInsets = mSourceRectHintInsets;
final Rect endInsets = mZeroInsets;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
index 012dabb..4558a9f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
@@ -30,6 +30,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
+import com.android.wm.shell.shared.animation.Interpolators;
/**
* Animator that handles any resize related animation for PIP.
@@ -128,6 +129,7 @@
mRectEvaluator = new RectEvaluator(mAnimatedRect);
setObjectValues(startBounds, endBounds);
+ setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
addListener(mAnimatorListener);
addUpdateListener(mAnimatorUpdateListener);
setEvaluator(mRectEvaluator);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
index 58d2a85..44900ce 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
@@ -573,7 +573,7 @@
@PipTransitionState.TransitionState int newState, Bundle extra) {
switch (newState) {
case PipTransitionState.ENTERED_PIP:
- attach(mPipTransitionState.mPinnedTaskLeash);
+ attach(mPipTransitionState.getPinnedTaskLeash());
break;
case PipTransitionState.EXITED_PIP:
detach();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index 9a93371..d3f537b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -376,18 +376,20 @@
private void setLauncherKeepClearAreaHeight(boolean visible, int height) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"setLauncherKeepClearAreaHeight: visible=%b, height=%d", visible, height);
- if (visible) {
- Rect rect = new Rect(
- 0, mPipDisplayLayoutState.getDisplayBounds().bottom - height,
- mPipDisplayLayoutState.getDisplayBounds().right,
- mPipDisplayLayoutState.getDisplayBounds().bottom);
- mPipBoundsState.setNamedUnrestrictedKeepClearArea(
- PipBoundsState.NAMED_KCA_LAUNCHER_SHELF, rect);
- } else {
- mPipBoundsState.setNamedUnrestrictedKeepClearArea(
- PipBoundsState.NAMED_KCA_LAUNCHER_SHELF, null);
- }
- mPipTouchHandler.onShelfVisibilityChanged(visible, height);
+ mPipTransitionState.setOnIdlePipTransitionStateRunnable(() -> {
+ if (visible) {
+ Rect rect = new Rect(
+ 0, mPipDisplayLayoutState.getDisplayBounds().bottom - height,
+ mPipDisplayLayoutState.getDisplayBounds().right,
+ mPipDisplayLayoutState.getDisplayBounds().bottom);
+ mPipBoundsState.setNamedUnrestrictedKeepClearArea(
+ PipBoundsState.NAMED_KCA_LAUNCHER_SHELF, rect);
+ } else {
+ mPipBoundsState.setNamedUnrestrictedKeepClearArea(
+ PipBoundsState.NAMED_KCA_LAUNCHER_SHELF, null);
+ }
+ mPipTouchHandler.onShelfVisibilityChanged(visible, height);
+ });
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
index 17392bc..3738353 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
@@ -785,7 +785,7 @@
private void handleFlingTransition(SurfaceControl.Transaction startTx,
SurfaceControl.Transaction finishTx, Rect destinationBounds) {
- startTx.setPosition(mPipTransitionState.mPinnedTaskLeash,
+ startTx.setPosition(mPipTransitionState.getPinnedTaskLeash(),
destinationBounds.left, destinationBounds.top);
startTx.apply();
@@ -799,7 +799,7 @@
private void startResizeAnimation(SurfaceControl.Transaction startTx,
SurfaceControl.Transaction finishTx, Rect destinationBounds, int duration) {
- SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash;
+ SurfaceControl pipLeash = mPipTransitionState.getPinnedTaskLeash();
Preconditions.checkState(pipLeash != null,
"No leash cached by mPipTransitionState=" + mPipTransitionState);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
index 751175f..d98be55 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
@@ -531,7 +531,7 @@
// If resize transition was scheduled from this component, handle leash updates.
mWaitingForBoundsChangeTransition = false;
- SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash;
+ SurfaceControl pipLeash = mPipTransitionState.getPinnedTaskLeash();
Preconditions.checkState(pipLeash != null,
"No leash cached by mPipTransitionState=" + mPipTransitionState);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index 8b25b11..607de0e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -118,7 +118,7 @@
public void removePipAfterAnimation() {
SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
PipAlphaAnimator animator = new PipAlphaAnimator(mContext,
- mPipTransitionState.mPinnedTaskLeash, tx, PipAlphaAnimator.FADE_OUT);
+ mPipTransitionState.getPinnedTaskLeash(), tx, PipAlphaAnimator.FADE_OUT);
animator.setAnimationEndCallback(this::scheduleRemovePipImmediately);
animator.start();
}
@@ -203,7 +203,7 @@
"%s: Attempted to user resize PIP to empty bounds, aborting.", TAG);
return;
}
- SurfaceControl leash = mPipTransitionState.mPinnedTaskLeash;
+ SurfaceControl leash = mPipTransitionState.getPinnedTaskLeash();
final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
Matrix transformTensor = new Matrix();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
index 2c7584a..2f93715 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
@@ -29,6 +29,8 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.Preconditions;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.ShellExecutor;
@@ -36,6 +38,7 @@
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.pip2.animation.PipResizeAnimator;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.annotations.ShellMainThread;
import java.util.ArrayList;
@@ -49,7 +52,8 @@
public class PipTaskListener implements ShellTaskOrganizer.TaskListener,
PipTransitionState.PipTransitionStateChangedListener {
private static final int ASPECT_RATIO_CHANGE_DURATION = 250;
- private static final String ANIMATING_ASPECT_RATIO_CHANGE = "animating_aspect_ratio_change";
+ @VisibleForTesting
+ static final String ANIMATING_ASPECT_RATIO_CHANGE = "animating_aspect_ratio_change";
private final Context mContext;
private final PipTransitionState mPipTransitionState;
@@ -63,6 +67,8 @@
private boolean mWaitingForAspectRatioChange = false;
private final List<PipParamsChangedCallback> mPipParamsChangedListeners = new ArrayList<>();
+ private PipResizeAnimatorSupplier mPipResizeAnimatorSupplier;
+
public PipTaskListener(Context context,
ShellTaskOrganizer shellTaskOrganizer,
PipTransitionState pipTransitionState,
@@ -84,6 +90,7 @@
ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP);
});
}
+ mPipResizeAnimatorSupplier = PipResizeAnimator::new;
}
void setPictureInPictureParams(@Nullable PictureInPictureParams params) {
@@ -121,6 +128,9 @@
if (mPictureInPictureParams.equals(params)) {
return;
}
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "onTaskInfoChanged: %s, state=%s oldParams=%s newParams=%s",
+ taskInfo.topActivity, mPipTransitionState, mPictureInPictureParams, params);
setPictureInPictureParams(params);
float newAspectRatio = mPictureInPictureParams.getAspectRatioFloat();
if (PipUtils.aspectRatioChanged(newAspectRatio, mPipBoundsState.getAspectRatio())) {
@@ -167,18 +177,18 @@
final int duration = extra.getInt(ANIMATING_BOUNDS_CHANGE_DURATION,
PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION);
- Preconditions.checkNotNull(mPipTransitionState.mPinnedTaskLeash,
+ Preconditions.checkNotNull(mPipTransitionState.getPinnedTaskLeash(),
"Leash is null for bounds transition.");
if (mWaitingForAspectRatioChange) {
- PipResizeAnimator animator = new PipResizeAnimator(mContext,
- mPipTransitionState.mPinnedTaskLeash, startTx, finishTx,
+ mWaitingForAspectRatioChange = false;
+ PipResizeAnimator animator = mPipResizeAnimatorSupplier.get(mContext,
+ mPipTransitionState.getPinnedTaskLeash(), startTx, finishTx,
destinationBounds,
mPipBoundsState.getBounds(), destinationBounds, duration,
0f /* delta */);
- animator.setAnimationEndCallback(() -> {
- mPipScheduler.scheduleFinishResizePip(destinationBounds);
- });
+ animator.setAnimationEndCallback(
+ () -> mPipScheduler.scheduleFinishResizePip(destinationBounds));
animator.start();
}
break;
@@ -192,4 +202,22 @@
default void onActionsChanged(List<RemoteAction> actions, RemoteAction closeAction) {
}
}
+
+ @VisibleForTesting
+ interface PipResizeAnimatorSupplier {
+ PipResizeAnimator get(@NonNull Context context,
+ @NonNull SurfaceControl leash,
+ @Nullable SurfaceControl.Transaction startTx,
+ @Nullable SurfaceControl.Transaction finishTx,
+ @NonNull Rect baseBounds,
+ @NonNull Rect startBounds,
+ @NonNull Rect endBounds,
+ int duration,
+ float delta);
+ }
+
+ @VisibleForTesting
+ void setPipResizeAnimatorSupplier(@NonNull PipResizeAnimatorSupplier supplier) {
+ mPipResizeAnimatorSupplier = supplier;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
index 19d293e..65972fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -231,17 +231,15 @@
// KCA triggered movement to wait for other transitions (e.g. due to IME changes).
return;
}
- mPipTransitionState.setOnIdlePipTransitionStateRunnable(() -> {
- boolean hasUserInteracted = (mPipBoundsState.hasUserMovedPip()
- || mPipBoundsState.hasUserResizedPip());
- int delta = mPipBoundsAlgorithm.getEntryDestinationBounds().top
- - mPipBoundsState.getBounds().top;
+ boolean hasUserInteracted = (mPipBoundsState.hasUserMovedPip()
+ || mPipBoundsState.hasUserResizedPip());
+ int delta = mPipBoundsAlgorithm.getEntryDestinationBounds().top
+ - mPipBoundsState.getBounds().top;
- if (!mIsImeShowing && !hasUserInteracted && delta != 0) {
- // If the user hasn't interacted with PiP, we respect the keep clear areas
- mMotionHelper.animateToOffset(mPipBoundsState.getBounds(), delta);
- }
- });
+ if (!mIsImeShowing && !hasUserInteracted && delta != 0) {
+ // If the user hasn't interacted with PiP, we respect the keep clear areas
+ mMotionHelper.animateToOffset(mPipBoundsState.getBounds(), delta);
+ }
};
if (PipUtils.isPip2ExperimentEnabled()) {
@@ -877,7 +875,7 @@
mMovementWithinDismiss = touchState.getDownTouchPosition().y
>= mPipBoundsState.getMovementBounds().bottom;
mMotionHelper.setSpringingToTouch(false);
- mPipDismissTargetHandler.setTaskLeash(mPipTransitionState.mPinnedTaskLeash);
+ mPipDismissTargetHandler.setTaskLeash(mPipTransitionState.getPinnedTaskLeash());
// If the menu is still visible then just poke the menu
// so that it will timeout after the user stops touching it
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 6bf92f6..ea783e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -325,9 +325,7 @@
return false;
}
- SurfaceControl pipLeash = pipChange.getLeash();
- Preconditions.checkNotNull(pipLeash, "Leash is null for swipe-up transition.");
-
+ final SurfaceControl pipLeash = getLeash(pipChange);
final Rect destinationBounds = pipChange.getEndAbsBounds();
final SurfaceControl swipePipToHomeOverlay = mPipTransitionState.getSwipePipToHomeOverlay();
if (swipePipToHomeOverlay != null) {
@@ -349,7 +347,7 @@
: startRotation - endRotation;
if (delta != ROTATION_0) {
mPipTransitionState.setInFixedRotation(true);
- handleBoundsTypeFixedRotation(pipChange, pipActivityChange, endRotation);
+ handleBoundsEnterFixedRotation(pipChange, pipActivityChange, endRotation);
}
prepareConfigAtEndActivity(startTransaction, finishTransaction, pipChange,
@@ -399,7 +397,7 @@
final Rect adjustedSourceRectHint = sourceRectHint != null ? new Rect(sourceRectHint)
: PipUtils.getEnterPipWithOverlaySrcRectHint(startBounds, aspectRatio);
- final SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash;
+ final SurfaceControl pipLeash = mPipTransitionState.getPinnedTaskLeash();
// For opening type transitions, if there is a change of mode TO_FRONT/OPEN,
// make sure that change has alpha of 1f, since it's init state might be set to alpha=0f
@@ -414,15 +412,15 @@
}
final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info);
- int startRotation = pipChange.getStartRotation();
- int endRotation = fixedRotationChange != null
+ final int startRotation = pipChange.getStartRotation();
+ final int endRotation = fixedRotationChange != null
? fixedRotationChange.getEndFixedRotation() : ROTATION_UNDEFINED;
final int delta = endRotation == ROTATION_UNDEFINED ? ROTATION_0
: startRotation - endRotation;
if (delta != ROTATION_0) {
mPipTransitionState.setInFixedRotation(true);
- handleBoundsTypeFixedRotation(pipChange, pipActivityChange,
+ handleBoundsEnterFixedRotation(pipChange, pipActivityChange,
fixedRotationChange.getEndFixedRotation());
}
@@ -459,7 +457,7 @@
animator.start();
}
- private void handleBoundsTypeFixedRotation(TransitionInfo.Change pipTaskChange,
+ private void handleBoundsEnterFixedRotation(TransitionInfo.Change pipTaskChange,
TransitionInfo.Change pipActivityChange, int endRotation) {
final Rect endBounds = pipTaskChange.getEndAbsBounds();
final Rect endActivityBounds = pipActivityChange.getEndAbsBounds();
@@ -492,6 +490,26 @@
endBounds.top + activityEndOffset.y);
}
+ private void handleExpandFixedRotation(TransitionInfo.Change pipTaskChange, int endRotation) {
+ final Rect endBounds = pipTaskChange.getEndAbsBounds();
+ final int width = endBounds.width();
+ final int height = endBounds.height();
+ final int left = endBounds.left;
+ final int top = endBounds.top;
+ int newTop, newLeft;
+
+ if (endRotation == Surface.ROTATION_90) {
+ newLeft = top;
+ newTop = -(left + width);
+ } else {
+ newLeft = -(height + top);
+ newTop = left;
+ }
+ // Modify the endBounds, rotating and placing them potentially off-screen, so that
+ // as we translate and rotate around the origin, we place them right into the target.
+ endBounds.set(newLeft, newTop, newLeft + height, newTop + width);
+ }
+
private boolean startAlphaTypeEnterAnimation(@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
@@ -503,7 +521,7 @@
}
Rect destinationBounds = pipChange.getEndAbsBounds();
- SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash;
+ SurfaceControl pipLeash = mPipTransitionState.getPinnedTaskLeash();
Preconditions.checkNotNull(pipLeash, "Leash is null for alpha transition.");
// Start transition with 0 alpha at the entry bounds.
@@ -544,33 +562,51 @@
}
}
- // for multi activity, we need to manually set the leash layer
- if (pipChange.getTaskInfo() == null) {
- TransitionInfo.Change parent = getChangeByToken(info, pipChange.getParent());
- if (parent != null) {
- startTransaction.setLayer(parent.getLeash(), Integer.MAX_VALUE - 1);
- }
+ // The parent change if we were in a multi-activity PiP; null if single activity PiP.
+ final TransitionInfo.Change parentBeforePip = pipChange.getTaskInfo() == null
+ ? getChangeByToken(info, pipChange.getParent()) : null;
+ if (parentBeforePip != null) {
+ // For multi activity, we need to manually set the leash layer
+ startTransaction.setLayer(parentBeforePip.getLeash(), Integer.MAX_VALUE - 1);
}
- Rect startBounds = pipChange.getStartAbsBounds();
- Rect endBounds = pipChange.getEndAbsBounds();
- SurfaceControl pipLeash = pipChange.getLeash();
- Preconditions.checkNotNull(pipLeash, "Leash is null for exit transition.");
+ final Rect startBounds = pipChange.getStartAbsBounds();
+ final Rect endBounds = pipChange.getEndAbsBounds();
+ final SurfaceControl pipLeash = getLeash(pipChange);
- Rect sourceRectHint = null;
- if (pipChange.getTaskInfo() != null
- && pipChange.getTaskInfo().pictureInPictureParams != null) {
+ PictureInPictureParams params = null;
+ if (pipChange.getTaskInfo() != null) {
// single activity
- sourceRectHint = pipChange.getTaskInfo().pictureInPictureParams.getSourceRectHint();
- } else if (mPipTaskListener.getPictureInPictureParams().hasSourceBoundsHint()) {
+ params = pipChange.getTaskInfo().pictureInPictureParams;
+ } else if (parentBeforePip != null && parentBeforePip.getTaskInfo() != null) {
// multi activity
- sourceRectHint = mPipTaskListener.getPictureInPictureParams().getSourceRectHint();
+ params = parentBeforePip.getTaskInfo().pictureInPictureParams;
+ }
+ final Rect sourceRectHint = PipBoundsAlgorithm.getValidSourceHintRect(params, endBounds,
+ startBounds);
+
+ final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info);
+ final int startRotation = pipChange.getStartRotation();
+ final int endRotation = fixedRotationChange != null
+ ? fixedRotationChange.getEndFixedRotation() : ROTATION_UNDEFINED;
+ final int delta = endRotation == ROTATION_UNDEFINED ? ROTATION_0
+ : endRotation - startRotation;
+
+ if (delta != ROTATION_0) {
+ handleExpandFixedRotation(pipChange, endRotation);
}
PipExpandAnimator animator = new PipExpandAnimator(mContext, pipLeash,
startTransaction, finishTransaction, endBounds, startBounds, endBounds,
- sourceRectHint, Surface.ROTATION_0);
- animator.setAnimationEndCallback(this::finishTransition);
+ sourceRectHint, delta);
+ animator.setAnimationEndCallback(() -> {
+ if (parentBeforePip != null) {
+ // TODO b/377362511: Animate local leash instead to also handle letterbox case.
+ // For multi-activity, set the crop to be null
+ finishTransaction.setCrop(pipLeash, null);
+ }
+ finishTransition();
+ });
animator.start();
return true;
}
@@ -717,6 +753,13 @@
}
}
+ @NonNull
+ private SurfaceControl getLeash(TransitionInfo.Change change) {
+ SurfaceControl leash = change.getLeash();
+ Preconditions.checkNotNull(leash, "Leash is null for change=" + change);
+ return leash;
+ }
+
//
// Miscellaneous callbacks and listeners
//
@@ -754,17 +797,17 @@
mPipTransitionState.mPipTaskToken = extra.getParcelable(
PIP_TASK_TOKEN, WindowContainerToken.class);
- mPipTransitionState.mPinnedTaskLeash = extra.getParcelable(
- PIP_TASK_LEASH, SurfaceControl.class);
+ mPipTransitionState.setPinnedTaskLeash(extra.getParcelable(
+ PIP_TASK_LEASH, SurfaceControl.class));
boolean hasValidTokenAndLeash = mPipTransitionState.mPipTaskToken != null
- && mPipTransitionState.mPinnedTaskLeash != null;
+ && mPipTransitionState.getPinnedTaskLeash() != null;
Preconditions.checkState(hasValidTokenAndLeash,
"Unexpected bundle for " + mPipTransitionState);
break;
case PipTransitionState.EXITED_PIP:
mPipTransitionState.mPipTaskToken = null;
- mPipTransitionState.mPinnedTaskLeash = null;
+ mPipTransitionState.setPinnedTaskLeash(null);
break;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
index ccdd66b..03e06f9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
@@ -142,7 +142,7 @@
// pinned PiP task's leash
@Nullable
- SurfaceControl mPinnedTaskLeash;
+ private SurfaceControl mPinnedTaskLeash;
// Overlay leash potentially used during swipe PiP to home transition;
// if null while mInSwipePipToHomeTransition is true, then srcRectHint was invalid.
@@ -304,6 +304,14 @@
mSwipePipToHomeAppBounds.setEmpty();
}
+ @Nullable SurfaceControl getPinnedTaskLeash() {
+ return mPinnedTaskLeash;
+ }
+
+ void setPinnedTaskLeash(@Nullable SurfaceControl leash) {
+ mPinnedTaskLeash = leash;
+ }
+
/**
* @return true if either in swipe or button-nav fixed rotation.
*/
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 799028a..4a301cc 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
@@ -24,7 +24,7 @@
import com.android.wm.shell.recents.IRecentsAnimationRunner;
import com.android.wm.shell.recents.IRecentTasksListener;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
/**
* Interface that is exposed to remote callers to fetch recent tasks.
@@ -44,7 +44,7 @@
/**
* Gets the set of recent tasks.
*/
- GroupedRecentTaskInfo[] getRecentTasks(int maxNum, int flags, int userId) = 3;
+ GroupedTaskInfo[] getRecentTasks(int maxNum, int flags, int userId) = 3;
/**
* Gets the set of running tasks.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
index 371bdd5..b58f068 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
@@ -18,6 +18,8 @@
import android.app.ActivityManager.RunningTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
+
/**
* Listener interface that Launcher attaches to SystemUI to get split-screen callbacks.
*/
@@ -44,8 +46,8 @@
void onRunningTaskChanged(in RunningTaskInfo taskInfo);
/** A task has moved to front. */
- oneway void onTaskMovedToFront(in RunningTaskInfo taskInfo);
+ void onTaskMovedToFront(in GroupedTaskInfo[] visibleTasks);
/** A task info has changed. */
- oneway void onTaskInfoChanged(in RunningTaskInfo taskInfo);
+ void onTaskInfoChanged(in RunningTaskInfo taskInfo);
}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasks.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasks.java
index 8c5d1e7..364a087 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasks.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasks.java
@@ -19,7 +19,7 @@
import android.annotation.Nullable;
import android.graphics.Color;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.annotations.ExternalThread;
import java.util.List;
@@ -35,7 +35,7 @@
* Gets the set of recent tasks.
*/
default void getRecentTasks(int maxNum, int flags, int userId, Executor callbackExecutor,
- Consumer<List<GroupedRecentTaskInfo>> callback) {
+ Consumer<List<GroupedTaskInfo>> callback) {
}
/**
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 faa2015..9911669 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,10 +24,12 @@
import android.Manifest;
import android.annotation.RequiresPermission;
import android.app.ActivityManager;
+import android.app.ActivityManager.RecentTaskInfo;
import android.app.ActivityTaskManager;
import android.app.IApplicationThread;
import android.app.KeyguardManager;
import android.app.PendingIntent;
+import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -55,7 +57,7 @@
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.annotations.ExternalThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -379,7 +381,8 @@
return;
}
try {
- mListener.onTaskMovedToFront(taskInfo);
+ GroupedTaskInfo runningTask = GroupedTaskInfo.forFullscreenTasks(taskInfo);
+ mListener.onTaskMovedToFront(new GroupedTaskInfo[]{ runningTask });
} catch (RemoteException e) {
Slog.w(TAG, "Failed call onTaskMovedToFront", e);
}
@@ -407,27 +410,27 @@
}
@VisibleForTesting
- ArrayList<GroupedRecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
+ ArrayList<GroupedTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
// Note: the returned task list is from the most-recent to least-recent order
- final List<ActivityManager.RecentTaskInfo> rawList = mActivityTaskManager.getRecentTasks(
+ final List<RecentTaskInfo> rawList = mActivityTaskManager.getRecentTasks(
maxNum, flags, userId);
// Make a mapping of task id -> task info
- final SparseArray<ActivityManager.RecentTaskInfo> rawMapping = new SparseArray<>();
+ final SparseArray<TaskInfo> rawMapping = new SparseArray<>();
for (int i = 0; i < rawList.size(); i++) {
- final ActivityManager.RecentTaskInfo taskInfo = rawList.get(i);
+ final TaskInfo taskInfo = rawList.get(i);
rawMapping.put(taskInfo.taskId, taskInfo);
}
- ArrayList<ActivityManager.RecentTaskInfo> freeformTasks = new ArrayList<>();
+ ArrayList<TaskInfo> freeformTasks = new ArrayList<>();
Set<Integer> minimizedFreeformTasks = new HashSet<>();
int mostRecentFreeformTaskIndex = Integer.MAX_VALUE;
// Pull out the pairs as we iterate back in the list
- ArrayList<GroupedRecentTaskInfo> recentTasks = new ArrayList<>();
+ ArrayList<GroupedTaskInfo> recentTasks = new ArrayList<>();
for (int i = 0; i < rawList.size(); i++) {
- final ActivityManager.RecentTaskInfo taskInfo = rawList.get(i);
+ final RecentTaskInfo taskInfo = rawList.get(i);
if (!rawMapping.contains(taskInfo.taskId)) {
// If it's not in the mapping, then it was already paired with another task
continue;
@@ -460,20 +463,20 @@
final int pairedTaskId = mSplitTasks.get(taskInfo.taskId, INVALID_TASK_ID);
if (pairedTaskId != INVALID_TASK_ID && rawMapping.contains(
pairedTaskId)) {
- final ActivityManager.RecentTaskInfo pairedTaskInfo = rawMapping.get(pairedTaskId);
+ final TaskInfo pairedTaskInfo = rawMapping.get(pairedTaskId);
rawMapping.remove(pairedTaskId);
- recentTasks.add(GroupedRecentTaskInfo.forSplitTasks(taskInfo, pairedTaskInfo,
+ recentTasks.add(GroupedTaskInfo.forSplitTasks(taskInfo, pairedTaskInfo,
mTaskSplitBoundsMap.get(pairedTaskId)));
} else {
- recentTasks.add(GroupedRecentTaskInfo.forSingleTask(taskInfo));
+ recentTasks.add(GroupedTaskInfo.forFullscreenTasks(taskInfo));
}
}
// Add a special entry for freeform tasks
if (!freeformTasks.isEmpty()) {
recentTasks.add(mostRecentFreeformTaskIndex,
- GroupedRecentTaskInfo.forFreeformTasks(
- freeformTasks.toArray(new ActivityManager.RecentTaskInfo[0]),
+ GroupedTaskInfo.forFreeformTasks(
+ freeformTasks,
minimizedFreeformTasks));
}
@@ -514,16 +517,16 @@
* {@param ignoreTaskToken} if it is non-null.
*/
@Nullable
- public ActivityManager.RecentTaskInfo findTaskInBackground(ComponentName componentName,
+ public RecentTaskInfo findTaskInBackground(ComponentName componentName,
int userId, @Nullable WindowContainerToken ignoreTaskToken) {
if (componentName == null) {
return null;
}
- List<ActivityManager.RecentTaskInfo> tasks = mActivityTaskManager.getRecentTasks(
+ List<RecentTaskInfo> tasks = mActivityTaskManager.getRecentTasks(
Integer.MAX_VALUE, ActivityManager.RECENT_IGNORE_UNAVAILABLE,
ActivityManager.getCurrentUser());
for (int i = 0; i < tasks.size(); i++) {
- final ActivityManager.RecentTaskInfo task = tasks.get(i);
+ final RecentTaskInfo task = tasks.get(i);
if (task.isVisible) {
continue;
}
@@ -541,12 +544,12 @@
* Find the background task that match the given taskId.
*/
@Nullable
- public ActivityManager.RecentTaskInfo findTaskInBackground(int taskId) {
- List<ActivityManager.RecentTaskInfo> tasks = mActivityTaskManager.getRecentTasks(
+ public RecentTaskInfo findTaskInBackground(int taskId) {
+ List<RecentTaskInfo> tasks = mActivityTaskManager.getRecentTasks(
Integer.MAX_VALUE, ActivityManager.RECENT_IGNORE_UNAVAILABLE,
ActivityManager.getCurrentUser());
for (int i = 0; i < tasks.size(); i++) {
- final ActivityManager.RecentTaskInfo task = tasks.get(i);
+ final RecentTaskInfo task = tasks.get(i);
if (task.isVisible) {
continue;
}
@@ -570,7 +573,7 @@
pw.println(prefix + TAG);
pw.println(prefix + " mListener=" + mListener);
pw.println(prefix + "Tasks:");
- ArrayList<GroupedRecentTaskInfo> recentTasks = getRecentTasks(Integer.MAX_VALUE,
+ ArrayList<GroupedTaskInfo> recentTasks = getRecentTasks(Integer.MAX_VALUE,
ActivityManager.RECENT_IGNORE_UNAVAILABLE, ActivityManager.getCurrentUser());
for (int i = 0; i < recentTasks.size(); i++) {
pw.println(innerPrefix + recentTasks.get(i));
@@ -584,9 +587,9 @@
private class RecentTasksImpl implements RecentTasks {
@Override
public void getRecentTasks(int maxNum, int flags, int userId, Executor executor,
- Consumer<List<GroupedRecentTaskInfo>> callback) {
+ Consumer<List<GroupedTaskInfo>> callback) {
mMainExecutor.execute(() -> {
- List<GroupedRecentTaskInfo> tasks =
+ List<GroupedTaskInfo> tasks =
RecentTasksController.this.getRecentTasks(maxNum, flags, userId);
executor.execute(() -> callback.accept(tasks));
});
@@ -650,7 +653,7 @@
}
@Override
- public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onTaskMovedToFront(GroupedTaskInfo[] taskInfo) {
mListener.call(l -> l.onTaskMovedToFront(taskInfo));
}
@@ -692,17 +695,20 @@
}
@Override
- public GroupedRecentTaskInfo[] getRecentTasks(int maxNum, int flags, int userId)
+ public GroupedTaskInfo[] getRecentTasks(int maxNum, int flags, int userId)
throws RemoteException {
if (mController == null) {
// The controller is already invalidated -- just return an empty task list for now
- return new GroupedRecentTaskInfo[0];
+ return new GroupedTaskInfo[0];
}
- final GroupedRecentTaskInfo[][] out = new GroupedRecentTaskInfo[][]{null};
+ final GroupedTaskInfo[][] out = new GroupedTaskInfo[][]{null};
executeRemoteCallWithTaskPermission(mController, "getRecentTasks",
- (controller) -> out[0] = controller.getRecentTasks(maxNum, flags, userId)
- .toArray(new GroupedRecentTaskInfo[0]),
+ (controller) -> {
+ List<GroupedTaskInfo> tasks = controller.getRecentTasks(
+ maxNum, flags, userId);
+ out[0] = tasks.toArray(new GroupedTaskInfo[0]);
+ },
true /* blocking */);
return out[0];
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index ec58292..29e4b5b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -395,10 +395,17 @@
continue;
}
// No default animation for this, so just update bounds/position.
- final int rootIdx = TransitionUtil.rootIndexFor(change, info);
- startTransaction.setPosition(change.getLeash(),
- change.getEndAbsBounds().left - info.getRoot(rootIdx).getOffset().x,
- change.getEndAbsBounds().top - info.getRoot(rootIdx).getOffset().y);
+ if (change.getParent() == null) {
+ // For independent change without a parent, we have reparented it to the root
+ // leash in Transitions#setupAnimHierarchy.
+ final int rootIdx = TransitionUtil.rootIndexFor(change, info);
+ startTransaction.setPosition(change.getLeash(),
+ change.getEndAbsBounds().left - info.getRoot(rootIdx).getOffset().x,
+ change.getEndAbsBounds().top - info.getRoot(rootIdx).getOffset().y);
+ } else {
+ startTransaction.setPosition(change.getLeash(),
+ change.getEndRelOffset().x, change.getEndRelOffset().y);
+ }
// Seamless display transition doesn't need to animate.
if (isSeamlessDisplayChange) continue;
if (isTask || (change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index be4fd7c..7265fb8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -24,6 +24,8 @@
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
import static android.view.WindowManager.TRANSIT_CHANGE;
+import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions;
+
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ContentResolver;
import android.content.Context;
@@ -195,7 +197,12 @@
return;
}
- decoration.relayout(taskInfo, decoration.mHasGlobalFocus);
+ if (enableDisplayFocusInShellTransitions()) {
+ // Pass the current global focus status to avoid updates outside of a ShellTransition.
+ decoration.relayout(taskInfo, decoration.mHasGlobalFocus);
+ } else {
+ decoration.relayout(taskInfo, taskInfo.isFocused);
+ }
}
@Override
@@ -496,4 +503,4 @@
return Settings.Global.getInt(resolver,
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
}
-}
\ No newline at end of file
+}
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 17e3dd2..f2d8a78 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
@@ -31,6 +31,7 @@
import static android.view.WindowInsets.Type.statusBars;
import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU;
+import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions;
import static com.android.wm.shell.compatui.AppCompatUtils.isTopActivityExemptFromDesktopWindowing;
import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
@@ -468,7 +469,12 @@
removeTaskFromEventReceiver(oldTaskInfo.displayId);
incrementEventReceiverTasks(taskInfo.displayId);
}
- decoration.relayout(taskInfo, decoration.mHasGlobalFocus);
+ if (enableDisplayFocusInShellTransitions()) {
+ // Pass the current global focus status to avoid updates outside of a ShellTransition.
+ decoration.relayout(taskInfo, decoration.mHasGlobalFocus);
+ } else {
+ decoration.relayout(taskInfo, taskInfo.isFocused);
+ }
mActivityOrientationChangeHandler.ifPresent(handler ->
handler.handleActivityOrientationChange(oldTaskInfo, taskInfo));
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
index e43c3a6..61963cd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
@@ -30,6 +30,7 @@
import com.android.wm.shell.common.DisplayChangeController
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
@@ -48,6 +49,7 @@
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
private val returnToDragStartAnimator: ReturnToDragStartAnimator,
private val taskRepository: DesktopRepository,
+ private val desktopModeEventLogger: DesktopModeEventLogger,
) : DisplayChangeController.OnDisplayChangingListener {
@VisibleForTesting
var tilingTransitionHandlerByDisplayId = SparseArray<DesktopTilingWindowDecoration>()
@@ -80,6 +82,7 @@
toggleResizeDesktopTaskTransitionHandler,
returnToDragStartAnimator,
taskRepository,
+ desktopModeEventLogger,
)
tilingTransitionHandlerByDisplayId.put(displayId, newHandler)
newHandler
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
index 209eb5e..6cdc517c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
@@ -23,6 +23,7 @@
import android.graphics.Region
import android.os.Binder
import android.view.LayoutInflater
+import android.view.MotionEvent
import android.view.RoundedCorner
import android.view.SurfaceControl
import android.view.SurfaceControlViewHost
@@ -39,6 +40,7 @@
import android.view.WindowlessWindowManager
import com.android.wm.shell.R
import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import java.util.function.Supplier
/**
@@ -141,8 +143,9 @@
t.setRelativeLayer(leash, relativeLeash, 1)
}
- override fun onDividerMoveStart(pos: Int) {
+ override fun onDividerMoveStart(pos: Int, motionEvent: MotionEvent) {
setSlippery(false)
+ transitionHandler.onDividerHandleDragStart(motionEvent)
}
/**
@@ -161,13 +164,13 @@
* Notifies the transition handler of tiling operations ending, which might result in resizing
* WindowContainerTransactions if the sizes of the tiled tasks changed.
*/
- override fun onDividerMovedEnd(pos: Int) {
+ override fun onDividerMovedEnd(pos: Int, motionEvent: MotionEvent) {
setSlippery(true)
val t = transactionSupplier.get()
t.setPosition(leash, pos.toFloat() - maxRoundedCornerRadius, dividerBounds.top.toFloat())
val dividerWidth = dividerBounds.width()
dividerBounds.set(pos, dividerBounds.top, pos + dividerWidth, dividerBounds.bottom)
- transitionHandler.onDividerHandleDragEnd(dividerBounds, t)
+ transitionHandler.onDividerHandleDragEnd(dividerBounds, t, motionEvent)
}
private fun getWindowManagerParams(): WindowManager.LayoutParams {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index c46767c..1c593c03 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -25,6 +25,7 @@
import android.os.IBinder
import android.os.UserHandle
import android.util.Slog
+import android.view.MotionEvent
import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
import android.view.WindowManager.TRANSIT_CHANGE
@@ -44,6 +45,8 @@
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
@@ -70,6 +73,7 @@
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
private val returnToDragStartAnimator: ReturnToDragStartAnimator,
private val taskRepository: DesktopRepository,
+ private val desktopModeEventLogger: DesktopModeEventLogger,
private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() },
) :
Transitions.TransitionHandler,
@@ -218,6 +222,25 @@
return tilingManager
}
+ fun onDividerHandleDragStart(motionEvent: MotionEvent) {
+ val leftTiledTask = leftTaskResizingHelper ?: return
+ val rightTiledTask = rightTaskResizingHelper ?: return
+
+ desktopModeEventLogger.logTaskResizingStarted(
+ ResizeTrigger.TILING_DIVIDER,
+ motionEvent,
+ leftTiledTask.taskInfo,
+ displayController
+ )
+
+ desktopModeEventLogger.logTaskResizingStarted(
+ ResizeTrigger.TILING_DIVIDER,
+ motionEvent,
+ rightTiledTask.taskInfo,
+ displayController
+ )
+ }
+
fun onDividerHandleMoved(dividerBounds: Rect, t: SurfaceControl.Transaction): Boolean {
val leftTiledTask = leftTaskResizingHelper ?: return false
val rightTiledTask = rightTaskResizingHelper ?: return false
@@ -266,10 +289,32 @@
return true
}
- fun onDividerHandleDragEnd(dividerBounds: Rect, t: SurfaceControl.Transaction) {
+ fun onDividerHandleDragEnd(
+ dividerBounds: Rect,
+ t: SurfaceControl.Transaction,
+ motionEvent: MotionEvent,
+ ) {
val leftTiledTask = leftTaskResizingHelper ?: return
val rightTiledTask = rightTaskResizingHelper ?: return
+ desktopModeEventLogger.logTaskResizingEnded(
+ ResizeTrigger.TILING_DIVIDER,
+ motionEvent,
+ leftTiledTask.taskInfo,
+ leftTiledTask.newBounds.height(),
+ leftTiledTask.newBounds.width(),
+ displayController
+ )
+
+ desktopModeEventLogger.logTaskResizingEnded(
+ ResizeTrigger.TILING_DIVIDER,
+ motionEvent,
+ rightTiledTask.taskInfo,
+ rightTiledTask.newBounds.height(),
+ rightTiledTask.newBounds.width(),
+ displayController
+ )
+
if (leftTiledTask.newBounds == leftTiledTask.bounds) {
leftTiledTask.hideVeil()
rightTiledTask.hideVeil()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DividerMoveCallback.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DividerMoveCallback.kt
index b3b30ad..9799d01 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DividerMoveCallback.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DividerMoveCallback.kt
@@ -15,14 +15,16 @@
*/
package com.android.wm.shell.windowdecor.tiling
+import android.view.MotionEvent
+
/** Divider move callback to whichever entity that handles the moving logic. */
interface DividerMoveCallback {
/** Called on the divider move start gesture. */
- fun onDividerMoveStart(pos: Int)
+ fun onDividerMoveStart(pos: Int, motionEvent: MotionEvent)
/** Called on the divider moved by dragging it. */
fun onDividerMove(pos: Int): Boolean
/** Called on divider move gesture end. */
- fun onDividerMovedEnd(pos: Int)
+ fun onDividerMovedEnd(pos: Int, motionEvent: MotionEvent)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
index 8922905..111e28e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
@@ -206,7 +206,7 @@
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
if (!isWithinHandleRegion(yTouchPosInDivider)) return true
- callback.onDividerMoveStart(touchPos)
+ callback.onDividerMoveStart(touchPos, event)
setTouching()
canResize = true
}
@@ -230,7 +230,7 @@
if (!canResize) return true
if (moving && resized) {
dividerBounds.left = dividerBounds.left + lastAcceptedPos - startPos
- callback.onDividerMovedEnd(dividerBounds.left)
+ callback.onDividerMovedEnd(dividerBounds.left, event)
}
moving = false
canResize = false
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
index df061e3..b06c2da 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandlerTest.kt
@@ -447,6 +447,37 @@
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS)
+ fun startAnimation_pendingTransition_noLaunchChange_returnsFalse() {
+ val wct = WindowContainerTransaction()
+ val launchingTask = createTask(WINDOWING_MODE_FREEFORM)
+ val nonLaunchTaskChange = createChange(createTask(WINDOWING_MODE_FREEFORM))
+ val transition = Binder()
+ whenever(transitions.startTransition(eq(TRANSIT_OPEN), eq(wct), anyOrNull()))
+ .thenReturn(transition)
+ mixedHandler.addPendingMixedTransition(
+ PendingMixedTransition.Launch(
+ transition = transition,
+ launchingTask = launchingTask.taskId,
+ minimizingTask = null,
+ exitingImmersiveTask = null,
+ )
+ )
+
+ val started = mixedHandler.startAnimation(
+ transition,
+ createTransitionInfo(
+ TRANSIT_OPEN,
+ listOf(nonLaunchTaskChange)
+ ),
+ SurfaceControl.Transaction(),
+ SurfaceControl.Transaction(),
+ ) { }
+
+ assertFalse("Should not start animation without launching desktop task", started)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS)
fun addPendingAndAnimateLaunchTransition_noMinimizeChange_doesNotReparentMinimizeChange() {
val wct = WindowContainerTransaction()
val launchingTask = createTask(WINDOWING_MODE_FREEFORM)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipExpandAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipExpandAnimatorTest.java
index e19a10a..b816f0e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipExpandAnimatorTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipExpandAnimatorTest.java
@@ -93,6 +93,17 @@
.thenReturn(mMockTransaction);
when(mMockTransaction.setShadowRadius(any(SurfaceControl.class), anyFloat()))
.thenReturn(mMockTransaction);
+ // No-op on the mMockStartTransaction
+ when(mMockStartTransaction.setAlpha(any(SurfaceControl.class), anyFloat()))
+ .thenReturn(mMockFinishTransaction);
+ when(mMockStartTransaction.setCrop(any(SurfaceControl.class), any(Rect.class)))
+ .thenReturn(mMockFinishTransaction);
+ when(mMockStartTransaction.setMatrix(any(SurfaceControl.class), any(Matrix.class), any()))
+ .thenReturn(mMockFinishTransaction);
+ when(mMockStartTransaction.setCornerRadius(any(SurfaceControl.class), anyFloat()))
+ .thenReturn(mMockFinishTransaction);
+ when(mMockStartTransaction.setShadowRadius(any(SurfaceControl.class), anyFloat()))
+ .thenReturn(mMockFinishTransaction);
// Do the same for mMockFinishTransaction
when(mMockFinishTransaction.setAlpha(any(SurfaceControl.class), anyFloat()))
.thenReturn(mMockFinishTransaction);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
new file mode 100644
index 0000000..89cb729
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.pip2.phone;
+
+import static com.android.wm.shell.pip2.phone.PipTaskListener.ANIMATING_ASPECT_RATIO_CHANGE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
+import static org.mockito.kotlin.MatchersKt.eq;
+import static org.mockito.kotlin.VerificationKt.clearInvocations;
+import static org.mockito.kotlin.VerificationKt.times;
+import static org.mockito.kotlin.VerificationKt.verify;
+import static org.mockito.kotlin.VerificationKt.verifyZeroInteractions;
+
+import android.app.ActivityManager;
+import android.app.PendingIntent;
+import android.app.PictureInPictureParams;
+import android.app.RemoteAction;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.util.Rational;
+import android.view.SurfaceControl;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
+import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.pip2.animation.PipResizeAnimator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Unit test against {@link PipTaskListener}.
+ */
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner.class)
+public class PipTaskListenerTest {
+
+ @Mock private Context mMockContext;
+ @Mock private ShellTaskOrganizer mMockShellTaskOrganizer;
+ @Mock private PipTransitionState mMockPipTransitionState;
+ @Mock private SurfaceControl mMockLeash;
+ @Mock private PipScheduler mMockPipScheduler;
+ @Mock private PipBoundsState mMockPipBoundsState;
+ @Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
+ @Mock private ShellExecutor mMockShellExecutor;
+
+ @Mock private Icon mMockIcon;
+ @Mock private PendingIntent mMockPendingIntent;
+
+ @Mock private PipTaskListener.PipParamsChangedCallback mMockPipParamsChangedCallback;
+
+ @Mock private PipResizeAnimator mMockPipResizeAnimator;
+
+ private ArgumentCaptor<List<RemoteAction>> mRemoteActionListCaptor;
+
+ private PipTaskListener mPipTaskListener;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mRemoteActionListCaptor = ArgumentCaptor.forClass(List.class);
+ when(mMockPipTransitionState.getPinnedTaskLeash()).thenReturn(mMockLeash);
+ }
+
+ @Test
+ public void constructor_addPipTransitionStateChangedListener() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+
+ verify(mMockPipTransitionState).addPipTransitionStateChangedListener(eq(mPipTaskListener));
+ }
+
+ @Test
+ public void setPictureInPictureParams_updatePictureInPictureParams() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ Rational aspectRatio = new Rational(4, 3);
+ String action1 = "action1";
+
+ mPipTaskListener.setPictureInPictureParams(getPictureInPictureParams(
+ aspectRatio, action1));
+
+ PictureInPictureParams params = mPipTaskListener.getPictureInPictureParams();
+ assertEquals(aspectRatio, params.getAspectRatio());
+ assertTrue(params.hasSetActions());
+ assertEquals(1, params.getActions().size());
+ assertEquals(action1, params.getActions().get(0).getTitle());
+ }
+
+ @Test
+ public void setPictureInPictureParams_withActionsChanged_callbackActionsChanged() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ mPipTaskListener.addParamsChangedListener(mMockPipParamsChangedCallback);
+ Rational aspectRatio = new Rational(4, 3);
+ String action1 = "action1";
+ mPipTaskListener.setPictureInPictureParams(getPictureInPictureParams(
+ aspectRatio, action1));
+
+ clearInvocations(mMockPipParamsChangedCallback);
+ action1 = "modified action1";
+ mPipTaskListener.setPictureInPictureParams(getPictureInPictureParams(
+ aspectRatio, action1));
+
+ verify(mMockPipParamsChangedCallback).onActionsChanged(
+ mRemoteActionListCaptor.capture(), any());
+ assertEquals(1, mRemoteActionListCaptor.getValue().size());
+ assertEquals(action1, mRemoteActionListCaptor.getValue().get(0).getTitle());
+ }
+
+ @Test
+ public void setPictureInPictureParams_withoutActionsChanged_doesNotCallbackActionsChanged() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ mPipTaskListener.addParamsChangedListener(mMockPipParamsChangedCallback);
+ Rational aspectRatio = new Rational(4, 3);
+ String action1 = "action1";
+ mPipTaskListener.setPictureInPictureParams(getPictureInPictureParams(
+ aspectRatio, action1));
+
+ clearInvocations(mMockPipParamsChangedCallback);
+ mPipTaskListener.setPictureInPictureParams(getPictureInPictureParams(
+ aspectRatio, action1));
+
+ verifyZeroInteractions(mMockPipParamsChangedCallback);
+ }
+
+ @Test
+ public void onTaskInfoChanged_withActionsChanged_callbackActionsChanged() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ mPipTaskListener.addParamsChangedListener(mMockPipParamsChangedCallback);
+ Rational aspectRatio = new Rational(4, 3);
+ when(mMockPipBoundsState.getAspectRatio()).thenReturn(aspectRatio.toFloat());
+ String action1 = "action1";
+ mPipTaskListener.onTaskInfoChanged(getTaskInfo(aspectRatio, action1));
+
+ clearInvocations(mMockPipParamsChangedCallback);
+ clearInvocations(mMockPipBoundsState);
+ action1 = "modified action1";
+ mPipTaskListener.onTaskInfoChanged(getTaskInfo(aspectRatio, action1));
+
+ verify(mMockPipTransitionState, times(0))
+ .setOnIdlePipTransitionStateRunnable(any(Runnable.class));
+ verify(mMockPipParamsChangedCallback).onActionsChanged(
+ mRemoteActionListCaptor.capture(), any());
+ assertEquals(1, mRemoteActionListCaptor.getValue().size());
+ assertEquals(action1, mRemoteActionListCaptor.getValue().get(0).getTitle());
+ }
+
+ @Test
+ public void onTaskInfoChanged_withAspectRatioChanged_callbackAspectRatioChanged() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ mPipTaskListener.addParamsChangedListener(mMockPipParamsChangedCallback);
+ Rational aspectRatio = new Rational(4, 3);
+ when(mMockPipBoundsState.getAspectRatio()).thenReturn(aspectRatio.toFloat());
+ String action1 = "action1";
+ mPipTaskListener.onTaskInfoChanged(getTaskInfo(aspectRatio, action1));
+
+ clearInvocations(mMockPipParamsChangedCallback);
+ clearInvocations(mMockPipBoundsState);
+ aspectRatio = new Rational(16, 9);
+ mPipTaskListener.onTaskInfoChanged(getTaskInfo(aspectRatio, action1));
+
+ verify(mMockPipTransitionState).setOnIdlePipTransitionStateRunnable(any(Runnable.class));
+ verifyZeroInteractions(mMockPipParamsChangedCallback);
+ }
+
+ @Test
+ public void onTaskInfoChanged_withoutParamsChanged_doesNotCallbackAspectRatioChanged() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ mPipTaskListener.addParamsChangedListener(mMockPipParamsChangedCallback);
+ Rational aspectRatio = new Rational(4, 3);
+ when(mMockPipBoundsState.getAspectRatio()).thenReturn(aspectRatio.toFloat());
+ String action1 = "action1";
+ mPipTaskListener.onTaskInfoChanged(getTaskInfo(aspectRatio, action1));
+
+ clearInvocations(mMockPipParamsChangedCallback);
+ mPipTaskListener.onTaskInfoChanged(getTaskInfo(aspectRatio, action1));
+
+ verifyZeroInteractions(mMockPipParamsChangedCallback);
+ verify(mMockPipTransitionState, times(0))
+ .setOnIdlePipTransitionStateRunnable(any(Runnable.class));
+ }
+
+ @Test
+ public void onPipTransitionStateChanged_scheduledBoundsChangeWithAspectRatioChange_schedule() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ Bundle extras = new Bundle();
+ extras.putBoolean(ANIMATING_ASPECT_RATIO_CHANGE, true);
+
+ mPipTaskListener.onPipTransitionStateChanged(
+ PipTransitionState.UNDEFINED, PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extras);
+
+ verify(mMockPipScheduler).scheduleAnimateResizePip(any(), anyBoolean(), anyInt());
+ }
+
+ @Test
+ public void onPipTransitionStateChanged_scheduledBoundsChangeWithoutAspectRatioChange_noop() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ Bundle extras = new Bundle();
+ extras.putBoolean(ANIMATING_ASPECT_RATIO_CHANGE, false);
+
+ mPipTaskListener.onPipTransitionStateChanged(
+ PipTransitionState.UNDEFINED,
+ PipTransitionState.SCHEDULED_BOUNDS_CHANGE,
+ extras);
+
+ verifyZeroInteractions(mMockPipScheduler);
+ }
+
+ @Test
+ public void onPipTransitionStateChanged_changingPipBoundsWaitAspectRatioChange_animate() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ Bundle extras = new Bundle();
+ extras.putBoolean(ANIMATING_ASPECT_RATIO_CHANGE, true);
+ extras.putParcelable(PipTransition.PIP_DESTINATION_BOUNDS,
+ new Rect(0, 0, 100, 100));
+ when(mMockPipBoundsState.getBounds()).thenReturn(new Rect(0, 0, 200, 200));
+
+ mPipTaskListener.onPipTransitionStateChanged(
+ PipTransitionState.UNDEFINED,
+ PipTransitionState.SCHEDULED_BOUNDS_CHANGE,
+ extras);
+ mPipTaskListener.setPipResizeAnimatorSupplier(
+ (context, leash, startTx, finishTx, baseBounds, startBounds, endBounds,
+ duration, delta) -> mMockPipResizeAnimator);
+ mPipTaskListener.onPipTransitionStateChanged(
+ PipTransitionState.SCHEDULED_BOUNDS_CHANGE,
+ PipTransitionState.CHANGING_PIP_BOUNDS,
+ extras);
+
+ verify(mMockPipResizeAnimator, times(1)).start();
+ }
+
+ @Test
+ public void onPipTransitionStateChanged_changingPipBoundsNotAspectRatioChange_noop() {
+ mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+ mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+ mMockPipBoundsAlgorithm, mMockShellExecutor);
+ Bundle extras = new Bundle();
+ extras.putBoolean(ANIMATING_ASPECT_RATIO_CHANGE, false);
+ extras.putParcelable(PipTransition.PIP_DESTINATION_BOUNDS,
+ new Rect(0, 0, 100, 100));
+ when(mMockPipBoundsState.getBounds()).thenReturn(new Rect(0, 0, 200, 200));
+
+ mPipTaskListener.onPipTransitionStateChanged(
+ PipTransitionState.UNDEFINED,
+ PipTransitionState.SCHEDULED_BOUNDS_CHANGE,
+ extras);
+ mPipTaskListener.setPipResizeAnimatorSupplier(
+ (context, leash, startTx, finishTx, baseBounds, startBounds, endBounds,
+ duration, delta) -> mMockPipResizeAnimator);
+ mPipTaskListener.onPipTransitionStateChanged(
+ PipTransitionState.SCHEDULED_BOUNDS_CHANGE,
+ PipTransitionState.CHANGING_PIP_BOUNDS,
+ extras);
+
+ verify(mMockPipResizeAnimator, times(0)).start();
+ }
+
+ private PictureInPictureParams getPictureInPictureParams(Rational aspectRatio,
+ String... actions) {
+ final PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder();
+ builder.setAspectRatio(aspectRatio);
+ final List<RemoteAction> remoteActions = new ArrayList<>();
+ for (String action : actions) {
+ remoteActions.add(new RemoteAction(mMockIcon, action, action, mMockPendingIntent));
+ }
+ if (!remoteActions.isEmpty()) {
+ builder.setActions(remoteActions);
+ }
+ return builder.build();
+ }
+
+ private ActivityManager.RunningTaskInfo getTaskInfo(Rational aspectRatio,
+ String... actions) {
+ final ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
+ taskInfo.pictureInPictureParams = getPictureInPictureParams(aspectRatio, actions);
+ return taskInfo;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
similarity index 81%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
index 0c100fc..2b30bc3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.recents
import android.app.ActivityManager
+import android.app.TaskInfo
import android.graphics.Rect
import android.os.Parcel
import android.testing.AndroidTestingRunner
@@ -24,11 +25,10 @@
import android.window.WindowContainerToken
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.shared.GroupedRecentTaskInfo
-import com.android.wm.shell.shared.GroupedRecentTaskInfo.CREATOR
-import com.android.wm.shell.shared.GroupedRecentTaskInfo.TYPE_FREEFORM
-import com.android.wm.shell.shared.GroupedRecentTaskInfo.TYPE_SINGLE
-import com.android.wm.shell.shared.GroupedRecentTaskInfo.TYPE_SPLIT
+import com.android.wm.shell.shared.GroupedTaskInfo
+import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM
+import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FULLSCREEN
+import com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT
import com.android.wm.shell.shared.split.SplitBounds
import com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50
import com.google.common.truth.Correspondence
@@ -39,15 +39,15 @@
import org.mockito.Mockito.mock
/**
- * Tests for [GroupedRecentTaskInfo]
+ * Tests for [GroupedTaskInfo]
*/
@SmallTest
@RunWith(AndroidTestingRunner::class)
-class GroupedRecentTaskInfoTest : ShellTestCase() {
+class GroupedTaskInfoTest : ShellTestCase() {
@Test
fun testSingleTask_hasCorrectType() {
- assertThat(singleTaskGroupInfo().type).isEqualTo(TYPE_SINGLE)
+ assertThat(singleTaskGroupInfo().type).isEqualTo(TYPE_FULLSCREEN)
}
@Test
@@ -117,8 +117,9 @@
recentTaskInfo.writeToParcel(parcel, 0)
parcel.setDataPosition(0)
// Read the object back from the parcel
- val recentTaskInfoParcel = CREATOR.createFromParcel(parcel)
- assertThat(recentTaskInfoParcel.type).isEqualTo(TYPE_SINGLE)
+ val recentTaskInfoParcel: GroupedTaskInfo =
+ GroupedTaskInfo.CREATOR.createFromParcel(parcel)
+ assertThat(recentTaskInfoParcel.type).isEqualTo(TYPE_FULLSCREEN)
assertThat(recentTaskInfoParcel.taskInfo1.taskId).isEqualTo(1)
assertThat(recentTaskInfoParcel.taskInfo2).isNull()
}
@@ -130,7 +131,8 @@
recentTaskInfo.writeToParcel(parcel, 0)
parcel.setDataPosition(0)
// Read the object back from the parcel
- val recentTaskInfoParcel = CREATOR.createFromParcel(parcel)
+ val recentTaskInfoParcel: GroupedTaskInfo =
+ GroupedTaskInfo.CREATOR.createFromParcel(parcel)
assertThat(recentTaskInfoParcel.type).isEqualTo(TYPE_SPLIT)
assertThat(recentTaskInfoParcel.taskInfo1.taskId).isEqualTo(1)
assertThat(recentTaskInfoParcel.taskInfo2).isNotNull()
@@ -146,11 +148,12 @@
recentTaskInfo.writeToParcel(parcel, 0)
parcel.setDataPosition(0)
// Read the object back from the parcel
- val recentTaskInfoParcel = CREATOR.createFromParcel(parcel)
+ val recentTaskInfoParcel: GroupedTaskInfo =
+ GroupedTaskInfo.CREATOR.createFromParcel(parcel)
assertThat(recentTaskInfoParcel.type).isEqualTo(TYPE_FREEFORM)
assertThat(recentTaskInfoParcel.taskInfoList).hasSize(3)
// Only compare task ids
- val taskIdComparator = Correspondence.transforming<ActivityManager.RecentTaskInfo, Int>(
+ val taskIdComparator = Correspondence.transforming<TaskInfo, Int>(
{ it?.taskId }, "has taskId of"
)
assertThat(recentTaskInfoParcel.taskInfoList).comparingElementsUsing(taskIdComparator)
@@ -167,7 +170,8 @@
parcel.setDataPosition(0)
// Read the object back from the parcel
- val recentTaskInfoParcel = CREATOR.createFromParcel(parcel)
+ val recentTaskInfoParcel: GroupedTaskInfo =
+ GroupedTaskInfo.CREATOR.createFromParcel(parcel)
assertThat(recentTaskInfoParcel.type).isEqualTo(TYPE_FREEFORM)
assertThat(recentTaskInfoParcel.minimizedTaskIds).isEqualTo(arrayOf(2).toIntArray())
}
@@ -177,24 +181,24 @@
token = WindowContainerToken(mock(IWindowContainerToken::class.java))
}
- private fun singleTaskGroupInfo(): GroupedRecentTaskInfo {
+ private fun singleTaskGroupInfo(): GroupedTaskInfo {
val task = createTaskInfo(id = 1)
- return GroupedRecentTaskInfo.forSingleTask(task)
+ return GroupedTaskInfo.forFullscreenTasks(task)
}
- private fun splitTasksGroupInfo(): GroupedRecentTaskInfo {
+ private fun splitTasksGroupInfo(): GroupedTaskInfo {
val task1 = createTaskInfo(id = 1)
val task2 = createTaskInfo(id = 2)
val splitBounds = SplitBounds(Rect(), Rect(), 1, 2, SNAP_TO_2_50_50)
- return GroupedRecentTaskInfo.forSplitTasks(task1, task2, splitBounds)
+ return GroupedTaskInfo.forSplitTasks(task1, task2, splitBounds)
}
private fun freeformTasksGroupInfo(
freeformTaskIds: Array<Int>,
minimizedTaskIds: Array<Int> = emptyArray()
- ): GroupedRecentTaskInfo {
- return GroupedRecentTaskInfo.forFreeformTasks(
- freeformTaskIds.map { createTaskInfo(it) }.toTypedArray(),
+ ): GroupedTaskInfo {
+ return GroupedTaskInfo.forFreeformTasks(
+ freeformTaskIds.map { createTaskInfo(it) }.toList(),
minimizedTaskIds.toSet())
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 9b73d53..dede583 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -46,6 +46,7 @@
import static java.lang.Integer.MAX_VALUE;
import android.app.ActivityManager;
+import android.app.ActivityManager.RecentTaskInfo;
import android.app.ActivityTaskManager;
import android.app.KeyguardManager;
import android.content.ComponentName;
@@ -71,7 +72,7 @@
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.desktopmode.DesktopRepository;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.ShellSharedConstants;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.shared.split.SplitBounds;
@@ -193,8 +194,8 @@
@Test
public void testAddRemoveSplitNotifyChange() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
setRawList(t1, t2);
mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, mock(SplitBounds.class));
@@ -207,8 +208,8 @@
@Test
public void testAddSameSplitBoundsInfoSkipNotifyChange() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
setRawList(t1, t2);
// Verify only one update if the split info is the same
@@ -223,13 +224,13 @@
@Test
public void testGetRecentTasks() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
- ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t3 = makeTaskInfo(3);
setRawList(t1, t2, t3);
- ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
- MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+ ArrayList<GroupedTaskInfo> recentTasks =
+ mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
assertGroupedTasksListEquals(recentTasks,
t1.taskId, -1,
t2.taskId, -1,
@@ -238,12 +239,12 @@
@Test
public void testGetRecentTasks_withPairs() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
- ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
- ActivityManager.RecentTaskInfo t4 = makeTaskInfo(4);
- ActivityManager.RecentTaskInfo t5 = makeTaskInfo(5);
- ActivityManager.RecentTaskInfo t6 = makeTaskInfo(6);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t3 = makeTaskInfo(3);
+ RecentTaskInfo t4 = makeTaskInfo(4);
+ RecentTaskInfo t5 = makeTaskInfo(5);
+ RecentTaskInfo t6 = makeTaskInfo(6);
setRawList(t1, t2, t3, t4, t5, t6);
// Mark a couple pairs [t2, t4], [t3, t5]
@@ -255,8 +256,8 @@
mRecentTasksController.addSplitPair(t2.taskId, t4.taskId, pair1Bounds);
mRecentTasksController.addSplitPair(t3.taskId, t5.taskId, pair2Bounds);
- ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
- MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+ ArrayList<GroupedTaskInfo> recentTasks =
+ mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
assertGroupedTasksListEquals(recentTasks,
t1.taskId, -1,
t2.taskId, t4.taskId,
@@ -267,14 +268,14 @@
@Test
public void testGetRecentTasks_ReturnsRecentTasksAsynchronously() {
@SuppressWarnings("unchecked")
- final List<GroupedRecentTaskInfo>[] recentTasks = new List[1];
- Consumer<List<GroupedRecentTaskInfo>> consumer = argument -> recentTasks[0] = argument;
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
- ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
- ActivityManager.RecentTaskInfo t4 = makeTaskInfo(4);
- ActivityManager.RecentTaskInfo t5 = makeTaskInfo(5);
- ActivityManager.RecentTaskInfo t6 = makeTaskInfo(6);
+ final List<GroupedTaskInfo>[] recentTasks = new List[1];
+ Consumer<List<GroupedTaskInfo>> consumer = argument -> recentTasks[0] = argument;
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t3 = makeTaskInfo(3);
+ RecentTaskInfo t4 = makeTaskInfo(4);
+ RecentTaskInfo t5 = makeTaskInfo(5);
+ RecentTaskInfo t6 = makeTaskInfo(6);
setRawList(t1, t2, t3, t4, t5, t6);
// Mark a couple pairs [t2, t4], [t3, t5]
@@ -287,7 +288,8 @@
mRecentTasksController.addSplitPair(t3.taskId, t5.taskId, pair2Bounds);
mRecentTasksController.asRecentTasks()
- .getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0, Runnable::run, consumer);
+ .getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0, Runnable::run,
+ consumer);
mMainExecutor.flushAll();
assertGroupedTasksListEquals(recentTasks[0],
@@ -299,28 +301,28 @@
@Test
public void testGetRecentTasks_hasActiveDesktopTasks_proto2Enabled_groupFreeformTasks() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
- ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
- ActivityManager.RecentTaskInfo t4 = makeTaskInfo(4);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t3 = makeTaskInfo(3);
+ RecentTaskInfo t4 = makeTaskInfo(4);
setRawList(t1, t2, t3, t4);
when(mDesktopRepository.isActiveTask(1)).thenReturn(true);
when(mDesktopRepository.isActiveTask(3)).thenReturn(true);
- ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
- MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+ ArrayList<GroupedTaskInfo> recentTasks =
+ mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
// 2 freeform tasks should be grouped into one, 3 total recents entries
assertEquals(3, recentTasks.size());
- GroupedRecentTaskInfo freeformGroup = recentTasks.get(0);
- GroupedRecentTaskInfo singleGroup1 = recentTasks.get(1);
- GroupedRecentTaskInfo singleGroup2 = recentTasks.get(2);
+ GroupedTaskInfo freeformGroup = recentTasks.get(0);
+ GroupedTaskInfo singleGroup1 = recentTasks.get(1);
+ GroupedTaskInfo singleGroup2 = recentTasks.get(2);
// Check that groups have expected types
- assertEquals(GroupedRecentTaskInfo.TYPE_FREEFORM, freeformGroup.getType());
- assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, singleGroup1.getType());
- assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, singleGroup2.getType());
+ assertEquals(GroupedTaskInfo.TYPE_FREEFORM, freeformGroup.getType());
+ assertEquals(GroupedTaskInfo.TYPE_FULLSCREEN, singleGroup1.getType());
+ assertEquals(GroupedTaskInfo.TYPE_FULLSCREEN, singleGroup2.getType());
// Check freeform group entries
assertEquals(t1, freeformGroup.getTaskInfoList().get(0));
@@ -333,11 +335,11 @@
@Test
public void testGetRecentTasks_hasActiveDesktopTasks_proto2Enabled_freeformTaskOrder() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
- ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
- ActivityManager.RecentTaskInfo t4 = makeTaskInfo(4);
- ActivityManager.RecentTaskInfo t5 = makeTaskInfo(5);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t3 = makeTaskInfo(3);
+ RecentTaskInfo t4 = makeTaskInfo(4);
+ RecentTaskInfo t5 = makeTaskInfo(5);
setRawList(t1, t2, t3, t4, t5);
SplitBounds pair1Bounds =
@@ -347,19 +349,19 @@
when(mDesktopRepository.isActiveTask(3)).thenReturn(true);
when(mDesktopRepository.isActiveTask(5)).thenReturn(true);
- ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
- MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+ ArrayList<GroupedTaskInfo> recentTasks =
+ mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
// 2 split screen tasks grouped, 2 freeform tasks grouped, 3 total recents entries
assertEquals(3, recentTasks.size());
- GroupedRecentTaskInfo splitGroup = recentTasks.get(0);
- GroupedRecentTaskInfo freeformGroup = recentTasks.get(1);
- GroupedRecentTaskInfo singleGroup = recentTasks.get(2);
+ GroupedTaskInfo splitGroup = recentTasks.get(0);
+ GroupedTaskInfo freeformGroup = recentTasks.get(1);
+ GroupedTaskInfo singleGroup = recentTasks.get(2);
// Check that groups have expected types
- assertEquals(GroupedRecentTaskInfo.TYPE_SPLIT, splitGroup.getType());
- assertEquals(GroupedRecentTaskInfo.TYPE_FREEFORM, freeformGroup.getType());
- assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, singleGroup.getType());
+ assertEquals(GroupedTaskInfo.TYPE_SPLIT, splitGroup.getType());
+ assertEquals(GroupedTaskInfo.TYPE_FREEFORM, freeformGroup.getType());
+ assertEquals(GroupedTaskInfo.TYPE_FULLSCREEN, singleGroup.getType());
// Check freeform group entries
assertEquals(t3, freeformGroup.getTaskInfoList().get(0));
@@ -378,24 +380,24 @@
ExtendedMockito.doReturn(false)
.when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
- ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
- ActivityManager.RecentTaskInfo t4 = makeTaskInfo(4);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t3 = makeTaskInfo(3);
+ RecentTaskInfo t4 = makeTaskInfo(4);
setRawList(t1, t2, t3, t4);
when(mDesktopRepository.isActiveTask(1)).thenReturn(true);
when(mDesktopRepository.isActiveTask(3)).thenReturn(true);
- ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
- MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+ ArrayList<GroupedTaskInfo> recentTasks =
+ mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
// Expect no grouping of tasks
assertEquals(4, recentTasks.size());
- assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(0).getType());
- assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(1).getType());
- assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(2).getType());
- assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(3).getType());
+ assertEquals(GroupedTaskInfo.TYPE_FULLSCREEN, recentTasks.get(0).getType());
+ assertEquals(GroupedTaskInfo.TYPE_FULLSCREEN, recentTasks.get(1).getType());
+ assertEquals(GroupedTaskInfo.TYPE_FULLSCREEN, recentTasks.get(2).getType());
+ assertEquals(GroupedTaskInfo.TYPE_FULLSCREEN, recentTasks.get(3).getType());
assertEquals(t1, recentTasks.get(0).getTaskInfo1());
assertEquals(t2, recentTasks.get(1).getTaskInfo1());
@@ -405,11 +407,11 @@
@Test
public void testGetRecentTasks_proto2Enabled_includesMinimizedFreeformTasks() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
- ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
- ActivityManager.RecentTaskInfo t4 = makeTaskInfo(4);
- ActivityManager.RecentTaskInfo t5 = makeTaskInfo(5);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t3 = makeTaskInfo(3);
+ RecentTaskInfo t4 = makeTaskInfo(4);
+ RecentTaskInfo t5 = makeTaskInfo(5);
setRawList(t1, t2, t3, t4, t5);
when(mDesktopRepository.isActiveTask(1)).thenReturn(true);
@@ -417,19 +419,19 @@
when(mDesktopRepository.isActiveTask(5)).thenReturn(true);
when(mDesktopRepository.isMinimizedTask(3)).thenReturn(true);
- ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
- MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+ ArrayList<GroupedTaskInfo> recentTasks =
+ mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
// 3 freeform tasks should be grouped into one, 2 single tasks, 3 total recents entries
assertEquals(3, recentTasks.size());
- GroupedRecentTaskInfo freeformGroup = recentTasks.get(0);
- GroupedRecentTaskInfo singleGroup1 = recentTasks.get(1);
- GroupedRecentTaskInfo singleGroup2 = recentTasks.get(2);
+ GroupedTaskInfo freeformGroup = recentTasks.get(0);
+ GroupedTaskInfo singleGroup1 = recentTasks.get(1);
+ GroupedTaskInfo singleGroup2 = recentTasks.get(2);
// Check that groups have expected types
- assertEquals(GroupedRecentTaskInfo.TYPE_FREEFORM, freeformGroup.getType());
- assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, singleGroup1.getType());
- assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, singleGroup2.getType());
+ assertEquals(GroupedTaskInfo.TYPE_FREEFORM, freeformGroup.getType());
+ assertEquals(GroupedTaskInfo.TYPE_FULLSCREEN, singleGroup1.getType());
+ assertEquals(GroupedTaskInfo.TYPE_FULLSCREEN, singleGroup2.getType());
// Check freeform group entries
assertEquals(3, freeformGroup.getTaskInfoList().size());
@@ -445,8 +447,8 @@
@Test
@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE)
public void testGetRecentTasks_hasDesktopTasks_persistenceEnabled_freeformTaskHaveBoundsSet() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
t1.lastNonFullscreenBounds = new Rect(100, 200, 300, 400);
t2.lastNonFullscreenBounds = new Rect(150, 250, 350, 450);
@@ -455,11 +457,11 @@
when(mDesktopRepository.isActiveTask(1)).thenReturn(true);
when(mDesktopRepository.isActiveTask(2)).thenReturn(true);
- ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
- MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+ ArrayList<GroupedTaskInfo> recentTasks =
+ mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
assertEquals(1, recentTasks.size());
- GroupedRecentTaskInfo freeformGroup = recentTasks.get(0);
+ GroupedTaskInfo freeformGroup = recentTasks.get(0);
// Check bounds
assertEquals(t1.lastNonFullscreenBounds, freeformGroup.getTaskInfoList().get(
@@ -478,9 +480,9 @@
@Test
public void testRemovedTaskRemovesSplit() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
- ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
- ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t2 = makeTaskInfo(2);
+ RecentTaskInfo t3 = makeTaskInfo(3);
setRawList(t1, t2, t3);
// Add a pair
@@ -500,7 +502,7 @@
@Test
public void testTaskWindowingModeChangedNotifiesChange() {
- ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo t1 = makeTaskInfo(1);
setRawList(t1);
// Remove one of the tasks and ensure the pair is removed
@@ -607,7 +609,8 @@
mRecentTasksControllerReal.onTaskMovedToFrontThroughTransition(taskInfo);
- verify(mRecentTasksListener).onTaskMovedToFront(taskInfo);
+ GroupedTaskInfo runningTask = GroupedTaskInfo.forFullscreenTasks(taskInfo);
+ verify(mRecentTasksListener).onTaskMovedToFront(eq(new GroupedTaskInfo[] { runningTask }));
}
@Test
@@ -656,8 +659,8 @@
/**
* Helper to create a task with a given task id.
*/
- private ActivityManager.RecentTaskInfo makeTaskInfo(int taskId) {
- ActivityManager.RecentTaskInfo info = new ActivityManager.RecentTaskInfo();
+ private RecentTaskInfo makeTaskInfo(int taskId) {
+ RecentTaskInfo info = new RecentTaskInfo();
info.taskId = taskId;
info.lastNonFullscreenBounds = new Rect();
return info;
@@ -676,10 +679,10 @@
/**
* Helper to set the raw task list on the controller.
*/
- private ArrayList<ActivityManager.RecentTaskInfo> setRawList(
- ActivityManager.RecentTaskInfo... tasks) {
- ArrayList<ActivityManager.RecentTaskInfo> rawList = new ArrayList<>();
- for (ActivityManager.RecentTaskInfo task : tasks) {
+ private ArrayList<RecentTaskInfo> setRawList(
+ RecentTaskInfo... tasks) {
+ ArrayList<RecentTaskInfo> rawList = new ArrayList<>();
+ for (RecentTaskInfo task : tasks) {
rawList.add(task);
}
doReturn(rawList).when(mActivityTaskManager).getRecentTasks(anyInt(), anyInt(),
@@ -693,11 +696,11 @@
* @param expectedTaskIds list of task ids that map to the flattened task ids of the tasks in
* the grouped task list
*/
- private void assertGroupedTasksListEquals(List<GroupedRecentTaskInfo> recentTasks,
+ private void assertGroupedTasksListEquals(List<GroupedTaskInfo> recentTasks,
int... expectedTaskIds) {
int[] flattenedTaskIds = new int[recentTasks.size() * 2];
for (int i = 0; i < recentTasks.size(); i++) {
- GroupedRecentTaskInfo pair = recentTasks.get(i);
+ GroupedTaskInfo pair = recentTasks.get(i);
int taskId1 = pair.getTaskInfo1().taskId;
flattenedTaskIds[2 * i] = taskId1;
flattenedTaskIds[2 * i + 1] = pair.getTaskInfo2() != null
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index ef3af8e..966651f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -217,7 +217,6 @@
// Put the same component to the top running task
ActivityManager.RunningTaskInfo topRunningTask =
createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
- doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(any());
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
@@ -238,7 +237,6 @@
// Put the same component to the top running task
ActivityManager.RunningTaskInfo topRunningTask =
createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
- doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(any());
// Put the same component into a task in the background
ActivityManager.RecentTaskInfo sameTaskInfo = new ActivityManager.RecentTaskInfo();
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 6cde056..2442a55 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
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
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;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
@@ -363,6 +364,25 @@
}
@Test
+ public void testTransitionFilterWindowingMode() {
+ TransitionFilter filter = new TransitionFilter();
+ filter.mRequirements =
+ new TransitionFilter.Requirement[]{new TransitionFilter.Requirement()};
+ filter.mRequirements[0].mWindowingMode = WINDOWING_MODE_FREEFORM;
+ filter.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
+
+ final TransitionInfo fullscreenStd = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(TRANSIT_OPEN, createTaskInfo(
+ 1, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD)).build();
+ assertFalse(filter.matches(fullscreenStd));
+
+ final TransitionInfo freeformStd = new TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(TRANSIT_OPEN, createTaskInfo(
+ 1, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD)).build();
+ assertTrue(filter.matches(freeformStd));
+ }
+
+ @Test
public void testTransitionFilterMultiRequirement() {
// filter that requires at-least one opening and one closing app
TransitionFilter filter = new TransitionFilter();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 5626717..956100d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -1307,6 +1307,48 @@
verify(decor).closeMaximizeMenu()
}
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS)
+ fun testOnTaskInfoChanged_enableShellTransitionsFlag() {
+ val task = createTask(
+ windowingMode = WINDOWING_MODE_FREEFORM
+ )
+ val taskSurface = SurfaceControl()
+ val decoration = setUpMockDecorationForTask(task)
+
+ onTaskOpening(task, taskSurface)
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
+
+ decoration.mHasGlobalFocus = true
+ desktopModeWindowDecorViewModel.onTaskInfoChanged(task)
+ verify(decoration).relayout(task, true)
+
+ decoration.mHasGlobalFocus = false
+ desktopModeWindowDecorViewModel.onTaskInfoChanged(task)
+ verify(decoration).relayout(task, false)
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS)
+ fun testOnTaskInfoChanged_disableShellTransitionsFlag() {
+ val task = createTask(
+ windowingMode = WINDOWING_MODE_FREEFORM
+ )
+ val taskSurface = SurfaceControl()
+ val decoration = setUpMockDecorationForTask(task)
+
+ onTaskOpening(task, taskSurface)
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
+
+ task.isFocused = true
+ desktopModeWindowDecorViewModel.onTaskInfoChanged(task)
+ verify(decoration).relayout(task, true)
+
+ task.isFocused = false
+ desktopModeWindowDecorViewModel.onTaskInfoChanged(task)
+ verify(decoration).relayout(task, false)
+ }
+
private fun createOpenTaskDecoration(
@WindowingMode windowingMode: Int,
taskSurface: SurfaceControl = SurfaceControl(),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
index 80ad1df..d44c015 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
@@ -25,6 +25,7 @@
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
@@ -52,6 +53,7 @@
private val transitionsMock: Transitions = mock()
private val shellTaskOrganizerMock: ShellTaskOrganizer = mock()
private val desktopRepository: DesktopRepository = mock()
+ private val desktopModeEventLogger: DesktopModeEventLogger = mock()
private val toggleResizeDesktopTaskTransitionHandlerMock:
ToggleResizeDesktopTaskTransitionHandler =
mock()
@@ -74,6 +76,7 @@
toggleResizeDesktopTaskTransitionHandlerMock,
returnToDragStartAnimatorMock,
desktopRepository,
+ desktopModeEventLogger,
)
whenever(contextMock.createContextAsUser(any(), any())).thenReturn(contextMock)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index f371f52..057d8fa3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -21,6 +21,7 @@
import android.graphics.Rect
import android.os.IBinder
import android.testing.AndroidTestingRunner
+import android.view.MotionEvent
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_CHANGE
import android.view.WindowManager.TRANSIT_TO_FRONT
@@ -33,6 +34,8 @@
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
@@ -91,7 +94,9 @@
private val info: TransitionInfo = mock()
private val finishCallback: Transitions.TransitionFinishCallback = mock()
private val desktopRepository: DesktopRepository = mock()
+ private val desktopModeEventLogger: DesktopModeEventLogger = mock()
private val desktopTilingDividerWindowManager: DesktopTilingDividerWindowManager = mock()
+ private val motionEvent: MotionEvent = mock()
private lateinit var tilingDecoration: DesktopTilingWindowDecoration
private val split_divider_width = 10
@@ -112,6 +117,7 @@
toggleResizeDesktopTaskTransitionHandler,
returnToDragStartAnimator,
desktopRepository,
+ desktopModeEventLogger,
)
whenever(context.createContextAsUser(any(), any())).thenReturn(context)
}
@@ -371,13 +377,13 @@
// End moving, no startTransition because bounds did not change.
tiledTaskHelper.newBounds.set(BOUNDS)
- tilingDecoration.onDividerHandleDragEnd(BOUNDS, transaction)
+ tilingDecoration.onDividerHandleDragEnd(BOUNDS, transaction, motionEvent)
verify(tiledTaskHelper, times(2)).hideVeil()
verify(transitions, never()).startTransition(any(), any(), any())
// Move then end again with bounds changing to ensure startTransition is called.
tilingDecoration.onDividerHandleMoved(BOUNDS, transaction)
- tilingDecoration.onDividerHandleDragEnd(BOUNDS, transaction)
+ tilingDecoration.onDividerHandleDragEnd(BOUNDS, transaction, motionEvent)
verify(transitions, times(1))
.startTransition(eq(TRANSIT_CHANGE), any(), eq(tilingDecoration))
// No hide veil until start animation is called.
@@ -389,6 +395,64 @@
}
@Test
+ fun tiledTasksResizedUsingDividerHandle_shouldLogResizingEvents() {
+ // Setup
+ val task1 = createFreeformTask()
+ val task2 = createFreeformTask()
+ val stableBounds = STABLE_BOUNDS_MOCK
+ whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
+ whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
+ (i.arguments.first() as Rect).set(stableBounds)
+ }
+ whenever(context.resources).thenReturn(resources)
+ whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width)
+ desktopWindowDecoration.mTaskInfo = task1
+ task1.minWidth = 0
+ task1.minHeight = 0
+ initTiledTaskHelperMock(task1)
+ desktopWindowDecoration.mDecorWindowContext = context
+ whenever(resources.getBoolean(any())).thenReturn(true)
+
+ // Act
+ tilingDecoration.onAppTiled(
+ task1,
+ desktopWindowDecoration,
+ DesktopTasksController.SnapPosition.RIGHT,
+ BOUNDS,
+ )
+ tilingDecoration.onAppTiled(
+ task2,
+ desktopWindowDecoration,
+ DesktopTasksController.SnapPosition.LEFT,
+ BOUNDS,
+ )
+ tilingDecoration.leftTaskResizingHelper = tiledTaskHelper
+ tilingDecoration.rightTaskResizingHelper = tiledTaskHelper
+ tilingDecoration.onDividerHandleDragStart(motionEvent)
+ // Log start event for task1 and task2, but the tasks are the same in
+ // this test, so we verify the same log twice.
+ verify(desktopModeEventLogger, times(2)).logTaskResizingStarted(
+ ResizeTrigger.TILING_DIVIDER,
+ motionEvent,
+ task1,
+ displayController,
+ )
+
+ tilingDecoration.onDividerHandleMoved(BOUNDS, transaction)
+ tilingDecoration.onDividerHandleDragEnd(BOUNDS, transaction, motionEvent)
+ // Log end event for task1 and task2, but the tasks are the same in
+ // this test, so we verify the same log twice.
+ verify(desktopModeEventLogger, times(2)).logTaskResizingEnded(
+ ResizeTrigger.TILING_DIVIDER,
+ motionEvent,
+ task1,
+ BOUNDS.height(),
+ BOUNDS.width(),
+ displayController,
+ )
+ }
+
+ @Test
fun taskTiled_shouldBeRemoved_whenTileBroken() {
val task1 = createFreeformTask()
val stableBounds = STABLE_BOUNDS_MOCK
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt
index c96ce95..734815c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt
@@ -68,7 +68,7 @@
val downMotionEvent =
getMotionEvent(downTime, MotionEvent.ACTION_DOWN, x.toFloat(), y.toFloat())
tilingDividerView.handleMotionEvent(viewMock, downMotionEvent)
- verify(dividerMoveCallbackMock, times(1)).onDividerMoveStart(any())
+ verify(dividerMoveCallbackMock, times(1)).onDividerMoveStart(any(), any())
whenever(dividerMoveCallbackMock.onDividerMove(any())).thenReturn(true)
val motionEvent =
@@ -79,7 +79,7 @@
val upMotionEvent =
getMotionEvent(downTime, MotionEvent.ACTION_UP, x.toFloat(), y.toFloat())
tilingDividerView.handleMotionEvent(viewMock, upMotionEvent)
- verify(dividerMoveCallbackMock, times(1)).onDividerMovedEnd(any())
+ verify(dividerMoveCallbackMock, times(1)).onDividerMovedEnd(any(), any())
}
@Test
@@ -92,12 +92,12 @@
val downMotionEvent =
getMotionEvent(downTime, MotionEvent.ACTION_DOWN, x.toFloat(), y.toFloat())
tilingDividerView.handleMotionEvent(viewMock, downMotionEvent)
- verify(dividerMoveCallbackMock, times(1)).onDividerMoveStart(any())
+ verify(dividerMoveCallbackMock, times(1)).onDividerMoveStart(any(), any())
val upMotionEvent =
getMotionEvent(downTime, MotionEvent.ACTION_UP, x.toFloat(), y.toFloat())
tilingDividerView.handleMotionEvent(viewMock, upMotionEvent)
- verify(dividerMoveCallbackMock, never()).onDividerMovedEnd(any())
+ verify(dividerMoveCallbackMock, never()).onDividerMovedEnd(any(), any())
}
private fun getMotionEvent(eventTime: Long, action: Int, x: Float, y: Float): MotionEvent {
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index b71abdc..fcb7efc 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -580,6 +580,7 @@
"utils/Color.cpp",
"utils/LinearAllocator.cpp",
"utils/StringUtils.cpp",
+ "utils/StatsUtils.cpp",
"utils/TypefaceUtils.cpp",
"utils/VectorDrawableUtils.cpp",
"AnimationContext.cpp",
diff --git a/libs/hwui/hwui/ImageDecoder.cpp b/libs/hwui/hwui/ImageDecoder.cpp
index e074a27..a9a5db8 100644
--- a/libs/hwui/hwui/ImageDecoder.cpp
+++ b/libs/hwui/hwui/ImageDecoder.cpp
@@ -27,8 +27,8 @@
#include <SkColorSpace.h>
#include <SkColorType.h>
#include <SkEncodedOrigin.h>
-#include <SkImageInfo.h>
#include <SkGainmapInfo.h>
+#include <SkImageInfo.h>
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkPngChunkReader.h>
@@ -43,6 +43,8 @@
#include <memory>
+#include "modules/skcms/src/skcms_public.h"
+
using namespace android;
sk_sp<SkColorSpace> ImageDecoder::getDefaultColorSpace() const {
diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp
index 9cd6e25..e5fb755 100644
--- a/libs/hwui/hwui/MinikinUtils.cpp
+++ b/libs/hwui/hwui/MinikinUtils.cpp
@@ -49,6 +49,7 @@
minikinPaint.fontStyle = resolvedFace->fStyle;
minikinPaint.fontFeatureSettings = paint->getFontFeatureSettings();
minikinPaint.fontVariationSettings = paint->getFontVariationOverride();
+ minikinPaint.verticalText = paint->isVerticalText();
const std::optional<minikin::FamilyVariant>& familyVariant = paint->getFamilyVariant();
if (familyVariant.has_value()) {
diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h
index 7eb849f..594ea31 100644
--- a/libs/hwui/hwui/Paint.h
+++ b/libs/hwui/hwui/Paint.h
@@ -158,6 +158,7 @@
SkSamplingOptions sampling() const {
return SkSamplingOptions(this->filterMode());
}
+ bool isVerticalText() const { return mVerticalText; }
void setVariationOverride(minikin::VariationSettings&& varSettings) {
mFontVariationOverride = std::move(varSettings);
@@ -202,6 +203,7 @@
bool mUnderline = false;
bool mDevKern = false;
minikin::RunFlag mRunFlag = minikin::RunFlag::NONE;
+ bool mVerticalText = false;
};
} // namespace android
diff --git a/libs/hwui/hwui/PaintImpl.cpp b/libs/hwui/hwui/PaintImpl.cpp
index 6dfcedc..fa5325d 100644
--- a/libs/hwui/hwui/PaintImpl.cpp
+++ b/libs/hwui/hwui/PaintImpl.cpp
@@ -49,7 +49,8 @@
, mStrikeThru(paint.mStrikeThru)
, mUnderline(paint.mUnderline)
, mDevKern(paint.mDevKern)
- , mRunFlag(paint.mRunFlag) {}
+ , mRunFlag(paint.mRunFlag)
+ , mVerticalText(paint.mVerticalText) {}
Paint::~Paint() {}
@@ -71,6 +72,7 @@
mUnderline = other.mUnderline;
mDevKern = other.mDevKern;
mRunFlag = other.mRunFlag;
+ mVerticalText = other.mVerticalText;
return *this;
}
@@ -83,7 +85,8 @@
a.mFamilyVariant == b.mFamilyVariant && a.mHyphenEdit == b.mHyphenEdit &&
a.mTypeface == b.mTypeface && a.mAlign == b.mAlign &&
a.mFilterBitmap == b.mFilterBitmap && a.mStrikeThru == b.mStrikeThru &&
- a.mUnderline == b.mUnderline && a.mDevKern == b.mDevKern && a.mRunFlag == b.mRunFlag;
+ a.mUnderline == b.mUnderline && a.mDevKern == b.mDevKern && a.mRunFlag == b.mRunFlag &&
+ a.mVerticalText == b.mVerticalText;
}
void Paint::reset() {
@@ -97,6 +100,7 @@
mStrikeThru = false;
mUnderline = false;
mDevKern = false;
+ mVerticalText = false;
mRunFlag = minikin::RunFlag::NONE;
}
@@ -135,6 +139,7 @@
// flags related to minikin::Paint
static const uint32_t sUnderlineFlag = 0x08;
static const uint32_t sStrikeThruFlag = 0x10;
+static const uint32_t sVerticalTextFlag = 0x1000;
static const uint32_t sTextRunLeftEdge = 0x2000;
static const uint32_t sTextRunRightEdge = 0x4000;
// flags no longer supported on native side (but mirrored for compatibility)
@@ -190,6 +195,7 @@
flags |= -(int)mUnderline & sUnderlineFlag;
flags |= -(int)mDevKern & sDevKernFlag;
flags |= -(int)mFilterBitmap & sFilterBitmapFlag;
+ flags |= -(int)mVerticalText & sVerticalTextFlag;
if (mRunFlag & minikin::RunFlag::LEFT_EDGE) {
flags |= sTextRunLeftEdge;
}
@@ -206,6 +212,7 @@
mUnderline = (flags & sUnderlineFlag) != 0;
mDevKern = (flags & sDevKernFlag) != 0;
mFilterBitmap = (flags & sFilterBitmapFlag) != 0;
+ mVerticalText = (flags & sVerticalTextFlag) != 0;
std::underlying_type<minikin::RunFlag>::type rawFlag = minikin::RunFlag::NONE;
if (flags & sTextRunLeftEdge) {
diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp
index 49a7f73..8b43f1d 100644
--- a/libs/hwui/jni/BitmapFactory.cpp
+++ b/libs/hwui/jni/BitmapFactory.cpp
@@ -10,6 +10,7 @@
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
+#include <utils/StatsUtils.h>
#include <memory>
@@ -630,6 +631,7 @@
}
bitmap::reinitBitmap(env, javaBitmap, outputBitmap.info(), isPremultiplied);
outputBitmap.notifyPixelsChanged();
+ uirenderer::logBitmapDecode(*reuseBitmap);
// If a java bitmap was passed in for reuse, pass it back
return javaBitmap;
}
@@ -650,6 +652,7 @@
}
}
+ uirenderer::logBitmapDecode(*hardwareBitmap);
return bitmap::createBitmap(env, hardwareBitmap.release(), bitmapCreateFlags,
ninePatchChunk, ninePatchInsets, -1);
}
@@ -659,6 +662,7 @@
heapBitmap->setGainmap(std::move(gainmap));
}
+ uirenderer::logBitmapDecode(*heapBitmap);
// now create the java bitmap
return bitmap::createBitmap(env, heapBitmap, bitmapCreateFlags, ninePatchChunk, ninePatchInsets,
-1);
diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp
index f7e8e07..5ffd5b9 100644
--- a/libs/hwui/jni/BitmapRegionDecoder.cpp
+++ b/libs/hwui/jni/BitmapRegionDecoder.cpp
@@ -19,6 +19,7 @@
#include <HardwareBitmapUploader.h>
#include <androidfw/Asset.h>
#include <sys/stat.h>
+#include <utils/StatsUtils.h>
#include <memory>
@@ -376,6 +377,7 @@
recycledBitmap->setGainmap(std::move(gainmap));
}
bitmap::reinitBitmap(env, javaBitmap, recycledBitmap->info(), !requireUnpremul);
+ uirenderer::logBitmapDecode(*recycledBitmap);
return javaBitmap;
}
@@ -392,12 +394,14 @@
hardwareBitmap->setGainmap(std::move(gm));
}
}
+ uirenderer::logBitmapDecode(*hardwareBitmap);
return bitmap::createBitmap(env, hardwareBitmap.release(), bitmapCreateFlags);
}
Bitmap* heapBitmap = heapAlloc.getStorageObjAndReset();
if (hasGainmap && heapBitmap != nullptr) {
heapBitmap->setGainmap(std::move(gainmap));
}
+ uirenderer::logBitmapDecode(*heapBitmap);
return android::bitmap::createBitmap(env, heapBitmap, bitmapCreateFlags);
}
diff --git a/libs/hwui/jni/ImageDecoder.cpp b/libs/hwui/jni/ImageDecoder.cpp
index aebc4db..90fd3d8 100644
--- a/libs/hwui/jni/ImageDecoder.cpp
+++ b/libs/hwui/jni/ImageDecoder.cpp
@@ -37,6 +37,7 @@
#include <hwui/Bitmap.h>
#include <hwui/ImageDecoder.h>
#include <sys/stat.h>
+#include <utils/StatsUtils.h>
#include "Bitmap.h"
#include "BitmapFactory.h"
@@ -485,6 +486,7 @@
hwBitmap->setGainmap(std::move(gm));
}
}
+ uirenderer::logBitmapDecode(*hwBitmap);
return bitmap::createBitmap(env, hwBitmap.release(), bitmapCreateFlags,
ninePatchChunk, ninePatchInsets);
}
@@ -498,6 +500,8 @@
nativeBitmap->setImmutable();
}
+
+ uirenderer::logBitmapDecode(*nativeBitmap);
return bitmap::createBitmap(env, nativeBitmap.release(), bitmapCreateFlags, ninePatchChunk,
ninePatchInsets);
}
diff --git a/libs/hwui/libhwui.map.txt b/libs/hwui/libhwui.map.txt
index 2414299..b559194 100644
--- a/libs/hwui/libhwui.map.txt
+++ b/libs/hwui/libhwui.map.txt
@@ -67,6 +67,7 @@
SkFILEStream::SkFILEStream*;
SkImageInfo::*;
SkMemoryStream::SkMemoryStream*;
+ android::uirenderer::logBitmapDecode*;
};
local:
*;
diff --git a/libs/hwui/utils/StatsUtils.cpp b/libs/hwui/utils/StatsUtils.cpp
new file mode 100644
index 0000000..5c4027e
--- /dev/null
+++ b/libs/hwui/utils/StatsUtils.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef __ANDROID__
+#include <dlfcn.h>
+#include <log/log.h>
+#include <statslog_hwui.h>
+#include <statssocket_lazy.h>
+#include <utils/Errors.h>
+
+#include <mutex>
+#endif
+
+#include <unistd.h>
+
+#include "StatsUtils.h"
+
+namespace android {
+namespace uirenderer {
+
+#ifdef __ANDROID__
+
+namespace {
+
+int32_t toStatsColorSpaceTransfer(skcms_TFType transferType) {
+ switch (transferType) {
+ case skcms_TFType_sRGBish:
+ return stats::IMAGE_DECODED__COLOR_SPACE_TRANSFER__COLOR_SPACE_TRANSFER_SRGBISH;
+ case skcms_TFType_PQish:
+ return stats::IMAGE_DECODED__COLOR_SPACE_TRANSFER__COLOR_SPACE_TRANSFER_PQISH;
+ case skcms_TFType_HLGish:
+ return stats::IMAGE_DECODED__COLOR_SPACE_TRANSFER__COLOR_SPACE_TRANSFER_HLGISH;
+ default:
+ return stats::IMAGE_DECODED__COLOR_SPACE_TRANSFER__COLOR_SPACE_TRANSFER_UNKNOWN;
+ }
+}
+
+int32_t toStatsBitmapFormat(SkColorType type) {
+ switch (type) {
+ case kAlpha_8_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_A_8;
+ case kRGB_565_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_RGB_565;
+ case kN32_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_ARGB_8888;
+ case kRGBA_F16_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_RGBA_F16;
+ case kRGBA_1010102_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_RGBA_1010102;
+ default:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_UNKNOWN;
+ }
+}
+
+} // namespace
+
+#endif
+
+void logBitmapDecode(const SkImageInfo& info, bool hasGainmap) {
+#ifdef __ANDROID__
+
+ if (!statssocket::lazy::IsAvailable()) {
+ std::once_flag once;
+ std::call_once(once, []() { ALOGD("libstatssocket not available, dropping stats"); });
+ return;
+ }
+
+ skcms_TFType tfnType = skcms_TFType_Invalid;
+
+ if (info.colorSpace()) {
+ skcms_TransferFunction tfn;
+ info.colorSpace()->transferFn(&tfn);
+ tfnType = skcms_TransferFunction_getType(&tfn);
+ }
+
+ auto status =
+ stats::stats_write(uirenderer::stats::IMAGE_DECODED, static_cast<int32_t>(getuid()),
+ uirenderer::toStatsColorSpaceTransfer(tfnType), hasGainmap,
+ uirenderer::toStatsBitmapFormat(info.colorType()));
+ ALOGW_IF(status != OK, "Image decoding logging dropped!");
+#endif
+}
+
+void logBitmapDecode(const Bitmap& bitmap) {
+ logBitmapDecode(bitmap.info(), bitmap.hasGainmap());
+}
+
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/utils/StatsUtils.h b/libs/hwui/utils/StatsUtils.h
new file mode 100644
index 0000000..0c247014
--- /dev/null
+++ b/libs/hwui/utils/StatsUtils.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <SkBitmap.h>
+#include <SkColorSpace.h>
+#include <SkColorType.h>
+#include <cutils/compiler.h>
+#include <hwui/Bitmap.h>
+
+namespace android {
+namespace uirenderer {
+
+ANDROID_API void logBitmapDecode(const SkImageInfo& info, bool hasGainmap);
+
+ANDROID_API void logBitmapDecode(const Bitmap& bitmap);
+
+} // namespace uirenderer
+} // namespace android
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 55c8ed5..530d48d 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -40,6 +40,8 @@
import android.os.Trace;
import android.view.Surface;
+import com.android.internal.camera.flags.Flags;
+
import dalvik.system.VMRuntime;
import java.io.IOException;
@@ -1208,6 +1210,11 @@
default:
width = nativeGetWidth();
}
+ if (Flags.cameraHeifGainmap()) {
+ if (getFormat() == ImageFormat.HEIC_ULTRAHDR){
+ width = ImageReader.this.getWidth();
+ }
+ }
return width;
}
@@ -1227,6 +1234,11 @@
default:
height = nativeGetHeight();
}
+ if (Flags.cameraHeifGainmap()) {
+ if (getFormat() == ImageFormat.HEIC_ULTRAHDR){
+ height = ImageReader.this.getHeight();
+ }
+ }
return height;
}
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index f4caad7..c767806 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -23,6 +23,8 @@
import android.util.Log;
import android.util.Size;
+import com.android.internal.camera.flags.Flags;
+
import libcore.io.Memory;
import java.nio.ByteBuffer;
@@ -44,6 +46,11 @@
* are used.
*/
public static int getNumPlanesForFormat(int format) {
+ if (Flags.cameraHeifGainmap()) {
+ if (format == ImageFormat.HEIC_ULTRAHDR) {
+ return 1;
+ }
+ }
switch (format) {
case ImageFormat.YV12:
case ImageFormat.YUV_420_888:
@@ -229,6 +236,11 @@
public static int getEstimatedNativeAllocBytes(int width, int height, int format,
int numImages) {
double estimatedBytePerPixel;
+ if (Flags.cameraHeifGainmap()) {
+ if (format == ImageFormat.HEIC_ULTRAHDR) {
+ estimatedBytePerPixel = 0.3;
+ }
+ }
switch (format) {
// 10x compression from RGB_888
case ImageFormat.JPEG:
@@ -283,6 +295,11 @@
}
private static Size getEffectivePlaneSizeForImage(Image image, int planeIdx) {
+ if (Flags.cameraHeifGainmap()) {
+ if (image.getFormat() == ImageFormat.HEIC_ULTRAHDR){
+ return new Size(image.getWidth(), image.getHeight());
+ }
+ }
switch (image.getFormat()) {
case ImageFormat.YCBCR_P010:
case ImageFormat.YV12:
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 816729d..0902278 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -22,6 +22,7 @@
import static com.android.media.flags.Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER;
import static com.android.media.flags.Flags.FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES;
import static com.android.media.flags.Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES;
+import static com.android.media.flags.Flags.FLAG_ENABLE_NEW_WIRED_MEDIA_ROUTE_2_INFO_TYPES;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
@@ -150,6 +151,9 @@
TYPE_HDMI,
TYPE_HDMI_ARC,
TYPE_HDMI_EARC,
+ TYPE_LINE_DIGITAL,
+ TYPE_LINE_ANALOG,
+ TYPE_AUX_LINE,
TYPE_USB_DEVICE,
TYPE_USB_ACCESSORY,
TYPE_DOCK,
@@ -231,6 +235,24 @@
public static final int TYPE_HDMI_EARC = AudioDeviceInfo.TYPE_HDMI_EARC;
/**
+ * Indicates the route is a digital line connection (for example S/PDIF).
+ */
+ @FlaggedApi(FLAG_ENABLE_NEW_WIRED_MEDIA_ROUTE_2_INFO_TYPES)
+ public static final int TYPE_LINE_DIGITAL = AudioDeviceInfo.TYPE_LINE_DIGITAL;
+
+ /**
+ * Indicates the route is an analog line-level connection.
+ */
+ @FlaggedApi(FLAG_ENABLE_NEW_WIRED_MEDIA_ROUTE_2_INFO_TYPES)
+ public static final int TYPE_LINE_ANALOG = AudioDeviceInfo.TYPE_LINE_ANALOG;
+
+ /**
+ * Indicates the route is using the auxiliary line-level connectors.
+ */
+ @FlaggedApi(FLAG_ENABLE_NEW_WIRED_MEDIA_ROUTE_2_INFO_TYPES)
+ public static final int TYPE_AUX_LINE = AudioDeviceInfo.TYPE_AUX_LINE;
+
+ /**
* Indicates the route is a USB audio device.
*
* @see #getType
@@ -839,6 +861,7 @@
public boolean isSystemRouteType() {
return switch (mType) {
case TYPE_BUILTIN_SPEAKER,
+ TYPE_AUX_LINE,
TYPE_BLUETOOTH_A2DP,
TYPE_DOCK,
TYPE_BLE_HEADSET,
@@ -846,6 +869,8 @@
TYPE_HDMI,
TYPE_HDMI_ARC,
TYPE_HDMI_EARC,
+ TYPE_LINE_DIGITAL,
+ TYPE_LINE_ANALOG,
TYPE_USB_ACCESSORY,
TYPE_USB_DEVICE,
TYPE_USB_HEADSET,
@@ -1074,6 +1099,12 @@
return "HDMI_ARC";
case TYPE_HDMI_EARC:
return "HDMI_EARC";
+ case TYPE_LINE_DIGITAL:
+ return "LINE_DIGITAL";
+ case TYPE_LINE_ANALOG:
+ return "LINE_ANALOG";
+ case TYPE_AUX_LINE:
+ return "AUX_LINE";
case TYPE_DOCK:
return "DOCK";
case TYPE_USB_DEVICE:
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index 1ef98f2..90b4aba 100644
--- a/media/java/android/media/flags/media_better_together.aconfig
+++ b/media/java/android/media/flags/media_better_together.aconfig
@@ -47,6 +47,14 @@
}
flag {
+ name: "enable_new_wired_media_route_2_info_types"
+ is_exported: true
+ namespace: "media_tv"
+ description: "Enables the following type constant in MediaRoute2Info: LINE_ANALOG, LINE_DIGITAL, AUX_LINE"
+ bug: "301713440"
+}
+
+flag {
name: "enable_privileged_routing_for_media_routing_control"
is_exported: true
namespace: "media_solutions"
diff --git a/media/java/android/media/quality/MediaQualityContract.java b/media/java/android/media/quality/MediaQualityContract.java
index 5cbc81d..472d798 100644
--- a/media/java/android/media/quality/MediaQualityContract.java
+++ b/media/java/android/media/quality/MediaQualityContract.java
@@ -21,11 +21,16 @@
import android.media.tv.flags.Flags;
/**
+ * The contract between the media quality service and applications. Contains definitions for the
+ * commonly used parameter names.
* @hide
*/
@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
public class MediaQualityContract {
+ /**
+ * @hide
+ */
public interface BaseParameters {
String PARAMETER_ID = "_id";
String PARAMETER_NAME = "_name";
@@ -33,13 +38,50 @@
String PARAMETER_INPUT_ID = "_input_id";
}
- public static final class PictureQuality implements BaseParameters {
+
+ /**
+ * Parameters picture quality.
+ * @hide
+ */
+ public static final class PictureQuality {
+ /**
+ * The brightness.
+ *
+ * <p>Type: INTEGER
+ */
public static final String PARAMETER_BRIGHTNESS = "brightness";
+
+ /**
+ * The contrast.
+ *
+ * <p>The ratio between the luminance of the brightest white and the darkest black.
+ * <p>Type: INTEGER
+ */
public static final String PARAMETER_CONTRAST = "contrast";
+
+ /**
+ * The sharpness.
+ *
+ * <p>Sharpness indicates the clarity of detail.
+ * <p>Type: INTEGER
+ */
public static final String PARAMETER_SHARPNESS = "sharpness";
+
+ /**
+ * The saturation.
+ *
+ * <p>Saturation indicates the intensity of the color.
+ * <p>Type: INTEGER
+ */
public static final String PARAMETER_SATURATION = "saturation";
+
+ private PictureQuality() {
+ }
}
+ /**
+ * @hide
+ */
public static final class SoundQuality implements BaseParameters {
public static final String PARAMETER_BALANCE = "balance";
public static final String PARAMETER_BASS = "bass";
diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java
index 1237d67..38a2025 100644
--- a/media/java/android/media/quality/MediaQualityManager.java
+++ b/media/java/android/media/quality/MediaQualityManager.java
@@ -34,7 +34,8 @@
import java.util.concurrent.Executor;
/**
- * Expose TV setting APIs for the application to use
+ * Central system API to the overall media quality, which arbitrates interaction between
+ * applications and media quality service.
* @hide
*/
@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
@@ -177,6 +178,7 @@
* Gets picture profile by given profile ID.
* @return the corresponding picture profile if available; {@code null} if the ID doesn't
* exist or the profile is not accessible to the caller.
+ * @hide
*/
public PictureProfile getPictureProfileById(long profileId) {
try {
@@ -187,7 +189,10 @@
}
- /** @SystemApi gets profiles that available to the given package */
+ /**
+ * @SystemApi gets profiles that available to the given package
+ * @hide
+ */
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public List<PictureProfile> getPictureProfilesByPackage(String packageName) {
try {
@@ -197,7 +202,10 @@
}
}
- /** Gets profiles that available to the caller package */
+ /**
+ * Gets profiles that available to the caller.
+ */
+ @NonNull
public List<PictureProfile> getAvailablePictureProfiles() {
try {
return mService.getAvailablePictureProfiles();
@@ -206,7 +214,10 @@
}
}
- /** @SystemApi all stored picture profiles of all packages */
+ /**
+ * @SystemApi all stored picture profiles of all packages
+ * @hide
+ */
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public List<PictureProfile> getAllPictureProfiles() {
try {
@@ -221,6 +232,7 @@
* Creates a picture profile and store it in the system.
*
* @return the stored profile with an assigned profile ID.
+ * @hide
*/
public PictureProfile createPictureProfile(PictureProfile pp) {
try {
@@ -233,6 +245,7 @@
/**
* Updates an existing picture profile and store it in the system.
+ * @hide
*/
public void updatePictureProfile(long profileId, PictureProfile pp) {
try {
@@ -245,6 +258,7 @@
/**
* Removes a picture profile from the system.
+ * @hide
*/
public void removePictureProfile(long profileId) {
try {
@@ -291,6 +305,7 @@
* Gets sound profile by given profile ID.
* @return the corresponding sound profile if available; {@code null} if the ID doesn't
* exist or the profile is not accessible to the caller.
+ * @hide
*/
public SoundProfile getSoundProfileById(long profileId) {
try {
@@ -301,7 +316,10 @@
}
- /** @SystemApi gets profiles that available to the given package */
+ /**
+ * @SystemApi gets profiles that available to the given package
+ * @hide
+ */
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public List<SoundProfile> getSoundProfilesByPackage(String packageName) {
try {
@@ -311,7 +329,10 @@
}
}
- /** Gets profiles that available to the caller package */
+ /**
+ * Gets profiles that available to the caller package
+ * @hide
+ */
public List<SoundProfile> getAvailableSoundProfiles() {
try {
return mService.getAvailableSoundProfiles();
@@ -320,7 +341,10 @@
}
}
- /** @SystemApi all stored sound profiles of all packages */
+ /**
+ * @SystemApi all stored sound profiles of all packages
+ * @hide
+ */
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public List<SoundProfile> getAllSoundProfiles() {
try {
@@ -335,6 +359,7 @@
* Creates a sound profile and store it in the system.
*
* @return the stored profile with an assigned profile ID.
+ * @hide
*/
public SoundProfile createSoundProfile(SoundProfile sp) {
try {
@@ -347,6 +372,7 @@
/**
* Updates an existing sound profile and store it in the system.
+ * @hide
*/
public void updateSoundProfile(long profileId, SoundProfile sp) {
try {
@@ -359,6 +385,7 @@
/**
* Removes a sound profile from the system.
+ * @hide
*/
public void removeSoundProfile(long profileId) {
try {
@@ -370,6 +397,7 @@
/**
* Gets capability information of the given parameters.
+ * @hide
*/
public List<ParamCapability> getParamCapabilities(List<String> names) {
try {
@@ -396,6 +424,7 @@
* different use cases.
*
* @param enabled {@code true} to enable, {@code false} to disable.
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setAutoPictureQualityEnabled(boolean enabled) {
@@ -408,6 +437,7 @@
/**
* Returns {@code true} if auto picture quality is enabled; {@code false} otherwise.
+ * @hide
*/
public boolean isAutoPictureQualityEnabled() {
try {
@@ -422,6 +452,7 @@
* <p>Super resolution is a feature to improve resolution.
*
* @param enabled {@code true} to enable, {@code false} to disable.
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setSuperResolutionEnabled(boolean enabled) {
@@ -434,6 +465,7 @@
/**
* Returns {@code true} if super resolution is enabled; {@code false} otherwise.
+ * @hide
*/
public boolean isSuperResolutionEnabled() {
try {
@@ -449,6 +481,7 @@
* different use cases.
*
* @param enabled {@code true} to enable, {@code false} to disable.
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public void setAutoSoundQualityEnabled(boolean enabled) {
@@ -461,6 +494,7 @@
/**
* Returns {@code true} if auto sound quality is enabled; {@code false} otherwise.
+ * @hide
*/
public boolean isAutoSoundQualityEnabled() {
try {
@@ -507,6 +541,7 @@
* Set the ambient backlight settings.
*
* @param settings The settings to use for the backlight detector.
+ * @hide
*/
public void setAmbientBacklightSettings(
@NonNull AmbientBacklightSettings settings) {
@@ -522,6 +557,7 @@
* Enables or disables the ambient backlight detection.
*
* @param enabled {@code true} to enable, {@code false} to disable.
+ * @hide
*/
public void setAmbientBacklightEnabled(boolean enabled) {
try {
@@ -700,6 +736,7 @@
public abstract static class AmbientBacklightCallback {
/**
* Called when new ambient backlight event is emitted.
+ * @hide
*/
public void onAmbientBacklightEvent(AmbientBacklightEvent event) {
}
diff --git a/media/java/android/media/quality/PictureProfile.java b/media/java/android/media/quality/PictureProfile.java
index 36c49d8..8fb5712 100644
--- a/media/java/android/media/quality/PictureProfile.java
+++ b/media/java/android/media/quality/PictureProfile.java
@@ -17,6 +17,8 @@
package android.media.quality;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.media.tv.TvInputInfo;
import android.media.tv.flags.Flags;
import android.os.Bundle;
import android.os.Parcel;
@@ -24,30 +26,55 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresPermission;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
+ * Profile for picture quality.
* @hide
*/
-
@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
-public class PictureProfile implements Parcelable {
+public final class PictureProfile implements Parcelable {
@Nullable
- private Long mId;
+ private String mId;
+ private final int mType;
@NonNull
private final String mName;
@Nullable
private final String mInputId;
- @Nullable
+ @NonNull
private final String mPackageName;
@NonNull
private final Bundle mParams;
- protected PictureProfile(Parcel in) {
- if (in.readByte() == 0) {
- mId = null;
- } else {
- mId = in.readLong();
- }
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = false, prefix = "TYPE_", value = {
+ TYPE_SYSTEM,
+ TYPE_APPLICATION})
+ public @interface ProfileType {}
+
+ /**
+ * System profile type.
+ *
+ * <p>A profile of system type is managed by the system, and readable to the package define in
+ * {@link #getPackageName()}.
+ */
+ public static final int TYPE_SYSTEM = 1;
+ /**
+ * Application profile type.
+ *
+ * <p>A profile of application type is managed by the package define in
+ * {@link #getPackageName()}.
+ */
+ public static final int TYPE_APPLICATION = 2;
+
+
+ private PictureProfile(@NonNull Parcel in) {
+ mId = in.readString();
+ mType = in.readInt();
mName = in.readString();
mInputId = in.readString();
mPackageName = in.readString();
@@ -55,13 +82,9 @@
}
@Override
- public void writeToParcel(Parcel dest, int flags) {
- if (mId == null) {
- dest.writeByte((byte) 0);
- } else {
- dest.writeByte((byte) 1);
- dest.writeLong(mId);
- }
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mId);
+ dest.writeInt(mType);
dest.writeString(mName);
dest.writeString(mInputId);
dest.writeString(mPackageName);
@@ -73,6 +96,7 @@
return 0;
}
+ @NonNull
public static final Creator<PictureProfile> CREATOR = new Creator<PictureProfile>() {
@Override
public PictureProfile createFromParcel(Parcel in) {
@@ -92,95 +116,166 @@
* @hide
*/
public PictureProfile(
- @Nullable Long id,
+ @Nullable String id,
+ int type,
@NonNull String name,
@Nullable String inputId,
- @Nullable String packageName,
+ @NonNull String packageName,
@NonNull Bundle params) {
this.mId = id;
+ this.mType = type;
this.mName = name;
- com.android.internal.util.AnnotationValidations.validate(NonNull.class, null, name);
this.mInputId = inputId;
this.mPackageName = packageName;
this.mParams = params;
}
+ /**
+ * Gets profile ID.
+ *
+ * <p>A profile ID is a globally unique ID generated and assigned by the system. For profile
+ * objects retrieved from system (e.g {@link MediaQualityManager#getAvailablePictureProfiles()})
+ * this profile ID is non-null; For profiles built locally with {@link Builder}, it's
+ * {@code null}.
+ *
+ * @return the unique profile ID; {@code null} if the profile is built locally with
+ * {@link Builder}.
+ */
@Nullable
- public Long getProfileId() {
+ public String getProfileId() {
return mId;
}
+ /**
+ * Only used by system to assign the ID.
+ * @hide
+ */
+ public void setProfileId(String id) {
+ mId = id;
+ }
+
+ /**
+ * Gets profile type.
+ */
+ @ProfileType
+ public int getProfileType() {
+ return mType;
+ }
+
+ /**
+ * Gets the profile name.
+ */
@NonNull
public String getName() {
return mName;
}
+ /**
+ * Gets the input ID if the profile is for a TV input.
+ *
+ * @return the corresponding TV input ID; {@code null} if the profile is not associated with a
+ * TV input.
+ *
+ * @see TvInputInfo#getId()
+ */
@Nullable
public String getInputId() {
return mInputId;
}
+ /**
+ * Gets the package name of this profile.
+ *
+ * <p>The package name defines the user of a profile. Only this specific package and system app
+ * can access to this profile.
+ *
+ * @return the package name; {@code null} if the profile is built locally using
+ * {@link Builder} and the package is not set.
+ */
@Nullable
public String getPackageName() {
return mPackageName;
}
+
+ /**
+ * Gets the parameters of this profile.
+ *
+ * <p>The keys of commonly used parameters can be found in
+ * {@link MediaQualityContract.PictureQuality}.
+ */
@NonNull
public Bundle getParameters() {
return new Bundle(mParams);
}
/**
- * A builder for {@link PictureProfile}
+ * A builder for {@link PictureProfile}.
+ * @hide
*/
- public static class Builder {
+ public static final class Builder {
@Nullable
- private Long mId;
+ private String mId;
+ private int mType = TYPE_APPLICATION;
@NonNull
private String mName;
@Nullable
private String mInputId;
- @Nullable
+ @NonNull
private String mPackageName;
@NonNull
private Bundle mParams;
/**
* Creates a new Builder.
- *
- * @hide
*/
public Builder(@NonNull String name) {
mName = name;
- com.android.internal.util.AnnotationValidations.validate(NonNull.class, null, name);
}
/**
- * Copy constructor.
- *
- * @hide
+ * Copy constructor of builder.
*/
public Builder(@NonNull PictureProfile p) {
mId = null; // ID needs to be reset
+ mType = p.getProfileType();
mName = p.getName();
mPackageName = p.getPackageName();
mInputId = p.getInputId();
+ mParams = p.getParameters();
}
/* @hide using by MediaQualityService */
/**
- * Sets profile ID.
- * @hide using by MediaQualityService
+ * Only used by system to assign the ID.
+ * @hide
*/
@NonNull
- public Builder setProfileId(@Nullable Long id) {
+ public Builder setProfileId(@Nullable String id) {
mId = id;
return this;
}
/**
- * Sets input ID.
+ * Sets profile type.
+ *
+ * @hide @SystemApi
*/
+ @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
+ @NonNull
+ public Builder setProfileType(@ProfileType int value) {
+ mType = value;
+ return this;
+ }
+
+ /**
+ * Sets input ID.
+ *
+ * @see PictureProfile#getInputId()
+ *
+ * @hide @SystemApi
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
@NonNull
public Builder setInputId(@NonNull String value) {
mInputId = value;
@@ -189,7 +284,12 @@
/**
* Sets package name of the profile.
+ *
+ * @see PictureProfile#getPackageName()
+ *
+ * @hide @SystemApi
*/
+ @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
@NonNull
public Builder setPackageName(@NonNull String value) {
mPackageName = value;
@@ -198,6 +298,8 @@
/**
* Sets profile parameters.
+ *
+ * @see PictureProfile#getParameters()
*/
@NonNull
public Builder setParameters(@NonNull Bundle params) {
@@ -213,6 +315,7 @@
PictureProfile o = new PictureProfile(
mId,
+ mType,
mName,
mInputId,
mPackageName,
diff --git a/media/java/android/media/tv/TvInputServiceExtensionManager.java b/media/java/android/media/tv/TvInputServiceExtensionManager.java
index 0e98488..c514f6e 100644
--- a/media/java/android/media/tv/TvInputServiceExtensionManager.java
+++ b/media/java/android/media/tv/TvInputServiceExtensionManager.java
@@ -17,13 +17,17 @@
package android.media.tv;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.StringDef;
import android.media.tv.flags.Flags;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -33,10 +37,14 @@
/**
+ * This class provides a list of available standardized TvInputService extension interface names
+ * and a container storing IBinder objects that implement these interfaces created by SoC/OEMs.
+ * It also provides an API for SoC/OEMs to register implemented IBinder objects.
+ *
* @hide
*/
@FlaggedApi(Flags.FLAG_TIF_EXTENSION_STANDARDIZATION)
-public class TvInputServiceExtensionManager {
+public final class TvInputServiceExtensionManager {
private static final String TAG = "TvInputServiceExtensionManager";
private static final String SCAN_PACKAGE = "android.media.tv.extension.scan.";
private static final String OAD_PACKAGE = "android.media.tv.extension.oad.";
@@ -54,404 +62,608 @@
private static final String ANALOG_PACKAGE = "android.media.tv.extension.analog.";
private static final String TUNE_PACKAGE = "android.media.tv.extension.tune.";
- /** Register binder returns success when it abides standardized interface structure */
- public static final int REGISTER_SUCCESS = 0;
- /** Register binder returns fail when the extension name is not in the standardization list */
- public static final int REGISTER_FAIL_NAME_NOT_STANDARDIZED = 1;
- /** Register binder returns fail when the IBinder does not implement standardized interface */
- public static final int REGISTER_FAIL_IMPLEMENTATION_NOT_STANDARDIZED = 2;
- /** Register binder returns fail when remote server not available */
- public static final int REGISTER_FAIL_REMOTE_EXCEPTION = 3;
+ /** @hide */
+ @IntDef(prefix = {"REGISTER_"}, value = {
+ REGISTER_SUCCESS,
+ REGISTER_FAIL_NAME_NOT_STANDARDIZED,
+ REGISTER_FAIL_IMPLEMENTATION_NOT_STANDARDIZED,
+ REGISTER_FAIL_REMOTE_EXCEPTION
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RegisterResult {}
/**
+ * Registering binder returns success when it abides standardized interface structure
+ */
+ public static final int REGISTER_SUCCESS = 0;
+ /**
+ * Registering binder returns failure when the extension name is not in the standardization
+ * list
+ */
+ public static final int REGISTER_FAIL_NAME_NOT_STANDARDIZED = 1;
+ /**
+ * Registering binder returns failure when the IBinder does not implement standardized interface
+ */
+ public static final int REGISTER_FAIL_IMPLEMENTATION_NOT_STANDARDIZED = 2;
+ /**
+ * Registering binder returns failure when remote server is not available
+ */
+ public static final int REGISTER_FAIL_REMOTE_EXCEPTION = 3;
+
+ /** @hide */
+ @StringDef({
+ ISCAN_INTERFACE,
+ ISCAN_SESSION,
+ ISCAN_LISTENER,
+ IHDPLUS_INFO,
+ IOPERATOR_DETECTION,
+ IOPERATOR_DETECTION_LISTENER,
+ IREGION_CHANNEL_LIST,
+ IREGION_CHANNEL_LIST_LISTENER,
+ ITARGET_REGION,
+ ITARGET_REGION_LISTENER,
+ ILCN_CONFLICT,
+ ILCN_CONFLICT_LISTENER,
+ ILCNV2_CHANNEL_LIST,
+ ILCNV2_CHANNEL_LIST_LISTENER,
+ IFAVORITE_NETWORK,
+ IFAVORITE_NETWORK_LISTENER,
+ ITKGS_INFO,
+ ITKGS_INFO_LISTENER,
+ ISCAN_SAT_SEARCH,
+ IOAD_UPDATE_INTERFACE,
+ ICAM_APP_INFO_SERVICE,
+ ICAM_APP_INFO_LISTENER,
+ ICAM_MONITORING_SERVICE,
+ ICAM_INFO_LISTENER,
+ ICI_OPERATOR_INTERFACE,
+ ICI_OPERATOR_LISTENER,
+ ICAM_PROFILE_INTERFACE,
+ ICONTENT_CONTROL_SERVICE,
+ ICAM_DRM_INFO_LISTENER,
+ ICAM_PIN_SERVICE,
+ ICAM_PIN_CAPABILITY_LISTENER,
+ ICAM_PIN_STATUS_LISTENER,
+ ICAM_HOST_CONTROL_SERVICE,
+ ICAM_HOST_CONTROL_ASK_RELEASE_REPLY_CALLBACK,
+ ICAM_HOST_CONTROL_INFO_LISTENER,
+ ICAM_HOST_CONTROL_TUNE_QUIETLY_FLAG,
+ ICAM_HOST_CONTROL_TUNE_QUIETLY_FLAG_LISTENER,
+ IMMI_INTERFACE,
+ IMMI_SESSION,
+ IMMI_STATUS_CALLBACK,
+ IENTER_MENU_ERROR_CALLBACK,
+ IDOWNLOADABLE_RATING_TABLE_MONITOR,
+ IRATING_INTERFACE,
+ IPMT_RATING_INTERFACE,
+ IPMT_RATING_LISTENER,
+ IVBI_RATING_INTERFACE,
+ IVBI_RATING_LISTENER,
+ IPROGRAM_INFO,
+ IPROGRAM_INFO_LISTENER,
+ IBROADCAST_TIME,
+ IDATA_SERVICE_SIGNAL_INFO,
+ IDATA_SERVICE_SIGNAL_INFO_LISTENER,
+ ITELETEXT_PAGE_SUB_CODE,
+ ISCAN_BACKGROUND_SERVICE_UPDATE,
+ ISCAN_BACKGROUND_SERVICE_UPDATE_LISTENER,
+ ICLIENT_TOKEN,
+ ISCREEN_MODE_SETTINGS,
+ IHDMI_SIGNAL_INTERFACE,
+ IHDMI_SIGNAL_INFO_LISTENER,
+ IAUDIO_SIGNAL_INFO,
+ IANALOG_AUDIO_INFO,
+ IAUDIO_SIGNAL_INFO_LISTENER,
+ IVIDEO_SIGNAL_INFO,
+ IVIDEO_SIGNAL_INFO_LISTENER,
+ ISERVICE_LIST_EDIT,
+ ISERVICE_LIST_EDIT_LISTENER,
+ ISERVICE_LIST,
+ ISERVICE_LIST_TRANSFER_INTERFACE,
+ ISERVICE_LIST_EXPORT_SESSION,
+ ISERVICE_LIST_EXPORT_LISTENER,
+ ISERVICE_LIST_IMPORT_SESSION,
+ ISERVICE_LIST_IMPORT_LISTENER,
+ ISERVICE_LIST_SET_CHANNEL_LIST_SESSION,
+ ISERVICE_LIST_SET_CHANNEL_LIST_LISTENER,
+ ICHANNEL_LIST_TRANSFER,
+ IRECORDED_CONTENTS,
+ IDELETE_RECORDED_CONTENTS_CALLBACK,
+ IGET_INFO_RECORDED_CONTENTS_CALLBACK,
+ IEVENT_MONITOR,
+ IEVENT_MONITOR_LISTENER,
+ IEVENT_DOWNLOAD,
+ IEVENT_DOWNLOAD_LISTENER,
+ IEVENT_DOWNLOAD_SESSION,
+ IANALOG_ATTRIBUTE_INTERFACE,
+ ICHANNEL_TUNED_INTERFACE,
+ ICHANNEL_TUNED_LISTENER,
+ ITUNER_FRONTEND_SIGNAL_INFO_INTERFACE,
+ ITUNER_FRONTEND_SIGNAL_INFO_LISTENER,
+ IMUX_TUNE_SESSION,
+ IMUX_TUNE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StandardizedExtensionName {}
+ /**
* Interface responsible for creating scan session and obtain parameters.
+ * @hide
*/
public static final String ISCAN_INTERFACE = SCAN_PACKAGE + "IScanInterface";
/**
* Interface that handles scan session and get/store related information.
+ * @hide
*/
public static final String ISCAN_SESSION = SCAN_PACKAGE + "IScanSession";
/**
* Interface that notifies changes related to scan session.
+ * @hide
*/
public static final String ISCAN_LISTENER = SCAN_PACKAGE + "IScanListener";
/**
* Interface for setting HDPlus information.
+ * @hide
*/
public static final String IHDPLUS_INFO = SCAN_PACKAGE + "IHDPlusInfo";
/**
* Interface for handling operator detection for scanning.
+ * @hide
*/
public static final String IOPERATOR_DETECTION = SCAN_PACKAGE + "IOperatorDetection";
/**
* Interface for changes related to operator detection searches.
+ * @hide
*/
public static final String IOPERATOR_DETECTION_LISTENER = SCAN_PACKAGE
+ "IOperatorDetectionListener";
/**
* Interface for handling region channel list for scanning.
+ * @hide
*/
public static final String IREGION_CHANNEL_LIST = SCAN_PACKAGE + "IRegionChannelList";
/**
* Interface for changes related to changes in region channel list search.
+ * @hide
*/
public static final String IREGION_CHANNEL_LIST_LISTENER = SCAN_PACKAGE
+ "IRegionChannelListListener";
/**
* Interface for handling target region information.
+ * @hide
*/
public static final String ITARGET_REGION = SCAN_PACKAGE + "ITargetRegion";
/**
* Interface for changes related to target regions during scanning.
+ * @hide
*/
public static final String ITARGET_REGION_LISTENER = SCAN_PACKAGE + "ITargetRegionListener";
/**
* Interface for handling LCN conflict groups.
+ * @hide
*/
public static final String ILCN_CONFLICT = SCAN_PACKAGE + "ILcnConflict";
/**
* Interface for detecting LCN conflicts during scanning.
+ * @hide
*/
public static final String ILCN_CONFLICT_LISTENER = SCAN_PACKAGE + "ILcnConflictListener";
/**
* Interface for handling LCN V2 channel list information.
+ * @hide
*/
public static final String ILCNV2_CHANNEL_LIST = SCAN_PACKAGE + "ILcnV2ChannelList";
/**
* Interface for detecting LCN V2 channel list during scanning.
+ * @hide
*/
public static final String ILCNV2_CHANNEL_LIST_LISTENER = SCAN_PACKAGE
+ "ILcnV2ChannelListListener";
/**
* Interface for handling favorite network related information.
+ * @hide
*/
public static final String IFAVORITE_NETWORK = SCAN_PACKAGE + "IFavoriteNetwork";
/**
* Interface for detecting favorite network during scanning.
+ * @hide
*/
public static final String IFAVORITE_NETWORK_LISTENER = SCAN_PACKAGE
+ "IFavoriteNetworkListener";
/**
* Interface for handling Turksat channel update system service.
+ * @hide
*/
public static final String ITKGS_INFO = SCAN_PACKAGE + "ITkgsInfo";
/**
* Interface for changes related to TKGS information.
+ * @hide
*/
public static final String ITKGS_INFO_LISTENER = SCAN_PACKAGE + "ITkgsInfoListener";
/**
* Interface for satellite search related to low noise block downconverter.
+ * @hide
*/
public static final String ISCAN_SAT_SEARCH = SCAN_PACKAGE + "IScanSatSearch";
/**
* Interface for Over-the-Air Download.
+ * @hide
*/
public static final String IOAD_UPDATE_INTERFACE = OAD_PACKAGE + "IOadUpdateInterface";
/**
* Interface for handling conditional access module app related information.
+ * @hide
*/
public static final String ICAM_APP_INFO_SERVICE = CAM_PACKAGE + "ICamAppInfoService";
/**
* Interface for changes on conditional access module app related information.
+ * @hide
*/
public static final String ICAM_APP_INFO_LISTENER = CAM_PACKAGE + "ICamAppInfoListener";
/**
* Interface for handling conditional access module related information.
+ * @hide
*/
public static final String ICAM_MONITORING_SERVICE = CAM_PACKAGE + "ICamMonitoringService";
/**
* Interface for changes on conditional access module related information.
+ * @hide
*/
public static final String ICAM_INFO_LISTENER = CAM_PACKAGE + "ICamInfoListener";
/**
* Interface for handling control of CI+ operations.
+ * @hide
*/
public static final String ICI_OPERATOR_INTERFACE = CAM_PACKAGE + "ICiOperatorInterface";
/**
* Interfaces for changes on CI+ operations.
+ * @hide
*/
public static final String ICI_OPERATOR_LISTENER = CAM_PACKAGE + "ICiOperatorListener";
/**
* Interface for handling conditional access module profile related information.
+ * @hide
*/
public static final String ICAM_PROFILE_INTERFACE = CAM_PACKAGE + "ICamProfileInterface";
/**
* Interface for handling conditional access module DRM related information.
+ * @hide
*/
public static final String ICONTENT_CONTROL_SERVICE = CAM_PACKAGE + "IContentControlService";
/**
* Interface for changes on DRM.
+ * @hide
*/
public static final String ICAM_DRM_INFO_LISTENER = CAM_PACKAGE + "ICamDrmInfoListener";
/**
* Interface for handling conditional access module pin related information.
+ * @hide
*/
public static final String ICAM_PIN_SERVICE = CAM_PACKAGE + "ICamPinService";
/**
* Interface for changes on conditional access module pin capability.
+ * @hide
*/
public static final String ICAM_PIN_CAPABILITY_LISTENER = CAM_PACKAGE
+ "ICamPinCapabilityListener";
/**
* Interface for changes on conditional access module pin status.
+ * @hide
*/
public static final String ICAM_PIN_STATUS_LISTENER = CAM_PACKAGE + "ICamPinStatusListener";
/**
* Interface for handling conditional access module host control service.
+ * @hide
*/
public static final String ICAM_HOST_CONTROL_SERVICE = CAM_PACKAGE + "ICamHostControlService";
/**
* Interface for handling conditional access module ask release reply.
+ * @hide
*/
public static final String ICAM_HOST_CONTROL_ASK_RELEASE_REPLY_CALLBACK = CAM_PACKAGE
+ "ICamHostControlAskReleaseReplyCallback";
/**
* Interface for changes on conditional access module host control service.
+ * @hide
*/
public static final String ICAM_HOST_CONTROL_INFO_LISTENER = CAM_PACKAGE
+ "ICamHostControlInfoListener";
/**
* Interface for handling conditional access module host control service tune_quietly_flag.
+ * @hide
*/
public static final String ICAM_HOST_CONTROL_TUNE_QUIETLY_FLAG = CAM_PACKAGE
+ "ICamHostControlTuneQuietlyFlag";
/**
* Interface for changes on conditional access module host control service tune_quietly_flag.
+ * @hide
*/
public static final String ICAM_HOST_CONTROL_TUNE_QUIETLY_FLAG_LISTENER = CAM_PACKAGE
+ "ICamHostControlTuneQuietlyFlagListener";
/**
* Interface for handling conditional access module multi media interface.
+ * @hide
*/
public static final String IMMI_INTERFACE = CAM_PACKAGE + "IMmiInterface";
/**
* Interface for controlling conditional access module multi media session.
+ * @hide
*/
public static final String IMMI_SESSION = CAM_PACKAGE + "IMmiSession";
/**
* Interface for changes on conditional access module multi media session status.
+ * @hide
*/
public static final String IMMI_STATUS_CALLBACK = CAM_PACKAGE + "IMmiStatusCallback";
/**
* Interface for changes on conditional access app info related to entering menu.
+ * @hide
*/
public static final String IENTER_MENU_ERROR_CALLBACK = CAM_PACKAGE + "IEnterMenuErrorCallback";
/**
* Interface for handling RRT downloadable rating data.
+ * @hide
*/
public static final String IDOWNLOADABLE_RATING_TABLE_MONITOR = RATING_PACKAGE
+ "IDownloadableRatingTableMonitor";
/**
* Interface for handling RRT rating related information.
+ * @hide
*/
public static final String IRATING_INTERFACE = RATING_PACKAGE + "IRatingInterface";
/**
* Interface for handling PMT rating related information.
+ * @hide
*/
public static final String IPMT_RATING_INTERFACE = RATING_PACKAGE + "IPmtRatingInterface";
/**
* Interface for changes on PMT rating related information.
+ * @hide
*/
public static final String IPMT_RATING_LISTENER = RATING_PACKAGE + "IPmtRatingListener";
/**
* Interface for handling IVBI rating related information.
+ * @hide
*/
public static final String IVBI_RATING_INTERFACE = RATING_PACKAGE + "IVbiRatingInterface";
/**
* Interface for changes on IVBI rating related information.
+ * @hide
*/
public static final String IVBI_RATING_LISTENER = RATING_PACKAGE + "IVbiRatingListener";
/**
* Interface for handling program rating related information.
+ * @hide
*/
public static final String IPROGRAM_INFO = RATING_PACKAGE + "IProgramInfo";
/**
* Interface for changes on program rating related information.
+ * @hide
*/
public static final String IPROGRAM_INFO_LISTENER = RATING_PACKAGE + "IProgramInfoListener";
/**
* Interface for getting broadcast time related information.
+ * @hide
*/
- public static final String BROADCAST_TIME = TIME_PACKAGE + "BroadcastTime";
+ public static final String IBROADCAST_TIME = TIME_PACKAGE + "BroadcastTime";
/**
* Interface for handling data service signal information on teletext.
+ * @hide
*/
public static final String IDATA_SERVICE_SIGNAL_INFO = TELETEXT_PACKAGE
+ "IDataServiceSignalInfo";
/**
* Interface for changes on data service signal information on teletext.
+ * @hide
*/
public static final String IDATA_SERVICE_SIGNAL_INFO_LISTENER = TELETEXT_PACKAGE
+ "IDataServiceSignalInfoListener";
/**
* Interface for handling teletext page information.
+ * @hide
*/
public static final String ITELETEXT_PAGE_SUB_CODE = TELETEXT_PACKAGE + "ITeletextPageSubCode";
/**
* Interface for handling scan background service update.
+ * @hide
*/
public static final String ISCAN_BACKGROUND_SERVICE_UPDATE = SCAN_BSU_PACKAGE
+ "IScanBackgroundServiceUpdate";
/**
* Interface for changes on background service update
+ * @hide
*/
public static final String ISCAN_BACKGROUND_SERVICE_UPDATE_LISTENER = SCAN_BSU_PACKAGE
+ "IScanBackgroundServiceUpdateListener";
/**
* Interface for generating client token.
+ * @hide
*/
public static final String ICLIENT_TOKEN = CLIENT_TOKEN_PACKAGE + "IClientToken";
/**
* Interfaces for handling screen mode information.
+ * @hide
*/
public static final String ISCREEN_MODE_SETTINGS = SCREEN_MODE_PACKAGE + "IScreenModeSettings";
/**
* Interfaces for handling HDMI signal information update.
+ * @hide
*/
public static final String IHDMI_SIGNAL_INTERFACE = SIGNAL_PACKAGE + "IHdmiSignalInterface";
/**
* Interfaces for changes on HDMI signal information update.
+ * @hide
*/
public static final String IHDMI_SIGNAL_INFO_LISTENER = SIGNAL_PACKAGE
+ "IHdmiSignalInfoListener";
/**
* Interfaces for handling audio signal information update.
+ * @hide
*/
public static final String IAUDIO_SIGNAL_INFO = SIGNAL_PACKAGE + "IAudioSignalInfo";
/**
* Interfaces for handling analog audio signal information update.
+ * @hide
*/
public static final String IANALOG_AUDIO_INFO = SIGNAL_PACKAGE + "IAnalogAudioInfo";
/**
* Interfaces for change on audio signal information update.
+ * @hide
*/
public static final String IAUDIO_SIGNAL_INFO_LISTENER = SIGNAL_PACKAGE
+ "IAudioSignalInfoListener";
/**
* Interfaces for handling video signal information update.
+ * @hide
*/
public static final String IVIDEO_SIGNAL_INFO = SIGNAL_PACKAGE + "IVideoSignalInfo";
/**
* Interfaces for changes on video signal information update.
+ * @hide
*/
public static final String IVIDEO_SIGNAL_INFO_LISTENER = SIGNAL_PACKAGE
+ "IVideoSignalInfoListener";
/**
* Interfaces for handling service database updates.
+ * @hide
*/
public static final String ISERVICE_LIST_EDIT = SERVICE_DATABASE_PACKAGE + "IServiceListEdit";
/**
* Interfaces for changes on service database updates.
+ * @hide
*/
public static final String ISERVICE_LIST_EDIT_LISTENER = SERVICE_DATABASE_PACKAGE
+ "IServiceListEditListener";
/**
* Interfaces for getting service database related information.
+ * @hide
*/
public static final String ISERVICE_LIST = SERVICE_DATABASE_PACKAGE + "IServiceList";
/**
* Interfaces for transferring service database related information.
+ * @hide
*/
public static final String ISERVICE_LIST_TRANSFER_INTERFACE = SERVICE_DATABASE_PACKAGE
+ "IServiceListTransferInterface";
/**
* Interfaces for exporting service database session.
+ * @hide
*/
public static final String ISERVICE_LIST_EXPORT_SESSION = SERVICE_DATABASE_PACKAGE
+ "IServiceListExportSession";
/**
* Interfaces for changes on exporting service database session.
+ * @hide
*/
public static final String ISERVICE_LIST_EXPORT_LISTENER = SERVICE_DATABASE_PACKAGE
+ "IServiceListExportListener";
/**
* Interfaces for importing service database session.
+ * @hide
*/
public static final String ISERVICE_LIST_IMPORT_SESSION = SERVICE_DATABASE_PACKAGE
+ "IServiceListImportSession";
/**
* Interfaces for changes on importing service database session.
+ * @hide
*/
public static final String ISERVICE_LIST_IMPORT_LISTENER = SERVICE_DATABASE_PACKAGE
+ "IServiceListImportListener";
/**
* Interfaces for setting channel list resources.
+ * @hide
*/
public static final String ISERVICE_LIST_SET_CHANNEL_LIST_SESSION = SERVICE_DATABASE_PACKAGE
+ "IServiceListSetChannelListSession";
/**
* Interfaces for changes on setting channel list resources.
+ * @hide
*/
public static final String ISERVICE_LIST_SET_CHANNEL_LIST_LISTENER = SERVICE_DATABASE_PACKAGE
+ "IServiceListSetChannelListListener";
/**
* Interfaces for transferring channel list resources.
+ * @hide
*/
public static final String ICHANNEL_LIST_TRANSFER = SERVICE_DATABASE_PACKAGE
+ "IChannelListTransfer";
/**
* Interfaces for record contents updates.
+ * @hide
*/
public static final String IRECORDED_CONTENTS = PVR_PACKAGE + "IRecordedContents";
/**
* Interfaces for changes on deleting record contents.
+ * @hide
*/
public static final String IDELETE_RECORDED_CONTENTS_CALLBACK = PVR_PACKAGE
+ "IDeleteRecordedContentsCallback";
/**
* Interfaces for changes on getting record contents.
+ * @hide
*/
public static final String IGET_INFO_RECORDED_CONTENTS_CALLBACK = PVR_PACKAGE
+ "IGetInfoRecordedContentsCallback";
/**
* Interfaces for monitoring present event information.
+ * @hide
*/
public static final String IEVENT_MONITOR = EVENT_PACKAGE + "IEventMonitor";
/**
* Interfaces for changes on present event information.
+ * @hide
*/
public static final String IEVENT_MONITOR_LISTENER = EVENT_PACKAGE + "IEventMonitorListener";
/**
* Interfaces for handling download event information.
+ * @hide
*/
public static final String IEVENT_DOWNLOAD = EVENT_PACKAGE + "IEventDownload";
/**
* Interfaces for changes on downloading event information.
+ * @hide
*/
public static final String IEVENT_DOWNLOAD_LISTENER = EVENT_PACKAGE + "IEventDownloadListener";
/**
* Interfaces for handling download event information for DVB and DTMB.
+ * @hide
*/
public static final String IEVENT_DOWNLOAD_SESSION = EVENT_PACKAGE + "IEventDownloadSession";
/**
* Interfaces for handling analog color system.
+ * @hide
*/
public static final String IANALOG_ATTRIBUTE_INTERFACE = ANALOG_PACKAGE
+ "IAnalogAttributeInterface";
/**
* Interfaces for monitoring channel tuned information.
+ * @hide
*/
public static final String ICHANNEL_TUNED_INTERFACE = TUNE_PACKAGE + "IChannelTunedInterface";
/**
* Interfaces for changes on channel tuned information.
+ * @hide
*/
public static final String ICHANNEL_TUNED_LISTENER = TUNE_PACKAGE + "IChannelTunedListener";
/**
* Interfaces for handling tuner frontend signal info.
+ * @hide
*/
public static final String ITUNER_FRONTEND_SIGNAL_INFO_INTERFACE = SIGNAL_PACKAGE
+ "ITunerFrontendSignalInfoInterface";
/**
* Interfaces for changes on tuner frontend signal info.
+ * @hide
*/
public static final String ITUNER_FRONTEND_SIGNAL_INFO_LISTENER = SIGNAL_PACKAGE
+ "ITunerFrontendSignalInfoListener";
/**
* Interfaces for handling mux tune operations.
+ * @hide
*/
public static final String IMUX_TUNE_SESSION = TUNE_PACKAGE + "IMuxTuneSession";
/**
* Interfaces for initing mux tune session.
+ * @hide
*/
public static final String IMUX_TUNE = TUNE_PACKAGE + "IMuxTune";
@@ -506,7 +718,7 @@
IVBI_RATING_LISTENER,
IPROGRAM_INFO,
IPROGRAM_INFO_LISTENER,
- BROADCAST_TIME,
+ IBROADCAST_TIME,
IDATA_SERVICE_SIGNAL_INFO,
IDATA_SERVICE_SIGNAL_INFO_LISTENER,
ITELETEXT_PAGE_SUB_CODE,
@@ -586,7 +798,8 @@
*
* @hide
*/
- public int registerExtensionIBinder(@NonNull String extensionName,
+ @RegisterResult
+ public int registerExtensionIBinder(@StandardizedExtensionName @NonNull String extensionName,
@NonNull IBinder binder) {
if (!checkIsStandardizedInterfaces(extensionName)) {
return REGISTER_FAIL_NAME_NOT_STANDARDIZED;
diff --git a/native/android/tests/thermal/NativeThermalUnitTest.cpp b/native/android/tests/thermal/NativeThermalUnitTest.cpp
index 6d6861a..4e319fc 100644
--- a/native/android/tests/thermal/NativeThermalUnitTest.cpp
+++ b/native/android/tests/thermal/NativeThermalUnitTest.cpp
@@ -67,6 +67,14 @@
MOCK_METHOD(Status, getThermalHeadroomThresholds, (::std::vector<float> * _aidl_return),
(override));
MOCK_METHOD(IBinder*, onAsBinder, (), (override));
+ MOCK_METHOD(Status, registerThermalHeadroomListener,
+ (const ::android::sp<::android::os::IThermalHeadroomListener>& listener,
+ bool* _aidl_return),
+ (override));
+ MOCK_METHOD(Status, unregisterThermalHeadroomListener,
+ (const ::android::sp<::android::os::IThermalHeadroomListener>& listener,
+ bool* _aidl_return),
+ (override));
};
class NativeThermalUnitTest : public Test {
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 0fb3049..23dd9b7 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -48,7 +48,9 @@
"libhwui_internal_headers",
],
- static_libs: ["libarect"],
+ static_libs: [
+ "libarect",
+ ],
host_supported: true,
target: {
@@ -60,6 +62,11 @@
shared_libs: [
"libandroid",
],
+ static_libs: [
+ "libstatslog_hwui",
+ "libstatspull_lazy",
+ "libstatssocket_lazy",
+ ],
version_script: "libjnigraphics.map.txt",
},
host: {
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index e18b4a9..cb95bcf 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -14,18 +14,9 @@
* limitations under the License.
*/
-#include "aassetstreamadaptor.h"
-
-#include <android/asset_manager.h>
-#include <android/bitmap.h>
-#include <android/data_space.h>
-#include <android/imagedecoder.h>
#include <MimeType.h>
-#include <android/rect.h>
-#include <hwui/ImageDecoder.h>
-#include <log/log.h>
-#include <SkAndroidCodec.h>
#include <SkAlphaType.h>
+#include <SkAndroidCodec.h>
#include <SkCodec.h>
#include <SkCodecAnimation.h>
#include <SkColorSpace.h>
@@ -35,14 +26,24 @@
#include <SkRefCnt.h>
#include <SkSize.h>
#include <SkStream.h>
-#include <utils/Color.h>
-
+#include <android/asset_manager.h>
+#include <android/bitmap.h>
+#include <android/data_space.h>
+#include <android/imagedecoder.h>
+#include <android/rect.h>
#include <fcntl.h>
-#include <limits>
-#include <optional>
+#include <hwui/ImageDecoder.h>
+#include <log/log.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <utils/Color.h>
+#include <utils/StatsUtils.h>
+
+#include <limits>
+#include <optional>
+
+#include "aassetstreamadaptor.h"
using namespace android;
@@ -400,9 +401,7 @@
return info.minRowBytes();
}
-int AImageDecoder_decodeImage(AImageDecoder* decoder,
- void* pixels, size_t stride,
- size_t size) {
+int AImageDecoder_decodeImage(AImageDecoder* decoder, void* pixels, size_t stride, size_t size) {
if (!decoder || !pixels || !stride) {
return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
}
@@ -419,7 +418,13 @@
return ANDROID_IMAGE_DECODER_FINISHED;
}
- return ResultToErrorCode(imageDecoder->decode(pixels, stride));
+ const auto result = ResultToErrorCode(imageDecoder->decode(pixels, stride));
+
+ if (result == ANDROID_IMAGE_DECODER_SUCCESS) {
+ uirenderer::logBitmapDecode(imageDecoder->getOutputInfo(), false);
+ }
+
+ return result;
}
void AImageDecoder_delete(AImageDecoder* decoder) {
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 6aa8a2b..675c8f8 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -59,6 +59,7 @@
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.List<java.lang.String> getActiveNfceeList();
method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.nfc.RoutingStatus getRoutingStatus();
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.List<android.nfc.NfcRoutingTableEntry> getRoutingTable();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean hasUserEnabledNfc();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAutoChangeEnabled();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagPresent();
@@ -110,12 +111,46 @@
method public void onTagDispatch(@NonNull java.util.function.Consumer<java.lang.Boolean>);
}
+ @FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry {
+ method public int getNfceeId();
+ }
+
@FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingStatus {
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultIsoDepRoute();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultOffHostRoute();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultRoute();
}
+ @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableAidEntry extends android.nfc.NfcRoutingTableEntry {
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public String getAid();
+ }
+
+ @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableProtocolEntry extends android.nfc.NfcRoutingTableEntry {
+ method @FlaggedApi("android.nfc.nfc_oem_extension") public int getProtocol();
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_ISO_DEP = 4; // 0x4
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_NDEF = 7; // 0x7
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_NFC_DEP = 5; // 0x5
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T1T = 1; // 0x1
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T2T = 2; // 0x2
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T3T = 3; // 0x3
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T5T = 6; // 0x6
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_UNDETERMINED = 0; // 0x0
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_UNSUPPORTED = -1; // 0xffffffff
+ }
+
+ @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableSystemCodeEntry extends android.nfc.NfcRoutingTableEntry {
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public byte[] getSystemCode();
+ }
+
+ @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableTechnologyEntry extends android.nfc.NfcRoutingTableEntry {
+ method @FlaggedApi("android.nfc.nfc_oem_extension") public int getTechnology();
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_A = 0; // 0x0
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_B = 1; // 0x1
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_F = 2; // 0x2
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_UNSUPPORTED = -1; // 0xffffffff
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_V = 3; // 0x3
+ }
+
}
package android.nfc.cardemulation {
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/nfc/java/android/nfc/Entry.aidl
similarity index 88%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to nfc/java/android/nfc/Entry.aidl
index e21bf8f..148c4ec 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/nfc/java/android/nfc/Entry.aidl
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.nfc;
-package com.android.wm.shell.shared;
-
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+parcelable Entry;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/Entry.java b/nfc/java/android/nfc/Entry.java
new file mode 100644
index 0000000..49d0f10
--- /dev/null
+++ b/nfc/java/android/nfc/Entry.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.nfc;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+
+/** @hide */
+public final class Entry implements Parcelable {
+ private final byte mType;
+ private final byte mNfceeId;
+ private final String mEntry;
+
+ public Entry(String entry, byte type, byte nfceeId) {
+ mEntry = entry;
+ mType = type;
+ mNfceeId = nfceeId;
+ }
+
+ public byte getType() {
+ return mType;
+ }
+
+ public byte getNfceeId() {
+ return mNfceeId;
+ }
+
+ public String getEntry() {
+ return mEntry;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ private Entry(Parcel in) {
+ this.mEntry = in.readString();
+ this.mNfceeId = in.readByte();
+ this.mType = in.readByte();
+ }
+
+ public static final @NonNull Parcelable.Creator<Entry> CREATOR =
+ new Parcelable.Creator<Entry>() {
+ @Override
+ public Entry createFromParcel(Parcel in) {
+ return new Entry(in);
+ }
+
+ @Override
+ public Entry[] newArray(int size) {
+ return new Entry[size];
+ }
+ };
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mEntry);
+ dest.writeByte(mNfceeId);
+ dest.writeByte(mType);
+ }
+}
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index a166b28..40fd068 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -18,6 +18,7 @@
import android.app.PendingIntent;
import android.content.IntentFilter;
+import android.nfc.Entry;
import android.nfc.NdefMessage;
import android.nfc.Tag;
import android.nfc.TechListParcel;
@@ -117,4 +118,6 @@
void triggerInitialization();
boolean getSettingStatus();
boolean isTagPresent();
+ List<Entry> getRoutingTableEntryList();
+ void indicateDataMigration(boolean inProgress, String pkg);
}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index d9fd42f..c5d8191 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -2795,11 +2795,8 @@
@IntRange(from = 0, to = 15) int gid, @IntRange(from = 0) int oid,
@NonNull byte[] payload) {
Objects.requireNonNull(payload, "Payload must not be null");
- try {
- return sService.sendVendorNciMessage(mt, gid, oid, payload);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return callServiceReturn(() -> sService.sendVendorNciMessage(mt, gid, oid, payload),
+ SEND_VENDOR_NCI_STATUS_FAILED);
}
/**
@@ -2873,6 +2870,18 @@
}
/**
+ * Used by data migration to indicate data migration is in progrerss or not.
+ *
+ * Note: This is @hide intentionally since the client is inside the NFC apex.
+ * @param inProgress true if migration is in progress, false once done.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public void indicateDataMigration(boolean inProgress) {
+ callService(() -> sService.indicateDataMigration(inProgress, mContext.getPackageName()));
+ }
+
+ /**
* Returns an instance of {@link NfcOemExtension} associated with {@link NfcAdapter} instance.
* @hide
*/
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 1d2085c..1bfe714 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -43,6 +43,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -71,6 +72,11 @@
public final class NfcOemExtension {
private static final String TAG = "NfcOemExtension";
private static final int OEM_EXTENSION_RESPONSE_THRESHOLD_MS = 2000;
+ private static final int TYPE_TECHNOLOGY = 0;
+ private static final int TYPE_PROTOCOL = 1;
+ private static final int TYPE_AID = 2;
+ private static final int TYPE_SYSTEMCODE = 3;
+
private final NfcAdapter mAdapter;
private final NfcOemExtensionCallback mOemNfcExtensionCallback;
private boolean mIsRegistered = false;
@@ -689,6 +695,39 @@
));
}
+ /**
+ * Gets current routing table entries.
+ * @return List of {@link NfcRoutingTableEntry} representing current routing table
+ */
+ @NonNull
+ @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public List<NfcRoutingTableEntry> getRoutingTable() {
+ List<Entry> entryList = NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sService.getRoutingTableEntryList(), null);
+ List<NfcRoutingTableEntry> result = new ArrayList<>();
+ for (Entry entry : entryList) {
+ switch (entry.getType()) {
+ case TYPE_TECHNOLOGY -> result.add(
+ new RoutingTableTechnologyEntry(entry.getNfceeId(),
+ RoutingTableTechnologyEntry.techStringToInt(entry.getEntry()))
+ );
+ case TYPE_PROTOCOL -> result.add(
+ new RoutingTableProtocolEntry(entry.getNfceeId(),
+ RoutingTableProtocolEntry.protocolStringToInt(entry.getEntry()))
+ );
+ case TYPE_AID -> result.add(
+ new RoutingTableAidEntry(entry.getNfceeId(), entry.getEntry())
+ );
+ case TYPE_SYSTEMCODE -> result.add(
+ new RoutingTableSystemCodeEntry(entry.getNfceeId(),
+ entry.getEntry().getBytes(StandardCharsets.UTF_8))
+ );
+ }
+ }
+ return result;
+ }
+
private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
@Override
diff --git a/nfc/java/android/nfc/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java
new file mode 100644
index 0000000..4e91377
--- /dev/null
+++ b/nfc/java/android/nfc/NfcRoutingTableEntry.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.nfc;
+
+
+import android.annotation.FlaggedApi;
+import android.annotation.SystemApi;
+
+/**
+ * Class to represent an entry of routing table. This class is abstract and extended by
+ * {@link RoutingTableTechnologyEntry}, {@link RoutingTableProtocolEntry},
+ * {@link RoutingTableAidEntry} and {@link RoutingTableSystemCodeEntry}.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public abstract class NfcRoutingTableEntry {
+ private final int mNfceeId;
+
+ /** @hide */
+ protected NfcRoutingTableEntry(int nfceeId) {
+ mNfceeId = nfceeId;
+ }
+
+ /**
+ * Gets the NFCEE Id of this entry.
+ * @return an integer of NFCEE Id.
+ */
+ public int getNfceeId() {
+ return mNfceeId;
+ }
+}
diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java
new file mode 100644
index 0000000..7634fe3
--- /dev/null
+++ b/nfc/java/android/nfc/RoutingTableAidEntry.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Represents an AID entry in current routing table.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public class RoutingTableAidEntry extends NfcRoutingTableEntry {
+ private final String mValue;
+
+ /** @hide */
+ public RoutingTableAidEntry(int nfceeId, String value) {
+ super(nfceeId);
+ this.mValue = value;
+ }
+
+ /**
+ * Gets AID value.
+ * @return String of AID
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ @NonNull
+ public String getAid() {
+ return mValue;
+ }
+}
diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
new file mode 100644
index 0000000..0c5be7d
--- /dev/null
+++ b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Represents a protocol entry in current routing table.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public class RoutingTableProtocolEntry extends NfcRoutingTableEntry {
+ /**
+ * Protocol undetermined.
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int PROTOCOL_UNDETERMINED = 0;
+ /**
+ * T1T Protocol
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int PROTOCOL_T1T = 1;
+ /**
+ * T2T Protocol
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int PROTOCOL_T2T = 2;
+ /**
+ * T3T Protocol
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int PROTOCOL_T3T = 3;
+ /**
+ * ISO-DEP Protocol
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int PROTOCOL_ISO_DEP = 4;
+ /**
+ * DEP Protocol
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int PROTOCOL_NFC_DEP = 5;
+ /**
+ * T5T Protocol
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int PROTOCOL_T5T = 6;
+ /**
+ * NDEF Protocol
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int PROTOCOL_NDEF = 7;
+ /**
+ * Unsupported Protocol
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int PROTOCOL_UNSUPPORTED = -1;
+
+ /**
+ *
+ * @hide
+ */
+ @IntDef(prefix = { "PROTOCOL_" }, value = {
+ PROTOCOL_UNDETERMINED,
+ PROTOCOL_T1T,
+ PROTOCOL_T2T,
+ PROTOCOL_T3T,
+ PROTOCOL_ISO_DEP,
+ PROTOCOL_NFC_DEP,
+ PROTOCOL_T5T,
+ PROTOCOL_NDEF,
+ PROTOCOL_UNSUPPORTED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ProtocolValue {}
+
+ private final @ProtocolValue int mValue;
+
+ /** @hide */
+ public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value) {
+ super(nfceeId);
+ this.mValue = value;
+ }
+
+ /**
+ * Gets Protocol value.
+ * @return Protocol defined in {@link ProtocolValue}
+ */
+ @ProtocolValue
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public int getProtocol() {
+ return mValue;
+ }
+
+ /** @hide */
+ @ProtocolValue
+ public static int protocolStringToInt(String protocolString) {
+ return switch (protocolString) {
+ case "PROTOCOL_T1T" -> PROTOCOL_T1T;
+ case "PROTOCOL_T2T" -> PROTOCOL_T2T;
+ case "PROTOCOL_T3T" -> PROTOCOL_T3T;
+ case "PROTOCOL_ISO_DEP" -> PROTOCOL_ISO_DEP;
+ case "PROTOCOL_NFC_DEP" -> PROTOCOL_NFC_DEP;
+ case "PROTOCOL_T5T" -> PROTOCOL_T5T;
+ case "PROTOCOL_NDEF" -> PROTOCOL_NDEF;
+ case "PROTOCOL_UNDETERMINED" -> PROTOCOL_UNDETERMINED;
+ default -> PROTOCOL_UNSUPPORTED;
+ };
+ }
+}
diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
new file mode 100644
index 0000000..f87ad5f
--- /dev/null
+++ b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Represents a system code entry in current routing table.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public class RoutingTableSystemCodeEntry extends NfcRoutingTableEntry {
+ private final byte[] mValue;
+
+ /** @hide */
+ public RoutingTableSystemCodeEntry(int nfceeId, byte[] value) {
+ super(nfceeId);
+ this.mValue = value;
+ }
+
+ /**
+ * Gets system code value.
+ * @return Byte array of system code
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ @NonNull
+ public byte[] getSystemCode() {
+ return mValue;
+ }
+}
diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
new file mode 100644
index 0000000..f51a529
--- /dev/null
+++ b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Represents a technology entry in current routing table.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry {
+ /**
+ * Technology-A
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int TECHNOLOGY_A = 0;
+ /**
+ * Technology-B
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int TECHNOLOGY_B = 1;
+ /**
+ * Technology-F
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int TECHNOLOGY_F = 2;
+ /**
+ * Technology-V
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int TECHNOLOGY_V = 3;
+ /**
+ * Unsupported technology
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int TECHNOLOGY_UNSUPPORTED = -1;
+
+ /**
+ *
+ * @hide
+ */
+ @IntDef(prefix = { "TECHNOLOGY_" }, value = {
+ TECHNOLOGY_A,
+ TECHNOLOGY_B,
+ TECHNOLOGY_F,
+ TECHNOLOGY_V,
+ TECHNOLOGY_UNSUPPORTED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TechnologyValue{}
+
+ private final @TechnologyValue int mValue;
+
+ /** @hide */
+ public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value) {
+ super(nfceeId);
+ this.mValue = value;
+ }
+
+ /**
+ * Gets technology value.
+ * @return technology value
+ */
+ @TechnologyValue
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public int getTechnology() {
+ return mValue;
+ }
+
+ /** @hide */
+ @TechnologyValue
+ public static int techStringToInt(String tech) {
+ return switch (tech) {
+ case "TECHNOLOGY_A" -> TECHNOLOGY_A;
+ case "TECHNOLOGY_B" -> TECHNOLOGY_B;
+ case "TECHNOLOGY_F" -> TECHNOLOGY_F;
+ case "TECHNOLOGY_V" -> TECHNOLOGY_V;
+ default -> TECHNOLOGY_UNSUPPORTED;
+ };
+ }
+}
diff --git a/packages/CarrierDefaultApp/res/values-bs/strings.xml b/packages/CarrierDefaultApp/res/values-bs/strings.xml
index bc725fe..50b7312 100644
--- a/packages/CarrierDefaultApp/res/values-bs/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bs/strings.xml
@@ -7,9 +7,9 @@
<string name="no_data_notification_id" msgid="668400731803969521">"Prijenos podataka na mobilnoj mreži je deaktiviran"</string>
<string name="portal_notification_detail" msgid="2295729385924660881">"Dodirnite da posjetite %s web lokaciju"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"Obratite se pružaocu usluga %s"</string>
- <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nema veze za prijenos podataka na mobilnoj mreži"</string>
- <string name="no_mobile_data_connection" msgid="544980465184147010">"Dodajte plan prijenosa podataka ili rominga putem operatera %s"</string>
- <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status prijenosa podataka na mobilnoj mreži"</string>
+ <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Nema veze za prenos podataka na mobilnoj mreži"</string>
+ <string name="no_mobile_data_connection" msgid="544980465184147010">"Dodajte plan prenosa podataka ili rominga putem operatera %s"</string>
+ <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"Status prenosa podataka na mobilnoj mreži"</string>
<string name="action_bar_label" msgid="4290345990334377177">"Prijava na mobilnu mrežu"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"Mreža kojoj pokušavate pristupiti ima sigurnosnih problema."</string>
<string name="ssl_error_example" msgid="6188711843183058764">"Naprimjer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index abb02992..86e8918 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -40,7 +40,7 @@
<string name="summary_generic" msgid="1761976003668044801">"Aplikasi ini akan dapat menyinkronkan info, seperti nama penelepon, antara ponsel dan perangkat yang dipilih"</string>
<string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
<string name="consent_no" msgid="2640796915611404382">"Jangan izinkan"</string>
- <string name="consent_cancel" msgid="5655005528379285841">"Batalkan"</string>
+ <string name="consent_cancel" msgid="5655005528379285841">"Batal"</string>
<string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
<string name="permission_expand" msgid="893185038020887411">"Luaskan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
<string name="permission_collapse" msgid="3320833884220844084">"Ciutkan <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index 5ac1e56..9520a32 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -56,7 +56,7 @@
<string name="permission_nearby_devices" msgid="7530973297737123481">"जवळपासची डिव्हाइस"</string>
<string name="permission_media_routing_control" msgid="5498639511586715253">"मीडिया आउटपुट बदला"</string>
<string name="permission_storage" msgid="6831099350839392343">"फोटो आणि मीडिया"</string>
- <string name="permission_notifications" msgid="4099418516590632909">"सूचना"</string>
+ <string name="permission_notifications" msgid="4099418516590632909">"नोटिफिकेशन"</string>
<string name="permission_phone_summary" msgid="8246321093970051702">"फोन कॉल करणे आणि ते व्यवस्थापित करणे"</string>
<string name="permission_call_logs_summary" msgid="7545243592757693321">"फोन कॉल लॉग रीड अँड राइट करणे"</string>
<string name="permission_sms_summary" msgid="8499509535410068616">"एसएमएस पाठवणे आणि पाहणे"</string>
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java
index f1103e1..992f581 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java
@@ -896,7 +896,8 @@
int systemUserId = UserHandle.SYSTEM.getIdentifier();
int[] userIds = { systemUserId };
try {
- for (File file : FileUtils.listFilesOrEmpty(Environment.getDataSystemDeDirectory())) {
+ for (File file : FileUtils.listFilesOrEmpty(
+ Environment.getDataSystemDeviceProtectedDirectory())) {
try {
final int userId = Integer.parseInt(file.getName());
if (userId != systemUserId) {
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 8277e57..311def8 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -499,8 +499,8 @@
// Check if the package is listed among the system modules or is an
// APK inside an updatable APEX.
try {
- final PackageInfo pkg = mContext.getPackageManager()
- .getPackageInfo(packageName, 0 /* flags */);
+ PackageManager pm = mContext.getPackageManager();
+ final PackageInfo pkg = pm.getPackageInfo(packageName, 0 /* flags */);
String apexPackageName = pkg.getApexPackageName();
if (apexPackageName != null) {
packageName = apexPackageName;
diff --git a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
index 2acedd5..129e47f 100644
--- a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
@@ -300,6 +300,31 @@
sPackageWatchdog = this;
}
+ /**
+ * Creating this temp constructor to match module constructor.
+ * Note: To be only used in tests.
+ * Creates a PackageWatchdog that allows injecting dependencies,
+ * except for connectivity module connector.
+ */
+ @VisibleForTesting
+ PackageWatchdog(Context context, AtomicFile policyFile, Handler shortTaskHandler,
+ Handler longTaskHandler, ExplicitHealthCheckController controller,
+ SystemClock clock) {
+ mContext = context;
+ mPolicyFile = policyFile;
+ mShortTaskHandler = shortTaskHandler;
+ mLongTaskHandler = longTaskHandler;
+ mHealthCheckController = controller;
+ mConnectivityModuleConnector = ConnectivityModuleConnector.getInstance();
+ mSystemClock = clock;
+ mNumberOfNativeCrashPollsRemaining = NUMBER_OF_NATIVE_CRASH_POLLS;
+ mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
+ DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS);
+
+ loadFromFile();
+ sPackageWatchdog = this;
+ }
+
/** Creates or gets singleton instance of PackageWatchdog. */
public static @NonNull PackageWatchdog getInstance(@NonNull Context context) {
synchronized (sPackageWatchdogLock) {
@@ -358,7 +383,7 @@
*
* <p>If monitoring a package supporting explicit health check, at the end of the monitoring
* duration if {@link #onHealthCheckPassed} was never called,
- * {@link PackageHealthObserver#execute} will be called as if the package failed.
+ * {@link PackageHealthObserver#onExecuteHealthCheckMitigation} will be called as if the package failed.
*
* <p>If {@code observer} is already monitoring a package in {@code packageNames},
* the monitoring window of that package will be reset to {@code durationMs} and the health
@@ -521,8 +546,8 @@
maybeExecute(currentObserverToNotify, versionedPackage,
failureReason, currentObserverImpact, mitigationCount);
} else {
- currentObserverToNotify.execute(versionedPackage,
- failureReason, mitigationCount);
+ currentObserverToNotify.onExecuteHealthCheckMitigation(
+ versionedPackage, failureReason, mitigationCount);
}
}
}
@@ -557,7 +582,8 @@
maybeExecute(currentObserverToNotify, failingPackage, failureReason,
currentObserverImpact, /*mitigationCount=*/ 1);
} else {
- currentObserverToNotify.execute(failingPackage, failureReason, 1);
+ currentObserverToNotify.onExecuteHealthCheckMitigation(failingPackage,
+ failureReason, 1);
}
}
}
@@ -571,7 +597,8 @@
synchronized (mLock) {
mLastMitigation = mSystemClock.uptimeMillis();
}
- currentObserverToNotify.execute(versionedPackage, failureReason, mitigationCount);
+ currentObserverToNotify.onExecuteHealthCheckMitigation(versionedPackage, failureReason,
+ mitigationCount);
}
}
@@ -633,12 +660,12 @@
currentObserverInternal.setBootMitigationCount(
currentObserverMitigationCount);
saveAllObserversBootMitigationCountToMetadata(METADATA_FILE);
- currentObserverToNotify.executeBootLoopMitigation(
+ currentObserverToNotify.onExecuteBootLoopMitigation(
currentObserverMitigationCount);
} else {
mBootThreshold.setMitigationCount(mitigationCount);
mBootThreshold.saveMitigationCountToMetadata();
- currentObserverToNotify.executeBootLoopMitigation(mitigationCount);
+ currentObserverToNotify.onExecuteBootLoopMitigation(mitigationCount);
}
}
}
@@ -724,7 +751,8 @@
return mPackagesExemptFromImpactLevelThreshold;
}
- /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}.
+ /** Possible severity values of the user impact of a
+ * {@link PackageHealthObserver#onExecuteHealthCheckMitigation}.
* @hide
*/
@Retention(SOURCE)
@@ -772,7 +800,7 @@
*
*
* @return any one of {@link PackageHealthObserverImpact} to express the impact
- * to the user on {@link #execute}
+ * to the user on {@link #onExecuteHealthCheckMitigation}
*/
@PackageHealthObserverImpact int onHealthCheckFailed(
@Nullable VersionedPackage versionedPackage,
@@ -789,7 +817,7 @@
* (including this time).
* @return {@code true} if action was executed successfully, {@code false} otherwise
*/
- boolean execute(@Nullable VersionedPackage versionedPackage,
+ boolean onExecuteHealthCheckMitigation(@Nullable VersionedPackage versionedPackage,
@FailureReasons int failureReason, int mitigationCount);
@@ -809,7 +837,7 @@
* @param mitigationCount the number of times mitigation has been attempted for this
* boot loop (including this time).
*/
- default boolean executeBootLoopMitigation(int mitigationCount) {
+ default boolean onExecuteBootLoopMitigation(int mitigationCount) {
return false;
}
@@ -1090,7 +1118,7 @@
if (versionedPkg != null) {
Slog.i(TAG,
"Explicit health check failed for package " + versionedPkg);
- registeredObserver.execute(versionedPkg,
+ registeredObserver.onExecuteHealthCheckMitigation(versionedPkg,
PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK, 1);
}
}
diff --git a/packages/CrashRecovery/services/platform/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/platform/java/com/android/server/RescueParty.java
index feb5775..f757236 100644
--- a/packages/CrashRecovery/services/platform/java/com/android/server/RescueParty.java
+++ b/packages/CrashRecovery/services/platform/java/com/android/server/RescueParty.java
@@ -859,7 +859,7 @@
}
@Override
- public boolean execute(@Nullable VersionedPackage failedPackage,
+ public boolean onExecuteHealthCheckMitigation(@Nullable VersionedPackage failedPackage,
@FailureReasons int failureReason, int mitigationCount) {
if (isDisabled()) {
return false;
@@ -927,7 +927,7 @@
}
@Override
- public boolean executeBootLoopMitigation(int mitigationCount) {
+ public boolean onExecuteBootLoopMitigation(int mitigationCount) {
if (isDisabled()) {
return false;
}
diff --git a/packages/CrashRecovery/services/platform/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/packages/CrashRecovery/services/platform/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index d206c66..7445534 100644
--- a/packages/CrashRecovery/services/platform/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/packages/CrashRecovery/services/platform/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -158,7 +158,7 @@
// Note: For non-native crashes the rollback-all step has higher impact
impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
} else if (getAvailableRollback(failedPackage) != null) {
- // Rollback is available, we may get a callback into #execute
+ // Rollback is available, we may get a callback into #onExecuteHealthCheckMitigation
impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
} else if (anyRollbackAvailable) {
// If any rollbacks are available, we will commit them
@@ -175,7 +175,7 @@
}
@Override
- public boolean execute(@Nullable VersionedPackage failedPackage,
+ public boolean onExecuteHealthCheckMitigation(@Nullable VersionedPackage failedPackage,
@FailureReasons int rollbackReason, int mitigationCount) {
Slog.i(TAG, "Executing remediation."
+ " failedPackage: "
@@ -229,7 +229,7 @@
}
@Override
- public boolean executeBootLoopMitigation(int mitigationCount) {
+ public boolean onExecuteBootLoopMitigation(int mitigationCount) {
if (Flags.recoverabilityDetection()) {
List<RollbackInfo> availableRollbacks = getAvailableRollbacks();
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java
index 062e9b8..42ffa67 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java
@@ -17,6 +17,7 @@
package com.android.settingslib.collapsingtoolbar;
import android.os.Build;
+import android.view.ViewGroup;
import androidx.activity.ComponentActivity;
import androidx.activity.EdgeToEdge;
@@ -53,6 +54,8 @@
.getInsets(WindowInsetsCompat.Type.statusBars()).top;
// Apply the insets paddings to the view.
v.setPadding(insets.left, statusBarHeight, insets.right, insets.bottom);
+ ((ViewGroup)v).setClipToPadding(false);
+ ((ViewGroup)v).setClipChildren(false);
// Return CONSUMED if you don't want the window insets to keep being
// passed down to descendant views.
diff --git a/packages/SettingsLib/HelpUtils/res/values-en-rGB/strings.xml b/packages/SettingsLib/HelpUtils/res/values-en-rGB/strings.xml
index 759da1d0..150020c 100644
--- a/packages/SettingsLib/HelpUtils/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-en-rGB/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="help_feedback_label" msgid="7106780063063027882">"Help & feedback"</string>
+ <string name="help_feedback_label" msgid="7106780063063027882">"Help and feedback"</string>
</resources>
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt
index 72cf403..49acc1d 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt
@@ -115,7 +115,7 @@
fun isFlagEnabled(context: Context): Boolean = true
val preferenceBindingFactory: PreferenceBindingFactory
- get() = DefaultPreferenceBindingFactory
+ get() = PreferenceBindingFactory.defaultFactory
override fun createPreferenceScreen(factory: PreferenceScreenFactory) =
factory.getOrCreatePreferenceScreen().apply {
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBindingFactory.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBindingFactory.kt
index 87c289f..51b9aac 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBindingFactory.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBindingFactory.kt
@@ -45,10 +45,15 @@
/** Returns the [PreferenceBinding] associated with the [PreferenceMetadata]. */
fun getPreferenceBinding(metadata: PreferenceMetadata): PreferenceBinding?
+
+ companion object {
+ /** Default preference binding factory. */
+ @JvmStatic var defaultFactory: PreferenceBindingFactory = DefaultPreferenceBindingFactory()
+ }
}
/** Default [PreferenceBindingFactory]. */
-object DefaultPreferenceBindingFactory : PreferenceBindingFactory {
+open class DefaultPreferenceBindingFactory : PreferenceBindingFactory {
override fun getPreferenceBinding(metadata: PreferenceMetadata) =
metadata as? PreferenceBinding
@@ -66,5 +71,6 @@
PreferenceBindingFactory {
override fun getPreferenceBinding(metadata: PreferenceMetadata) =
- bindings[metadata.key] ?: DefaultPreferenceBindingFactory.getPreferenceBinding(metadata)
+ bindings[metadata.key]
+ ?: PreferenceBindingFactory.defaultFactory.getPreferenceBinding(metadata)
}
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt
index 5f4b88f..41a626f 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt
@@ -21,16 +21,16 @@
import android.os.Bundle
import android.util.Log
import androidx.annotation.XmlRes
-import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceScreen
import com.android.settingslib.metadata.EXTRA_BINDING_SCREEN_KEY
import com.android.settingslib.metadata.PreferenceScreenBindingKeyProvider
import com.android.settingslib.metadata.PreferenceScreenRegistry
import com.android.settingslib.preference.PreferenceScreenBindingHelper.Companion.bindRecursively
+import com.android.settingslib.widget.SettingsBasePreferenceFragment
/** Fragment to display a preference screen. */
open class PreferenceFragment :
- PreferenceFragmentCompat(), PreferenceScreenProvider, PreferenceScreenBindingKeyProvider {
+ SettingsBasePreferenceFragment(), PreferenceScreenProvider, PreferenceScreenBindingKeyProvider {
private var preferenceScreenBindingHelper: PreferenceScreenBindingHelper? = null
diff --git a/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt b/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt
index f3142d0..00bad52 100644
--- a/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt
+++ b/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt
@@ -25,7 +25,7 @@
/** Creates [Preference] widget and binds with metadata. */
@VisibleForTesting
fun <P : Preference> PreferenceMetadata.createAndBindWidget(context: Context): P {
- val binding = DefaultPreferenceBindingFactory.getPreferenceBinding(this)
+ val binding = PreferenceBindingFactory.defaultFactory.getPreferenceBinding(this)!!
return (binding.createWidget(context) as P).also {
if (this is PersistentPreference<*>) {
storage(context)?.let { keyValueStore ->
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom_highlighted.xml
new file mode 100644
index 0000000..c0c0869
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_bottom_highlighted.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:colorControlHighlight">
+ <item
+ android:bottom="16dp"
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:start="?android:attr/listPreferredItemPaddingStart"
+ android:top="2dp">
+ <shape
+ android:shape="rectangle"
+ android:tint="?android:attr/colorAccent">
+ <corners
+ android:bottomLeftRadius="@dimen/settingslib_preference_corner_radius"
+ android:bottomRightRadius="@dimen/settingslib_preference_corner_radius"
+ android:topLeftRadius="4dp"
+ android:topRightRadius="4dp" />
+ <padding android:bottom="16dp" />
+ <solid android:color="#42000000" />
+ </shape>
+ </item>
+</ripple>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center_highlighted.xml
new file mode 100644
index 0000000..8099d9b
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_center_highlighted.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:colorControlHighlight">
+ <item
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:start="?android:attr/listPreferredItemPaddingStart"
+ android:top="2dp">
+ <shape
+ android:shape="rectangle"
+ android:tint="?android:attr/colorAccent">
+ <corners android:radius="4dp" />
+ <solid android:color="#42000000" />
+ </shape>
+ </item>
+</ripple>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_highlighted.xml
new file mode 100644
index 0000000..a119a4a
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_highlighted.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:colorControlHighlight">
+ <item
+ android:bottom="16dp"
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:start="?android:attr/listPreferredItemPaddingStart"
+ android:top="2dp">
+ <shape
+ android:shape="rectangle"
+ android:tint="?android:attr/colorAccent">
+ <corners android:radius="@dimen/settingslib_preference_corner_radius" />
+ <padding android:bottom="16dp" />
+ <solid android:color="#42000000" />
+ </shape>
+ </item>
+</ripple>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top_highlighted.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top_highlighted.xml
new file mode 100644
index 0000000..052eb01
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v35/settingslib_round_background_top_highlighted.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:colorControlHighlight">
+ <item
+ android:color="?android:attr/colorAccent"
+ android:end="?android:attr/listPreferredItemPaddingEnd"
+ android:start="?android:attr/listPreferredItemPaddingStart"
+ android:top="2dp">
+ <shape
+ android:shape="rectangle"
+ android:tint="?android:attr/colorAccent">
+ <corners
+ android:bottomLeftRadius="4dp"
+ android:bottomRightRadius="4dp"
+ android:topLeftRadius="@dimen/settingslib_preference_corner_radius"
+ android:topRightRadius="@dimen/settingslib_preference_corner_radius" />
+ <solid android:color="#42000000" />
+ </shape>
+ </item>
+</ripple>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt
index 535d80f..265c065 100644
--- a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt
+++ b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsBasePreferenceFragment.kt
@@ -21,7 +21,7 @@
import androidx.recyclerview.widget.RecyclerView
/** Base class for Settings to use PreferenceFragmentCompat */
-open abstract class SettingsBasePreferenceFragment : PreferenceFragmentCompat() {
+abstract class SettingsBasePreferenceFragment : PreferenceFragmentCompat() {
override fun onCreateAdapter(preferenceScreen: PreferenceScreen): RecyclerView.Adapter<*> {
if (SettingsThemeHelper.isExpressiveTheme(requireContext()))
diff --git a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsPreferenceGroupAdapter.kt b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsPreferenceGroupAdapter.kt
index 98b7f76..6a06320 100644
--- a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsPreferenceGroupAdapter.kt
+++ b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsPreferenceGroupAdapter.kt
@@ -16,8 +16,10 @@
package com.android.settingslib.widget
+import android.annotation.SuppressLint
import android.os.Handler
import android.os.Looper
+import android.util.TypedValue
import androidx.annotation.DrawableRes
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
@@ -27,12 +29,12 @@
import com.android.settingslib.widget.theme.R
/**
- * A custom adapter for displaying settings preferences in a list, handling rounded corners
- * for preference items within a group.
+ * A custom adapter for displaying settings preferences in a list, handling rounded corners for
+ * preference items within a group.
*/
-open class SettingsPreferenceGroupAdapter @JvmOverloads constructor(
- preferenceGroup: PreferenceGroup
-) : PreferenceGroupAdapter(preferenceGroup) {
+@SuppressLint("RestrictedApi")
+open class SettingsPreferenceGroupAdapter(preferenceGroup: PreferenceGroup) :
+ PreferenceGroupAdapter(preferenceGroup) {
private val mPreferenceGroup = preferenceGroup
private var mRoundCornerMappingList: ArrayList<Int> = ArrayList()
@@ -41,6 +43,7 @@
private var mGroupPaddingStart = 0
private var mNormalPaddingEnd = 0
private var mGroupPaddingEnd = 0
+ @DrawableRes private var mLegacyBackgroundRes: Int
private val mHandler = Handler(Looper.getMainLooper())
@@ -54,9 +57,17 @@
mNormalPaddingEnd =
context.resources.getDimensionPixelSize(R.dimen.settingslib_expressive_space_small1)
mGroupPaddingEnd = mNormalPaddingEnd * 2
+ val outValue = TypedValue()
+ context.theme.resolveAttribute(
+ android.R.attr.selectableItemBackground,
+ outValue,
+ true, /* resolveRefs */
+ )
+ mLegacyBackgroundRes = outValue.resourceId
updatePreferences()
}
+ @SuppressLint("RestrictedApi")
override fun onPreferenceHierarchyChange(preference: Preference) {
super.onPreferenceHierarchyChange(preference)
@@ -65,6 +76,7 @@
mHandler.post(syncRunnable)
}
+ @SuppressLint("RestrictedApi")
override fun onBindViewHolder(holder: PreferenceViewHolder, position: Int) {
super.onBindViewHolder(holder, position)
updateBackground(holder, position)
@@ -79,6 +91,7 @@
}
}
+ @SuppressLint("RestrictedApi")
private fun mappingPreferenceGroup(cornerStyles: MutableList<Int>, group: PreferenceGroup) {
cornerStyles.clear()
cornerStyles.addAll(MutableList(itemCount) { 0 })
@@ -151,20 +164,38 @@
}
}
- /** handle roundCorner background */
+ /** handle roundCorner background */
private fun updateBackground(holder: PreferenceViewHolder, position: Int) {
- @DrawableRes val backgroundRes = getRoundCornerDrawableRes(position, false /* isSelected*/)
+ val context = holder.itemView.context
+ @DrawableRes
+ val backgroundRes =
+ when (SettingsThemeHelper.isExpressiveTheme(context)) {
+ true -> getRoundCornerDrawableRes(position, isSelected = false)
+ else -> mLegacyBackgroundRes
+ }
val v = holder.itemView
- val paddingStart = if (backgroundRes == 0) mNormalPaddingStart else mGroupPaddingStart
- val paddingEnd = if (backgroundRes == 0) mNormalPaddingEnd else mGroupPaddingEnd
-
- v.setPaddingRelative(paddingStart, v.paddingTop, paddingEnd, v.paddingBottom)
+ // Update padding
+ if (SettingsThemeHelper.isExpressiveTheme(context)) {
+ val paddingStart = if (backgroundRes == 0) mNormalPaddingStart else mGroupPaddingStart
+ val paddingEnd = if (backgroundRes == 0) mNormalPaddingEnd else mGroupPaddingEnd
+ v.setPaddingRelative(paddingStart, v.paddingTop, paddingEnd, v.paddingBottom)
+ }
+ // Update background
v.setBackgroundResource(backgroundRes)
}
@DrawableRes
protected fun getRoundCornerDrawableRes(position: Int, isSelected: Boolean): Int {
+ return getRoundCornerDrawableRes(position, isSelected, false)
+ }
+
+ @DrawableRes
+ protected fun getRoundCornerDrawableRes(
+ position: Int,
+ isSelected: Boolean,
+ isHighlighted: Boolean,
+ ): Int {
val cornerType = mRoundCornerMappingList[position]
if ((cornerType and ROUND_CORNER_CENTER) == 0) {
@@ -175,24 +206,28 @@
(cornerType and ROUND_CORNER_TOP) != 0 && (cornerType and ROUND_CORNER_BOTTOM) == 0 -> {
// the first
if (isSelected) R.drawable.settingslib_round_background_top_selected
+ else if (isHighlighted) R.drawable.settingslib_round_background_top_highlighted
else R.drawable.settingslib_round_background_top
}
(cornerType and ROUND_CORNER_BOTTOM) != 0 && (cornerType and ROUND_CORNER_TOP) == 0 -> {
// the last
if (isSelected) R.drawable.settingslib_round_background_bottom_selected
+ else if (isHighlighted) R.drawable.settingslib_round_background_bottom_highlighted
else R.drawable.settingslib_round_background_bottom
}
(cornerType and ROUND_CORNER_TOP) != 0 && (cornerType and ROUND_CORNER_BOTTOM) != 0 -> {
// the only one preference
if (isSelected) R.drawable.settingslib_round_background_selected
+ else if (isHighlighted) R.drawable.settingslib_round_background_highlighted
else R.drawable.settingslib_round_background
}
else -> {
// in the center
if (isSelected) R.drawable.settingslib_round_background_center_selected
+ else if (isHighlighted) R.drawable.settingslib_round_background_center_highlighted
else R.drawable.settingslib_round_background_center
}
}
@@ -203,4 +238,4 @@
private const val ROUND_CORNER_TOP: Int = 1 shl 1
private const val ROUND_CORNER_BOTTOM: Int = 1 shl 2
}
-}
\ No newline at end of file
+}
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 09bfd83..f2d722e 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -125,7 +125,7 @@
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"الإعدادات الصوتية للوسائط"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"المكالمات الهاتفية"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"نقل الملف"</string>
- <string name="bluetooth_profile_hid" msgid="2969922922664315866">"جهاز إدخال بيانات"</string>
+ <string name="bluetooth_profile_hid" msgid="2969922922664315866">"جهاز إدخال"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"الوصول إلى الإنترنت"</string>
<string name="bluetooth_profile_pbap" msgid="2103406516858653017">"السماح بالوصول إلى جهات الاتصال وسجلّ المكالمات"</string>
<string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"سيتم استخدام المعلومات لإرسال إشعارات المكالمات وغيرها"</string>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index f6ee587..069dc04 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -156,13 +156,13 @@
<item msgid="1241278021345116816">"Optimizirano za kvalitet zvuka (990 kbps/909 kbps)"</item>
<item msgid="3523665555859696539">"Uravnotežen kvalitet zvuka i veze (660kbps/606kbps)"</item>
<item msgid="886408010459747589">"Optimizirano za kvalitet veze (330 kbps/303 kbps)"</item>
- <item msgid="3808414041654351577">"Maksimalan napor (prilagodljiva brzina prijenosa)"</item>
+ <item msgid="3808414041654351577">"Maksimalan napor (prilagodljiva brzina prenosa)"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
<item msgid="804499336721569838">"Optimizirano za kvalitet zvuka"</item>
<item msgid="7451422070435297462">"Uravnotežen kvalitet zvuka i veze"</item>
<item msgid="6173114545795428901">"Optimizirano za kvalitet veze"</item>
- <item msgid="4349908264188040530">"Maksimalan napor (prilagodljiva brzina prijenosa)"</item>
+ <item msgid="4349908264188040530">"Maksimalan napor (prilagodljiva brzina prenosa)"</item>
</string-array>
<string-array name="bluetooth_audio_active_device_summaries">
<item msgid="8019740759207729126"></item>
@@ -276,8 +276,8 @@
</string-array>
<string-array name="usb_configuration_titles">
<item msgid="3358668781763928157">"Punjenje"</item>
- <item msgid="7804797564616858506">"MTP (protokol za prijenos sadržaja medija)"</item>
- <item msgid="910925519184248772">"PTP (protokol za prijenos slika)"</item>
+ <item msgid="7804797564616858506">"MTP (protokol za prenos sadržaja medija)"</item>
+ <item msgid="910925519184248772">"PTP (protokol za prenos slika)"</item>
<item msgid="3825132913289380004">"RNDIS (USB Ethernet)"</item>
<item msgid="8828567335701536560">"Izvor zvuka"</item>
<item msgid="8688681727755534982">"MIDI"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 4d33466..72c2cbb 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -140,10 +140,10 @@
<string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Povezano s LE zvukom"</string>
<string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezano sa zvukom medija"</string>
<string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Povezano na zvuk telefona"</string>
- <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Povezano sa serverom za prijenos podataka"</string>
+ <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Povezano sa serverom za prenos podataka"</string>
<string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"Povezano na mapu"</string>
<string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"Povezan na SAP"</string>
- <string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"Nije povezano sa serverom za prijenos podataka"</string>
+ <string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"Nije povezano sa serverom za prenos podataka"</string>
<string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"Povezano s ulaznim uređajem"</string>
<string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"Povezano na uređaj za pristup internetu"</string>
<string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"Dijeljenje lokalne internetske veze s uređajem"</string>
@@ -152,7 +152,7 @@
<string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Koristi za pristup SIM-u"</string>
<string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Koristi za zvuk medija"</string>
<string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Koristi za zvuk telefona"</string>
- <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Koristi za prijenos fajlova"</string>
+ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Koristi za prenos fajlova"</string>
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Koristi kao ulaz"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="3374057355721486932">"Korištenje za slušne aparate"</string>
<string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Koristi za: LE_AUDIO"</string>
@@ -315,7 +315,7 @@
<string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"Aktivirajte Bluetooth Audio Codec\nOdabir: Način rada po kanalima"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"Bluetooth Audio LDAC kodek: kvalitet reprodukcije"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Aktivirajte Bluetooth Audio \nOdabir kodeka: kvalitet reprodukcije"</string>
- <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Prijenos: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Prenos: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Privatni DNS"</string>
<string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Odaberite način rada privatnog DNS-a"</string>
<string name="private_dns_mode_off" msgid="7065962499349997041">"Isključeno"</string>
@@ -719,7 +719,7 @@
<string name="accessibility_data_one_bar" msgid="6892888138070752480">"Prijenos podataka na jednoj crtici."</string>
<string name="accessibility_data_two_bars" msgid="9202641507241802499">"Prijenos podataka na dvije crtice."</string>
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Prijenos podataka na tri crtice."</string>
- <string name="accessibility_data_signal_full" msgid="1808301899314382337">"Signal za prijenos podataka pun."</string>
+ <string name="accessibility_data_signal_full" msgid="1808301899314382337">"Signal za prenos podataka pun."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Veza sa Ethernetom je prekinuta."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
<string name="accessibility_no_calling" msgid="3540827068323895748">"Nema pozivanja."</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 2aa3ffa..4365358 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -329,7 +329,7 @@
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Quan aquest mode està activat, és possible que l’adreça MAC d\'aquest dispositiu canviï cada vegada que es connecti a una xarxa amb l\'aleatorització d\'adreces MAC activada"</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"D\'ús mesurat"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"D\'ús no mesurat"</string>
- <string name="select_logd_size_title" msgid="1604578195914595173">"Mides de la memòria intermèdia del registre"</string>
+ <string name="select_logd_size_title" msgid="1604578195914595173">"Mides de la memòria cau del registre"</string>
<string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Selecciona la mida de la memòria intermèdia del registre"</string>
<string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"Vols esborrar l\'emmagatzematge persistent del registrador?"</string>
<string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Quan deixem de supervisar amb el registrador persistent, hem d\'esborrar les dades del registrador que hi ha al teu dispositiu."</string>
@@ -579,7 +579,7 @@
<string name="alarm_template_far" msgid="6382760514842998629">"Data: <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durada"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pregunta sempre"</string>
- <string name="zen_mode_forever" msgid="3339224497605461291">"Fins que no el desactivis"</string>
+ <string name="zen_mode_forever" msgid="3339224497605461291">"Fins que no ho desactivis"</string>
<string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sense nom)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"Ara mateix"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Aquest telèfon"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 94502c5..bafa654 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -475,7 +475,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalía (rojo-verde)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalía (azul-amarillo)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Corrección de color"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Corrección de color puede ser útil si quieres:<br/> <ol> <li>&nbsp;Ver los colores mejor</li> <li>&nbsp;Quitar los colores para concentrarte mejor</li> </ol>"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Corrección de color puede ser útil si quieres:<br/> <ol> <li>&nbsp;Ver los colores mejor</li> <li>&nbsp;Quitar colores para concentrarte mejor</li> </ol>"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>: <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga pausada para proteger la batería"</string>
@@ -490,7 +490,7 @@
<string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Debería durar hasta las <xliff:g id="TIME">%1$s</xliff:g> basado en tu uso"</string>
<string name="power_discharge_by" msgid="4113180890060388350">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar hasta las <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta las <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Puede que se agote la batería sobre las <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 30eba9e..1e4bbc4 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -606,7 +606,7 @@
<string name="tv_media_transfer_default" msgid="5403053145185843843">"Sortie audio par défaut de la télévision"</string>
<string name="tv_media_transfer_hdmi" msgid="692569220956829921">"Sortie HDMI"</string>
<string name="tv_media_transfer_internal_speakers" msgid="8181494402866565865">"Haut-parleurs internes"</string>
- <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteingez et rallumez l\'appareil"</string>
+ <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez et rallumez l\'appareil"</string>
<string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio à câble"</string>
<string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
<string name="storage_category" msgid="2287342585424631813">"Stockage"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 45c41dd..5f63ed3 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -577,8 +577,8 @@
<string name="zen_alarm_warning" msgid="245729928048586280">"לא תושמע ההתראה הבאה <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template" msgid="3346777418136233330">"בשעה <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="6382760514842998629">"ב-<xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"משך זמן"</string>
- <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"יש לשאול בכל פעם"</string>
+ <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"כמה זמן"</string>
+ <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"אני רוצה לבחור בכל פעם"</string>
<string name="zen_mode_forever" msgid="3339224497605461291">"עד הכיבוי"</string>
<string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ללא שם)"</string>
<string name="time_unit_just_now" msgid="3006134267292728099">"הרגע"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 5a184c5..e6935d0 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -475,7 +475,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ខ្វាក់ពណ៌ក្រហម (ក្រហមបៃតង)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ខ្វាក់ពណ៌ខៀវ (ខៀវលឿង)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ការកែតម្រូវពណ៌"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ការកែតម្រូវពណ៌អាចមានប្រយោជន៍ នៅពេលអ្នកចង់៖<br/> <ol> <li>&nbsp;មើលពណ៌កាន់តែត្រឹមត្រូវ</li> <li>&nbsp;លុបពណ៌ចេញ ដើម្បីជួយឱ្យអ្នកផ្ដោតអារម្មណ៍</li> </ol>"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ការកែតម្រូវពណ៌អាចមានប្រយោជន៍ នៅពេលអ្នកចង់៖<br/> <ol> <li>&nbsp;មើលពណ៌កាន់តែត្រឹមត្រូវ</li> <li>&nbsp;ដកពណ៌ចេញ ដើម្បីជួយឱ្យអ្នកផ្ដោតអារម្មណ៍</li> </ol>"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"បដិសេធដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - កំពុងផ្អាកការសាកថ្ម ដើម្បីការពារថ្ម"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index d803404..1e51ae6 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -94,7 +94,7 @@
<string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"연결됨(전화 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"연결됨(미디어 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"연결됨(전화 또는 미디어 없음), 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"사용 중입니다. 배터리는 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>입니다."</string>
+ <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"사용 중. 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"사용 중입니다. 배터리는 왼쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, 오른쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>입니다."</string>
<string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"활성 상태입니다. 왼쪽: 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"활성 상태입니다. 오른쪽: 배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -490,7 +490,7 @@
<string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"사용량을 기준으로 약 <xliff:g id="TIME">%1$s</xliff:g>까지 사용 가능"</string>
<string name="power_discharge_by" msgid="4113180890060388350">"대략 <xliff:g id="TIME">%1$s</xliff:g>까지 사용 가능(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"대략 <xliff:g id="TIME">%1$s</xliff:g>까지 사용 가능"</string>
- <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g>까지"</string>
+ <string name="power_discharge_by_only_short" msgid="5883041507426914446">"<xliff:g id="TIME">%1$s</xliff:g>까지 사용 가능"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"예상 배터리 종료 시간: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> 미만 남음(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 9bb30c7..2ced73b 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -475,7 +475,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (အနီ-အစိမ်း)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (အပြာ-အဝါ)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"အရောင် အမှန်ပြင်ခြင်း"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"အရောင် အမှန်ပြင်ခြင်းသည် အောက်ပါတို့အတွက် အသုံးဝင်နိုင်သည်-<br/> <ol> <li>&nbsp;အရောင်များကို ပိုမိုမှန်ကန်စွာ ကြည့်ရှုခြင်း</li> <li>&nbsp;အာရုံစိုက်နိုင်ရန် အရောင်များ ဖယ်ရှားခြင်း</li> </ol>"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"အရောင် အမှန်ပြင်ခြင်းသည် အောက်ပါတို့အတွက် အသုံးဝင်နိုင်သည်-<br/> <ol> <li>&nbsp;အရောင်များကို ပိုမိုမှန်ကန်စွာ ကြည့်ရှုရန်</li> <li>&nbsp;အာရုံစိုက်နိုင်ရန် အရောင်များ ဖယ်ရှားရန်</li> </ol>"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ဘက်ထရီကာကွယ်ရန် အားသွင်းခြင်းကို ခဏရပ်ထားသည်"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 1abe67a..91648df 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -125,7 +125,7 @@
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Профиль A2DP"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"Звонки"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"Профиль OPP"</string>
- <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Профиль HID"</string>
+ <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Устройство ввода"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Доступ к интернету"</string>
<string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Разрешить доступ к контактам и журналу звонков"</string>
<string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Эти сведения нужны для оповещений о звонках и других функций"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 4c41b7d..8fc99cf 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -475,7 +475,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomália (červená a zelená)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomália (modrá a žltá)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Úprava farieb"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Úprava farieb môže byť užitočná, keď chcete:<br/> <ol> <li>&nbsp;zobrazovať farby presnejšie;</li> <li>&nbsp;odstrániť farby, aby ste sa mohli sústrediť.</li> </ol>"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Úprava farieb môže byť užitočná, keď chcete:<br/> <ol> <li>&nbsp;vidieť farby presnejšie;</li> <li>&nbsp;odstrániť farby, aby ste sa mohli sústrediť.</li> </ol>"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – nabíjanie je pozastavené, aby sa chránila batéria"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 820fcc8..599113c 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -237,7 +237,7 @@
<string name="choose_profile" msgid="343803890897657450">"Chagua wasifu"</string>
<string name="category_personal" msgid="6236798763159385225">"Binafsi"</string>
<string name="category_work" msgid="4014193632325996115">"Kazini"</string>
- <string name="category_private" msgid="4244892185452788977">"Faragha"</string>
+ <string name="category_private" msgid="4244892185452788977">"Sehemu ya Faragha"</string>
<string name="category_clone" msgid="1554511758987195974">"Kloni"</string>
<string name="development_settings_title" msgid="140296922921597393">"Chaguo za wasanidi"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Washa chaguo za wasanidi programu"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index d6ec1ca..c8666ff 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -475,7 +475,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"紅色弱視 (紅綠)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"藍色弱視 (藍黃)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"色彩校正"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"「色彩校正」功能適用於以下情況::<br/> <ol> <li>&nbsp;你想讓裝置顯示更準確的色彩</li> <li>&nbsp;你想移除色彩以提高專注力</li> </ol>"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"「色彩校正」功能適用於以下情況:<br/> <ol> <li>&nbsp;你想讓裝置顯示更準確的色彩</li> <li>&nbsp;你想移除色彩以提高專注力</li> </ol>"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - 為保護電池,目前暫停充電"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index fd2a1cb..bc144d6 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1426,6 +1426,12 @@
<string name="media_transfer_default_device_name">Connected device</string>
<!-- Name of the phone device with an active remote session. [CHAR LIMIT=30] -->
<string name="media_transfer_this_phone">This phone</string>
+ <!-- Name of the digital audio output, i.e. S/PDIF, usually optical. [CHAR LIMIT=30] -->
+ <string name="media_transfer_digital_line_name">S/PDIF</string>
+ <!-- Name of the analog audio output. [CHAR LIMIT=30] -->
+ <string name="media_transfer_analog_line_name">Analog</string>
+ <!-- Name of the AUX audio output. [CHAR LIMIT=30] -->
+ <string name="media_transfer_aux_line_name">AUX</string>
<!-- Sub status indicates device is not available due to an unknown error. [CHAR LIMIT=NONE] -->
<string name="media_output_status_unknown_error">Can\’t play on this device</string>
<!-- Sub status indicates device need premium account. [CHAR LIMIT=NONE] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedDropDownPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedDropDownPreference.java
index 6578eb7..c36ade9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedDropDownPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedDropDownPreference.java
@@ -22,14 +22,20 @@
import androidx.preference.DropDownPreference;
import androidx.preference.PreferenceViewHolder;
-public class RestrictedDropDownPreference extends DropDownPreference {
- RestrictedPreferenceHelper mHelper;
+public class RestrictedDropDownPreference extends DropDownPreference implements
+ RestrictedPreferenceHelperProvider {
+ private final RestrictedPreferenceHelper mHelper;
public RestrictedDropDownPreference(@NonNull Context context) {
super(context);
mHelper = new RestrictedPreferenceHelper(context, this, null);
}
+ @Override
+ public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
+ return mHelper;
+ }
+
/**
* Checks if the given setting is subject to Enhanced Confirmation Mode restrictions for this
* package. Marks the preference as disabled if so.
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedInterface.kt b/packages/SettingsLib/src/com/android/settingslib/RestrictedInterface.kt
deleted file mode 100644
index 14f9a19..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedInterface.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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
-
-import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
-
-interface RestrictedInterface {
- fun useAdminDisabledSummary(useSummary: Boolean)
-
- fun checkRestrictionAndSetDisabled(userRestriction: String)
-
- fun checkRestrictionAndSetDisabled(userRestriction: String, userId: Int)
-
- /**
- * Checks if the given setting is subject to Enhanced Confirmation Mode restrictions for this
- * package. Marks the preference as disabled if so.
- *
- * @param settingIdentifier The key identifying the setting
- * @param packageName the package to check the settingIdentifier for
- */
- fun checkEcmRestrictionAndSetDisabled(
- settingIdentifier: String,
- packageName: String
- )
-
- val isDisabledByAdmin: Boolean
-
- fun setDisabledByAdmin(admin: EnforcedAdmin?)
-
- val isDisabledByEcm: Boolean
-
- val uid: Int
-
- val packageName: String?
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
index 495410b..332042a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
@@ -34,7 +34,9 @@
* Preference class that supports being disabled by a user restriction
* set by a device admin.
*/
-public class RestrictedPreference extends TwoTargetPreference {
+public class RestrictedPreference extends TwoTargetPreference implements
+ RestrictedPreferenceHelperProvider {
+
RestrictedPreferenceHelper mHelper;
public RestrictedPreference(Context context, AttributeSet attrs,
@@ -67,6 +69,11 @@
}
@Override
+ public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
+ return mHelper;
+ }
+
+ @Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelperProvider.kt
similarity index 68%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelperProvider.kt
index e21bf8f..f286084 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelperProvider.kt
@@ -14,6 +14,11 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package com.android.settingslib
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+/** Provider of [RestrictedPreferenceHelper]. */
+interface RestrictedPreferenceHelperProvider {
+
+ /** Returns the [RestrictedPreferenceHelper] applied to the preference. */
+ fun getRestrictedPreferenceHelper(): RestrictedPreferenceHelper
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSelectorWithWidgetPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSelectorWithWidgetPreference.java
index c52c7ea..573869d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSelectorWithWidgetPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSelectorWithWidgetPreference.java
@@ -32,8 +32,9 @@
/**
* Selector with widget preference that can be disabled by a device admin using a user restriction.
*/
-public class RestrictedSelectorWithWidgetPreference extends SelectorWithWidgetPreference {
- private RestrictedPreferenceHelper mHelper;
+public class RestrictedSelectorWithWidgetPreference extends SelectorWithWidgetPreference implements
+ RestrictedPreferenceHelperProvider {
+ private final RestrictedPreferenceHelper mHelper;
/**
* Perform inflation from XML and apply a class-specific base style.
@@ -82,8 +83,11 @@
*/
public RestrictedSelectorWithWidgetPreference(@NonNull Context context) {
this(context, null);
- mHelper =
- new RestrictedPreferenceHelper(context, /* preference= */ this, /* attrs= */ null);
+ }
+
+ @Override
+ public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
+ return mHelper;
}
@Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSliderPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSliderPreference.java
index 1dc5281..b690816 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSliderPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSliderPreference.java
@@ -19,7 +19,6 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Process;
-import android.os.UserHandle;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
@@ -34,8 +33,10 @@
* Slide Preference that supports being disabled by a user restriction
* set by a device admin.
*/
-public class RestrictedSliderPreference extends SliderPreference implements RestrictedInterface {
- RestrictedPreferenceHelper mHelper;
+public class RestrictedSliderPreference extends SliderPreference implements
+ RestrictedPreferenceHelperProvider {
+
+ private final RestrictedPreferenceHelper mHelper;
public RestrictedSliderPreference(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr, @Nullable String packageName, int uid) {
@@ -66,6 +67,11 @@
}
@Override
+ public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
+ return mHelper;
+ }
+
+ @Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
@@ -81,12 +87,12 @@
@Override
public void setEnabled(boolean enabled) {
- if (enabled && isDisabledByAdmin()) {
+ if (enabled && mHelper.isDisabledByAdmin()) {
mHelper.setDisabledByAdmin(null);
return;
}
- if (enabled && isDisabledByEcm()) {
+ if (enabled && mHelper.isDisabledByEcm()) {
mHelper.setDisabledByEcm(null);
return;
}
@@ -95,55 +101,6 @@
}
@Override
- public void useAdminDisabledSummary(boolean useSummary) {
- mHelper.useAdminDisabledSummary(useSummary);
- }
-
- @Override
- public void checkRestrictionAndSetDisabled(@NonNull String userRestriction) {
- mHelper.checkRestrictionAndSetDisabled(userRestriction, UserHandle.myUserId());
- }
-
- @Override
- public void checkRestrictionAndSetDisabled(@NonNull String userRestriction, int userId) {
- mHelper.checkRestrictionAndSetDisabled(userRestriction, userId);
- }
-
- @Override
- public void checkEcmRestrictionAndSetDisabled(@NonNull String settingIdentifier,
- @NonNull String packageName) {
- mHelper.checkEcmRestrictionAndSetDisabled(settingIdentifier, packageName);
- }
-
- @Override
- public void setDisabledByAdmin(@Nullable RestrictedLockUtils.EnforcedAdmin admin) {
- if (mHelper.setDisabledByAdmin(admin)) {
- notifyChanged();
- }
- }
-
- @Override
- public boolean isDisabledByAdmin() {
- return mHelper.isDisabledByAdmin();
- }
-
- @Override
- public boolean isDisabledByEcm() {
- return mHelper.isDisabledByEcm();
- }
-
- @Override
- public int getUid() {
- return mHelper != null ? mHelper.uid : Process.INVALID_UID;
- }
-
- @Override
- @Nullable
- public String getPackageName() {
- return mHelper != null ? mHelper.packageName : null;
- }
-
- @Override
protected void onAttachedToHierarchy(@NonNull PreferenceManager preferenceManager) {
mHelper.onAttachedToHierarchy();
super.onAttachedToHierarchy(preferenceManager);
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index fffbb54..727dbe1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -45,8 +45,9 @@
* Version of SwitchPreferenceCompat that can be disabled by a device admin
* using a user restriction.
*/
-public class RestrictedSwitchPreference extends SwitchPreferenceCompat {
- RestrictedPreferenceHelper mHelper;
+public class RestrictedSwitchPreference extends SwitchPreferenceCompat implements
+ RestrictedPreferenceHelperProvider {
+ private final RestrictedPreferenceHelper mHelper;
AppOpsManager mAppOpsManager;
boolean mUseAdditionalSummary = false;
CharSequence mRestrictedSwitchSummary;
@@ -98,6 +99,11 @@
this(context, null);
}
+ @Override
+ public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
+ return mHelper;
+ }
+
@VisibleForTesting
public void setAppOps(AppOpsManager appOps) {
mAppOpsManager = appOps;
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedTopLevelPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedTopLevelPreference.java
index 0096015..34e4d8f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedTopLevelPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedTopLevelPreference.java
@@ -22,14 +22,16 @@
import android.os.UserHandle;
import android.util.AttributeSet;
+import androidx.annotation.NonNull;
import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceViewHolder;
/** Top level preference that can be disabled by a device admin using a user restriction. */
-public class RestrictedTopLevelPreference extends Preference {
- private RestrictedPreferenceHelper mHelper;
+public class RestrictedTopLevelPreference extends Preference implements
+ RestrictedPreferenceHelperProvider {
+ private final RestrictedPreferenceHelper mHelper;
public RestrictedTopLevelPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
@@ -51,6 +53,11 @@
}
@Override
+ public @NonNull RestrictedPreferenceHelper getRestrictedPreferenceHelper() {
+ return mHelper;
+ }
+
+ @Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 4e1d8e3..ad196b8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -15,6 +15,9 @@
*/
package com.android.settingslib.media;
+import static android.media.MediaRoute2Info.TYPE_AUX_LINE;
+import static android.media.MediaRoute2Info.TYPE_LINE_ANALOG;
+import static android.media.MediaRoute2Info.TYPE_LINE_DIGITAL;
import static android.media.MediaRoute2Info.TYPE_BLE_HEADSET;
import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
@@ -700,6 +703,9 @@
case TYPE_HDMI:
case TYPE_HDMI_ARC:
case TYPE_HDMI_EARC:
+ case TYPE_LINE_DIGITAL:
+ case TYPE_LINE_ANALOG:
+ case TYPE_AUX_LINE:
case TYPE_WIRED_HEADSET:
case TYPE_WIRED_HEADPHONES:
mediaDevice =
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
index 4f315a2..76aa5bf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
@@ -75,6 +75,24 @@
@Override
public void onAudioDevicesAdded(@NonNull AudioDeviceInfo[] addedDevices) {
applyDefaultSelectedTypeToAllPresets();
+
+ // Activate the last hot plugged valid input device, to match the output device
+ // behavior.
+ @AudioDeviceType int deviceTypeToActivate = mSelectedInputDeviceType;
+ for (AudioDeviceInfo info : addedDevices) {
+ if (InputMediaDevice.isSupportedInputDevice(info.getType())) {
+ deviceTypeToActivate = info.getType();
+ }
+ }
+
+ // Only activate if we find a different valid input device. e.g. if none of the
+ // addedDevices is supported input device, we don't need to activate anything.
+ if (mSelectedInputDeviceType != deviceTypeToActivate) {
+ mSelectedInputDeviceType = deviceTypeToActivate;
+ AudioDeviceAttributes deviceAttributes =
+ createInputDeviceAttributes(mSelectedInputDeviceType);
+ setPreferredDeviceForAllPresets(deviceAttributes);
+ }
}
@Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index ce1f297..2321097 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -33,6 +33,9 @@
import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
+import static android.media.MediaRoute2Info.TYPE_LINE_DIGITAL;
+import static android.media.MediaRoute2Info.TYPE_LINE_ANALOG;
+import static android.media.MediaRoute2Info.TYPE_AUX_LINE;
import static android.media.RouteListingPreference.Item.FLAG_ONGOING_SESSION;
import static android.media.RouteListingPreference.Item.FLAG_ONGOING_SESSION_MANAGED;
import static android.media.RouteListingPreference.Item.FLAG_SUGGESTED;
@@ -150,6 +153,9 @@
break;
case TYPE_WIRED_HEADSET:
case TYPE_WIRED_HEADPHONES:
+ case TYPE_LINE_DIGITAL:
+ case TYPE_LINE_ANALOG:
+ case TYPE_AUX_LINE:
mType = MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE;
break;
case TYPE_USB_DEVICE:
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index 481306a..4766a86 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -26,7 +26,9 @@
import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
-
+import static android.media.MediaRoute2Info.TYPE_LINE_DIGITAL;
+import static android.media.MediaRoute2Info.TYPE_LINE_ANALOG;
+import static android.media.MediaRoute2Info.TYPE_AUX_LINE;
import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER;
import android.Manifest;
@@ -124,6 +126,15 @@
name = context.getString(R.string.media_transfer_external_device_name);
}
break;
+ case TYPE_LINE_DIGITAL:
+ name = context.getString(R.string.media_transfer_digital_line_name);
+ break;
+ case TYPE_LINE_ANALOG:
+ name = context.getString(R.string.media_transfer_analog_line_name);
+ break;
+ case TYPE_AUX_LINE:
+ name = context.getString(R.string.media_transfer_aux_line_name);
+ break;
default:
name = context.getString(R.string.media_transfer_default_device_name);
break;
@@ -268,6 +279,9 @@
switch (mRouteInfo.getType()) {
case TYPE_WIRED_HEADSET:
case TYPE_WIRED_HEADPHONES:
+ case TYPE_LINE_ANALOG:
+ case TYPE_LINE_DIGITAL:
+ case TYPE_AUX_LINE:
id = WIRED_HEADSET_ID;
break;
case TYPE_USB_DEVICE:
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconKeys.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconKeys.java
index 79dabf0..5d2a166 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconKeys.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconKeys.java
@@ -41,7 +41,7 @@
private static final ImmutableMap<Integer, ZenIcon.Key> TYPE_DEFAULTS = ImmutableMap.of(
AutomaticZenRule.TYPE_UNKNOWN,
- ZenIcon.Key.forSystemResource(R.drawable.ic_zen_mode_type_unknown),
+ ZenIcon.Key.forSystemResource(R.drawable.ic_zen_mode_type_special_dnd),
AutomaticZenRule.TYPE_OTHER,
ZenIcon.Key.forSystemResource(R.drawable.ic_zen_mode_type_other),
AutomaticZenRule.TYPE_SCHEDULE_TIME,
@@ -61,7 +61,7 @@
);
private static final ZenIcon.Key FOR_UNEXPECTED_TYPE =
- ZenIcon.Key.forSystemResource(R.drawable.ic_zen_mode_type_unknown);
+ ZenIcon.Key.forSystemResource(R.drawable.ic_zen_mode_type_special_dnd);
/** Default icon descriptors per mode {@link AutomaticZenRule.Type}. */
static ZenIcon.Key forType(@AutomaticZenRule.Type int ruleType) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
index 782cee2..d808a25 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -138,6 +139,18 @@
/* address= */ "");
}
+ private AudioDeviceAttributes getUsbHeadsetDeviceAttributes() {
+ return new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_INPUT,
+ AudioDeviceInfo.TYPE_USB_HEADSET,
+ /* address= */ "");
+ }
+
+ private AudioDeviceAttributes getHdmiDeviceAttributes() {
+ return new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_INPUT, AudioDeviceInfo.TYPE_HDMI, /* address= */ "");
+ }
+
private void onPreferredDevicesForCapturePresetChanged(InputRouteManager inputRouteManager) {
final List<AudioDeviceAttributes> audioDeviceAttributesList =
new ArrayList<AudioDeviceAttributes>();
@@ -303,21 +316,47 @@
}
@Test
- public void onAudioDevicesAdded_shouldApplyDefaultSelectedDeviceToAllPresets() {
+ public void onAudioDevicesAdded_shouldActivateAddedDevice() {
final AudioManager audioManager = mock(AudioManager.class);
- AudioDeviceAttributes wiredHeadsetDeviceAttributes = getWiredHeadsetDeviceAttributes();
- when(audioManager.getDevicesForAttributes(INPUT_ATTRIBUTES))
- .thenReturn(Collections.singletonList(wiredHeadsetDeviceAttributes));
-
InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
AudioDeviceInfo[] devices = {mockWiredHeadsetInfo()};
inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices);
- // Called twice, one after initiation, the other after onAudioDevicesAdded call.
- verify(audioManager, atLeast(2)).getDevicesForAttributes(INPUT_ATTRIBUTES);
+ // The only added wired headset will be activated.
for (@MediaRecorder.Source int preset : PRESETS) {
- verify(audioManager, atLeast(2))
- .setPreferredDeviceForCapturePreset(preset, wiredHeadsetDeviceAttributes);
+ verify(audioManager, atLeast(1))
+ .setPreferredDeviceForCapturePreset(preset, getWiredHeadsetDeviceAttributes());
+ }
+ }
+
+ @Test
+ public void onAudioDevicesAdded_shouldActivateLastAddedDevice() {
+ final AudioManager audioManager = mock(AudioManager.class);
+ InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
+ AudioDeviceInfo[] devices = {mockWiredHeadsetInfo(), mockUsbHeadsetInfo()};
+ inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices);
+
+ // When adding multiple valid input devices, the last added device (usb headset in this
+ // case) will be activated.
+ for (@MediaRecorder.Source int preset : PRESETS) {
+ verify(audioManager, never())
+ .setPreferredDeviceForCapturePreset(preset, getWiredHeadsetDeviceAttributes());
+ verify(audioManager, atLeast(1))
+ .setPreferredDeviceForCapturePreset(preset, getUsbHeadsetDeviceAttributes());
+ }
+ }
+
+ @Test
+ public void onAudioDevicesAdded_doNotActivateInvalidAddedDevice() {
+ final AudioManager audioManager = mock(AudioManager.class);
+ InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
+ AudioDeviceInfo[] devices = {mockHdmiInfo()};
+ inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices);
+
+ // Do not activate since HDMI is not a valid input device.
+ for (@MediaRecorder.Source int preset : PRESETS) {
+ verify(audioManager, never())
+ .setPreferredDeviceForCapturePreset(preset, getHdmiDeviceAttributes());
}
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 1919572..24b91f9 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -263,6 +263,8 @@
<uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_VIBRATOR_STATE" />
+ <uses-permission android:name="android.permission.VIBRATE_VENDOR_EFFECTS" />
+ <uses-permission android:name="android.permission.START_VIBRATION_SESSIONS" />
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />
<uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" />
<uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />
@@ -715,6 +717,9 @@
<uses-permission android:name="android.permission.UWB_PRIVILEGED" />
<uses-permission android:name="android.permission.UWB_RANGING" />
+ <!-- Permission required for CTS test - CtsRangingTestCases -->
+ <uses-permission android:name="android.permission.RANGING" />
+
<!-- Permission required for CTS test - CtsAlarmManagerTestCases -->
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index f0e1b43..e011736 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -1013,6 +1013,7 @@
android:autoRemoveFromRecents="true"
android:launchMode="singleTop"
android:showForAllUsers="true"
+ android:turnScreenOn="true"
android:exported="false">
</activity>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING b/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING
index 1820f39..1903d22 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING
+++ b/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING
@@ -1,8 +1,7 @@
{
- // TODO: b/324945360 - Re-enable on presubmit after fixing failures
"postsubmit": [
{
"name": "AccessibilityMenuServiceTests"
}
]
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-uk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-uk/strings.xml
index ee02b4a..ba38023 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-uk/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-uk/strings.xml
@@ -21,7 +21,7 @@
<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_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>
diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig
index 5251246..b5eba08 100644
--- a/packages/SystemUI/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/aconfig/accessibility.aconfig
@@ -118,3 +118,10 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "floating_menu_hearing_device_status_icon"
+ namespace: "accessibility"
+ description: "Update hearing device icon in floating menu according to the connection status."
+ bug: "357882387"
+}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 0938167..5eae6d3 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -26,6 +26,16 @@
}
flag {
+ name: "user_encrypted_source"
+ namespace: "systemui"
+ description: "Get rid of the local cache and rely on UserManager.isUserUnlocked directly to determine whether user CE storage is encrypted."
+ bug: "333656491"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "modes_ui_dialog_paging"
namespace: "systemui"
description: "Add pagination to the Modes dialog in quick settings."
@@ -404,6 +414,17 @@
}
flag {
+ name: "status_bar_auto_start_screen_record_chip"
+ namespace: "systemui"
+ description: "When screen recording, use the specified start time to update the screen record "
+ "chip state instead of waiting for an official 'recording started' signal"
+ bug: "366448907"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "status_bar_use_repos_for_call_chip"
namespace: "systemui"
description: "Use repositories as the source of truth for call notifications shown as a chip in"
@@ -1578,6 +1599,13 @@
}
flag {
+ name: "show_clipboard_indication"
+ namespace: "systemui"
+ description: "Show indication text under the clipboard overlay when copied something"
+ bug: "361199935"
+}
+
+flag {
name: "media_projection_dialog_behind_lockscreen"
namespace: "systemui"
description: "Ensure MediaProjection Dialog appears behind the lockscreen"
@@ -1659,6 +1687,16 @@
}
flag {
+ name: "show_toast_when_app_control_brightness"
+ namespace: "systemui"
+ description: "Showing the warning toast if the current running app window has controlled the brightness value."
+ bug: "363225340"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "home_controls_dream_hsum"
namespace: "systemui"
description: "Enables the home controls dream in HSUM"
@@ -1728,8 +1766,11 @@
}
flag {
- name: "touchpad_three_finger_tap_customization"
- namespace: "systemui"
- description: "Customize touchpad three finger tap"
- bug: "365063048"
+ name: "stoppable_fgs_system_app"
+ namespace: "systemui"
+ description: "System app with foreground service can opt in to be stoppable."
+ bug: "376564917"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java
index 0b15d23..cbe11a3 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java
@@ -268,7 +268,8 @@
// skip changes that we didn't wrap
if (!leashMap.containsKey(change.getLeash())) continue;
// Only make the update if we are closing Desktop tasks.
- if (change.getTaskInfo().isFreeform() && isClosingMode(change.getMode())) {
+ if (change.getTaskInfo() != null && change.getTaskInfo().isFreeform()
+ && isClosingMode(change.getMode())) {
startTransaction.setAlpha(leashMap.get(launcherChange.getLeash()), 0f);
return;
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
index 4cf2642..fdb4871 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
@@ -20,6 +20,7 @@
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
+import android.graphics.PointF
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.drawable.GradientDrawable
@@ -33,13 +34,13 @@
import android.view.animation.Interpolator
import android.window.WindowAnimationState
import com.android.app.animation.Interpolators.LINEAR
-import com.android.app.animation.MathUtils.max
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.dynamicanimation.animation.SpringAnimation
import com.android.internal.dynamicanimation.animation.SpringForce
import com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary
import java.util.concurrent.Executor
import kotlin.math.abs
+import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt
@@ -91,6 +92,14 @@
)
}
+ /**
+ * Similar to [getProgress] above, bug the delay and duration are expressed as percentages
+ * of the animation duration (between 0f and 1f).
+ */
+ internal fun getProgress(linearProgress: Float, delay: Float, duration: Float): Float {
+ return getProgressInternal(totalDuration = 1f, linearProgress, delay, duration)
+ }
+
private fun getProgressInternal(
totalDuration: Float,
linearProgress: Float,
@@ -262,10 +271,10 @@
var centerY: Float,
var scale: Float = 0f,
- // Cached values.
- var previousCenterX: Float = -1f,
- var previousCenterY: Float = -1f,
- var previousScale: Float = -1f,
+ // Update flags (used to decide whether it's time to update the transition state).
+ var isCenterXUpdated: Boolean = false,
+ var isCenterYUpdated: Boolean = false,
+ var isScaleUpdated: Boolean = false,
// Completion flags.
var isCenterXDone: Boolean = false,
@@ -286,6 +295,7 @@
override fun setValue(state: SpringState, value: Float) {
state.centerX = value
+ state.isCenterXUpdated = true
}
},
CENTER_Y {
@@ -295,6 +305,7 @@
override fun setValue(state: SpringState, value: Float) {
state.centerY = value
+ state.isCenterYUpdated = true
}
},
SCALE {
@@ -304,6 +315,7 @@
override fun setValue(state: SpringState, value: Float) {
state.scale = value
+ state.isScaleUpdated = true
}
};
@@ -444,8 +456,8 @@
* punching a hole in the [transition container][Controller.transitionContainer]) iff [drawHole]
* is true.
*
- * If [useSpring] is true, a multi-spring animation will be used instead of the default
- * interpolators.
+ * If [startVelocity] (expressed in pixels per second) is not null, a multi-spring animation
+ * using it for the initial momentum will be used instead of the default interpolators.
*/
fun startAnimation(
controller: Controller,
@@ -453,9 +465,9 @@
windowBackgroundColor: Int,
fadeWindowBackgroundLayer: Boolean = true,
drawHole: Boolean = false,
- useSpring: Boolean = false,
+ startVelocity: PointF? = null,
): Animation {
- if (!controller.isLaunching || useSpring) checkReturnAnimationFrameworkFlag()
+ if (!controller.isLaunching || startVelocity != null) checkReturnAnimationFrameworkFlag()
// We add an extra layer with the same color as the dialog/app splash screen background
// color, which is usually the same color of the app background. We first fade in this layer
@@ -474,7 +486,7 @@
windowBackgroundLayer,
fadeWindowBackgroundLayer,
drawHole,
- useSpring,
+ startVelocity,
)
.apply { start() }
}
@@ -487,7 +499,7 @@
windowBackgroundLayer: GradientDrawable,
fadeWindowBackgroundLayer: Boolean = true,
drawHole: Boolean = false,
- useSpring: Boolean = false,
+ startVelocity: PointF? = null,
): Animation {
val transitionContainer = controller.transitionContainer
val transitionContainerOverlay = transitionContainer.overlay
@@ -504,11 +516,12 @@
openingWindowSyncView != null &&
openingWindowSyncView.viewRootImpl != controller.transitionContainer.viewRootImpl
- return if (useSpring && springTimings != null && springInterpolators != null) {
+ return if (startVelocity != null && springTimings != null && springInterpolators != null) {
createSpringAnimation(
controller,
startState,
endState,
+ startVelocity,
windowBackgroundLayer,
transitionContainer,
transitionContainerOverlay,
@@ -693,6 +706,7 @@
controller: Controller,
startState: State,
endState: State,
+ startVelocity: PointF,
windowBackgroundLayer: GradientDrawable,
transitionContainer: View,
transitionContainerOverlay: ViewGroupOverlay,
@@ -721,19 +735,20 @@
fun updateProgress(state: SpringState) {
if (
- (!state.isCenterXDone && state.centerX == state.previousCenterX) ||
- (!state.isCenterYDone && state.centerY == state.previousCenterY) ||
- (!state.isScaleDone && state.scale == state.previousScale)
+ !(state.isCenterXUpdated || state.isCenterXDone) ||
+ !(state.isCenterYUpdated || state.isCenterYDone) ||
+ !(state.isScaleUpdated || state.isScaleDone)
) {
// Because all three springs use the same update method, we only actually update
- // when all values have changed, avoiding two redundant calls per frame.
+ // when all properties have received their new value (which could be unchanged from
+ // the previous one), avoiding two redundant calls per frame.
return
}
- // Update the latest values for the check above.
- state.previousCenterX = state.centerX
- state.previousCenterY = state.centerY
- state.previousScale = state.scale
+ // Reset the update flags.
+ state.isCenterXUpdated = false
+ state.isCenterYUpdated = false
+ state.isScaleUpdated = false
// Current scale-based values, that will be used to find the new animation bounds.
val width =
@@ -829,6 +844,7 @@
}
setStartValue(startState.centerX)
+ setStartVelocity(startVelocity.x)
setMinValue(min(startState.centerX, endState.centerX))
setMaxValue(max(startState.centerX, endState.centerX))
@@ -850,6 +866,7 @@
}
setStartValue(startState.centerY)
+ setStartVelocity(startVelocity.y)
setMinValue(min(startState.centerY, endState.centerY))
setMaxValue(max(startState.centerY, endState.centerY))
@@ -1057,15 +1074,13 @@
interpolators = springInterpolators!!
val timings = springTimings!!
fadeInProgress =
- getProgressInternal(
- totalDuration = 1f,
+ getProgress(
linearProgress,
timings.contentBeforeFadeOutDelay,
timings.contentBeforeFadeOutDuration,
)
fadeOutProgress =
- getProgressInternal(
- totalDuration = 1f,
+ getProgress(
linearProgress,
timings.contentAfterFadeInDelay,
timings.contentAfterFadeInDuration,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
index 00d9056..300bdf2 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
@@ -48,7 +48,7 @@
Bound.LEFT to createViewProperty(Bound.LEFT),
Bound.TOP to createViewProperty(Bound.TOP),
Bound.RIGHT to createViewProperty(Bound.RIGHT),
- Bound.BOTTOM to createViewProperty(Bound.BOTTOM)
+ Bound.BOTTOM to createViewProperty(Bound.BOTTOM),
)
private fun createViewProperty(bound: Bound): IntProperty<View> {
@@ -89,7 +89,7 @@
interpolator: Interpolator = DEFAULT_INTERPOLATOR,
duration: Long = DEFAULT_DURATION,
animateChildren: Boolean = true,
- excludedViews: Set<View> = emptySet()
+ excludedViews: Set<View> = emptySet(),
): Boolean {
return animate(
rootView,
@@ -97,7 +97,7 @@
duration,
ephemeral = false,
animateChildren = animateChildren,
- excludedViews = excludedViews
+ excludedViews = excludedViews,
)
}
@@ -111,7 +111,7 @@
interpolator: Interpolator = DEFAULT_INTERPOLATOR,
duration: Long = DEFAULT_DURATION,
animateChildren: Boolean = true,
- excludedViews: Set<View> = emptySet()
+ excludedViews: Set<View> = emptySet(),
): Boolean {
return animate(
rootView,
@@ -119,7 +119,7 @@
duration,
ephemeral = true,
animateChildren = animateChildren,
- excludedViews = excludedViews
+ excludedViews = excludedViews,
)
}
@@ -129,7 +129,7 @@
duration: Long,
ephemeral: Boolean,
animateChildren: Boolean,
- excludedViews: Set<View> = emptySet()
+ excludedViews: Set<View> = emptySet(),
): Boolean {
if (
!occupiesSpace(
@@ -137,7 +137,7 @@
rootView.left,
rootView.top,
rootView.right,
- rootView.bottom
+ rootView.bottom,
)
) {
return false
@@ -149,7 +149,7 @@
listener,
recursive = true,
animateChildren = animateChildren,
- excludedViews = excludedViews
+ excludedViews = excludedViews,
)
return true
}
@@ -164,7 +164,7 @@
private fun createUpdateListener(
interpolator: Interpolator,
duration: Long,
- ephemeral: Boolean
+ ephemeral: Boolean,
): View.OnLayoutChangeListener {
return createListener(interpolator, duration, ephemeral)
}
@@ -196,9 +196,9 @@
*
* @param includeFadeIn true if the animator should also fade in the view and child views.
* @param fadeInInterpolator the interpolator to use when fading in the view. Unused if
- * [includeFadeIn] is false.
- * @param onAnimationEnd an optional runnable that will be run once the animation
- * finishes successfully. Will not be run if the animation is cancelled.
+ * [includeFadeIn] is false.
+ * @param onAnimationEnd an optional runnable that will be run once the animation finishes,
+ * regardless of whether the animation is cancelled or finishes successfully.
*/
@JvmOverloads
fun animateAddition(
@@ -217,7 +217,7 @@
rootView.left,
rootView.top,
rootView.right,
- rootView.bottom
+ rootView.bottom,
)
) {
return false
@@ -241,7 +241,10 @@
// First, fade in the container view
val containerDuration = duration / 6
createAndStartFadeInAnimator(
- rootView, containerDuration, startDelay = 0, interpolator = fadeInInterpolator
+ rootView,
+ containerDuration,
+ startDelay = 0,
+ interpolator = fadeInInterpolator,
)
// Then, fade in the child views
@@ -253,7 +256,7 @@
childDuration,
// Wait until the container fades in before fading in the children
startDelay = containerDuration,
- interpolator = fadeInInterpolator
+ interpolator = fadeInInterpolator,
)
}
// For now, we don't recursively fade in additional sub views (e.g. grandchild
@@ -264,7 +267,7 @@
rootView,
duration / 2,
startDelay = 0,
- interpolator = fadeInInterpolator
+ interpolator = fadeInInterpolator,
)
}
@@ -323,7 +326,7 @@
previousLeft: Int,
previousTop: Int,
previousRight: Int,
- previousBottom: Int
+ previousBottom: Int,
) {
if (view == null) return
@@ -353,14 +356,14 @@
startTop,
startRight,
startBottom,
- ignorePreviousValues
+ ignorePreviousValues,
)
val endValues =
mapOf(
Bound.LEFT to left,
Bound.TOP to top,
Bound.RIGHT to right,
- Bound.BOTTOM to bottom
+ Bound.BOTTOM to bottom,
)
val boundsToAnimate = mutableSetOf<Bound>()
@@ -396,8 +399,8 @@
* added on the side(s) of the [destination], the translation of those margins can be
* included by specifying [includeMargins].
*
- * @param onAnimationEnd an optional runnable that will be run once the animation finishes
- * successfully. Will not be run if the animation is cancelled.
+ * @param onAnimationEnd an optional runnable that will be run once the animation finishes,
+ * regardless of whether the animation is cancelled or finishes successfully.
*/
@JvmOverloads
fun animateRemoval(
@@ -414,7 +417,7 @@
rootView.left,
rootView.top,
rootView.right,
- rootView.bottom
+ rootView.bottom,
)
) {
return false
@@ -458,7 +461,7 @@
Bound.LEFT to rootView.left,
Bound.TOP to rootView.top,
Bound.RIGHT to rootView.right,
- Bound.BOTTOM to rootView.bottom
+ Bound.BOTTOM to rootView.bottom,
)
val endValues =
processEndValuesForRemoval(
@@ -550,7 +553,7 @@
destination: Hotspot,
endValues: Map<Bound, Int>,
interpolator: Interpolator,
- duration: Long
+ duration: Long,
) {
for (i in 0 until rootView.childCount) {
val child = rootView.getChildAt(i)
@@ -559,7 +562,7 @@
Bound.LEFT to child.left,
Bound.TOP to child.top,
Bound.RIGHT to child.right,
- Bound.BOTTOM to child.bottom
+ Bound.BOTTOM to child.bottom,
)
val childEndValues =
processChildEndValuesForRemoval(
@@ -569,7 +572,7 @@
child.right,
child.bottom,
endValues.getValue(Bound.RIGHT) - endValues.getValue(Bound.LEFT),
- endValues.getValue(Bound.BOTTOM) - endValues.getValue(Bound.TOP)
+ endValues.getValue(Bound.BOTTOM) - endValues.getValue(Bound.TOP),
)
val boundsToAnimate = mutableSetOf<Bound>()
@@ -587,7 +590,7 @@
childEndValues,
interpolator,
duration,
- ephemeral = true
+ ephemeral = true,
)
}
}
@@ -601,7 +604,7 @@
left: Int,
top: Int,
right: Int,
- bottom: Int
+ bottom: Int,
): Boolean {
return visibility != View.GONE && left != right && top != bottom
}
@@ -616,6 +619,7 @@
* not newly introduced margins are included.
*
* Base case
+ *
* ```
* 1) origin=TOP
* x---------x x---------x x---------x x---------x x---------x
@@ -636,9 +640,11 @@
* x-----x x-------x | |
* x---------x
* ```
+ *
* In case the start and end values differ in the direction of the origin, and
* [ignorePreviousValues] is false, the previous values are used and a translation is
* included in addition to the view expansion.
+ *
* ```
* origin=TOP_LEFT - (0,0,0,0) -> (30,30,70,70)
* x
@@ -660,7 +666,7 @@
previousTop: Int,
previousRight: Int,
previousBottom: Int,
- ignorePreviousValues: Boolean
+ ignorePreviousValues: Boolean,
): Map<Bound, Int> {
val startLeft = if (ignorePreviousValues) newLeft else previousLeft
val startTop = if (ignorePreviousValues) newTop else previousTop
@@ -727,7 +733,7 @@
Bound.LEFT to left,
Bound.TOP to top,
Bound.RIGHT to right,
- Bound.BOTTOM to bottom
+ Bound.BOTTOM to bottom,
)
}
@@ -777,18 +783,17 @@
includeMargins: Boolean = false,
): Map<Bound, Int> {
val marginAdjustment =
- if (includeMargins &&
- (rootView.layoutParams is ViewGroup.MarginLayoutParams)) {
+ if (includeMargins && (rootView.layoutParams is ViewGroup.MarginLayoutParams)) {
val marginLp = rootView.layoutParams as ViewGroup.MarginLayoutParams
DimenHolder(
left = marginLp.leftMargin,
top = marginLp.topMargin,
right = marginLp.rightMargin,
- bottom = marginLp.bottomMargin
+ bottom = marginLp.bottomMargin,
)
- } else {
- DimenHolder(0, 0, 0, 0)
- }
+ } else {
+ DimenHolder(0, 0, 0, 0)
+ }
// These are the end values to use *if* this bound is part of the destination.
val endLeft = left - marginAdjustment.left
@@ -805,60 +810,69 @@
// - If destination=BOTTOM_LEFT, then endBottom == endTop AND endLeft == endRight.
return when (destination) {
- Hotspot.TOP -> mapOf(
- Bound.TOP to endTop,
- Bound.BOTTOM to endTop,
- Bound.LEFT to left,
- Bound.RIGHT to right,
- )
- Hotspot.TOP_RIGHT -> mapOf(
- Bound.TOP to endTop,
- Bound.BOTTOM to endTop,
- Bound.RIGHT to endRight,
- Bound.LEFT to endRight,
- )
- Hotspot.RIGHT -> mapOf(
- Bound.RIGHT to endRight,
- Bound.LEFT to endRight,
- Bound.TOP to top,
- Bound.BOTTOM to bottom,
- )
- Hotspot.BOTTOM_RIGHT -> mapOf(
- Bound.BOTTOM to endBottom,
- Bound.TOP to endBottom,
- Bound.RIGHT to endRight,
- Bound.LEFT to endRight,
- )
- Hotspot.BOTTOM -> mapOf(
- Bound.BOTTOM to endBottom,
- Bound.TOP to endBottom,
- Bound.LEFT to left,
- Bound.RIGHT to right,
- )
- Hotspot.BOTTOM_LEFT -> mapOf(
- Bound.BOTTOM to endBottom,
- Bound.TOP to endBottom,
- Bound.LEFT to endLeft,
- Bound.RIGHT to endLeft,
- )
- Hotspot.LEFT -> mapOf(
- Bound.LEFT to endLeft,
- Bound.RIGHT to endLeft,
- Bound.TOP to top,
- Bound.BOTTOM to bottom,
- )
- Hotspot.TOP_LEFT -> mapOf(
- Bound.TOP to endTop,
- Bound.BOTTOM to endTop,
- Bound.LEFT to endLeft,
- Bound.RIGHT to endLeft,
- )
- Hotspot.CENTER -> mapOf(
- Bound.LEFT to (endLeft + endRight) / 2,
- Bound.RIGHT to (endLeft + endRight) / 2,
- Bound.TOP to (endTop + endBottom) / 2,
- Bound.BOTTOM to (endTop + endBottom) / 2,
- )
+ Hotspot.TOP ->
+ mapOf(
+ Bound.TOP to endTop,
+ Bound.BOTTOM to endTop,
+ Bound.LEFT to left,
+ Bound.RIGHT to right,
+ )
+ Hotspot.TOP_RIGHT ->
+ mapOf(
+ Bound.TOP to endTop,
+ Bound.BOTTOM to endTop,
+ Bound.RIGHT to endRight,
+ Bound.LEFT to endRight,
+ )
+ Hotspot.RIGHT ->
+ mapOf(
+ Bound.RIGHT to endRight,
+ Bound.LEFT to endRight,
+ Bound.TOP to top,
+ Bound.BOTTOM to bottom,
+ )
+ Hotspot.BOTTOM_RIGHT ->
+ mapOf(
+ Bound.BOTTOM to endBottom,
+ Bound.TOP to endBottom,
+ Bound.RIGHT to endRight,
+ Bound.LEFT to endRight,
+ )
+ Hotspot.BOTTOM ->
+ mapOf(
+ Bound.BOTTOM to endBottom,
+ Bound.TOP to endBottom,
+ Bound.LEFT to left,
+ Bound.RIGHT to right,
+ )
+ Hotspot.BOTTOM_LEFT ->
+ mapOf(
+ Bound.BOTTOM to endBottom,
+ Bound.TOP to endBottom,
+ Bound.LEFT to endLeft,
+ Bound.RIGHT to endLeft,
+ )
+ Hotspot.LEFT ->
+ mapOf(
+ Bound.LEFT to endLeft,
+ Bound.RIGHT to endLeft,
+ Bound.TOP to top,
+ Bound.BOTTOM to bottom,
+ )
+ Hotspot.TOP_LEFT ->
+ mapOf(
+ Bound.TOP to endTop,
+ Bound.BOTTOM to endTop,
+ Bound.LEFT to endLeft,
+ Bound.RIGHT to endLeft,
+ )
+ Hotspot.CENTER ->
+ mapOf(
+ Bound.LEFT to (endLeft + endRight) / 2,
+ Bound.RIGHT to (endLeft + endRight) / 2,
+ Bound.TOP to (endTop + endBottom) / 2,
+ Bound.BOTTOM to (endTop + endBottom) / 2,
+ )
}
}
@@ -887,7 +901,7 @@
right: Int,
bottom: Int,
parentWidth: Int,
- parentHeight: Int
+ parentHeight: Int,
): Map<Bound, Int> {
val halfWidth = (right - left) / 2
val halfHeight = (bottom - top) / 2
@@ -945,7 +959,7 @@
Bound.LEFT to endLeft,
Bound.TOP to endTop,
Bound.RIGHT to endRight,
- Bound.BOTTOM to endBottom
+ Bound.BOTTOM to endBottom,
)
}
@@ -954,7 +968,7 @@
listener: View.OnLayoutChangeListener,
recursive: Boolean = false,
animateChildren: Boolean = true,
- excludedViews: Set<View> = emptySet()
+ excludedViews: Set<View> = emptySet(),
) {
if (excludedViews.contains(view)) return
@@ -973,7 +987,7 @@
listener,
recursive = true,
animateChildren = animateChildren,
- excludedViews = excludedViews
+ excludedViews = excludedViews,
)
}
}
@@ -1027,7 +1041,7 @@
PropertyValuesHolder.ofInt(
PROPERTIES[bound],
startValues.getValue(bound),
- endValues.getValue(bound)
+ endValues.getValue(bound),
)
)
}
@@ -1056,9 +1070,10 @@
// listener.
recursivelyRemoveListener(view)
}
- if (!cancelled) {
- onAnimationEnd?.run()
- }
+ // Run the end runnable regardless of whether the animation was cancelled or
+ // not - this ensures critical actions (like removing a window) always occur
+ // (see b/344049884).
+ onAnimationEnd?.run()
}
override fun onAnimationCancel(animation: Animator) {
@@ -1077,17 +1092,19 @@
view: View,
duration: Long,
startDelay: Long,
- interpolator: Interpolator
+ interpolator: Interpolator,
) {
val animator = ObjectAnimator.ofFloat(view, "alpha", 1f)
animator.startDelay = startDelay
animator.duration = duration
animator.interpolator = interpolator
- animator.addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- view.setTag(R.id.tag_alpha_animator, null /* tag */)
+ animator.addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ view.setTag(R.id.tag_alpha_animator, null /* tag */)
+ }
}
- })
+ )
(view.getTag(R.id.tag_alpha_animator) as? ObjectAnimator)?.cancel()
view.setTag(R.id.tag_alpha_animator, animator)
@@ -1105,7 +1122,7 @@
RIGHT,
BOTTOM_RIGHT,
BOTTOM,
- BOTTOM_LEFT
+ BOTTOM_LEFT,
}
private enum class Bound(val label: String, val overrideTag: Int) {
@@ -1147,14 +1164,10 @@
};
abstract fun setValue(view: View, value: Int)
+
abstract fun getValue(view: View): Int
}
/** Simple data class to hold a set of dimens for left, top, right, bottom. */
- private data class DimenHolder(
- val left: Int,
- val top: Int,
- val right: Int,
- val bottom: Int,
- )
+ private data class DimenHolder(val left: Int, val top: Int, val right: Int, val bottom: Int)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 6d30398..87e9c42 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -42,7 +42,6 @@
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.observableTransitionState
import com.android.compose.animation.scene.transitions
import com.android.systemui.communal.shared.model.CommunalBackgroundType
@@ -124,7 +123,7 @@
}
timestampRange(
startMillis = TransitionDuration.EDIT_MODE_TO_HUB_GRID_DELAY_MS,
- endMillis = TransitionDuration.EDIT_MODE_TO_HUB_GRID_END_MS
+ endMillis = TransitionDuration.EDIT_MODE_TO_HUB_GRID_END_MS,
) {
fade(Communal.Elements.Grid)
}
@@ -187,14 +186,13 @@
) {
scene(
CommunalScenes.Blank,
- userActions =
- mapOf(Swipe(SwipeDirection.Start, fromSource = Edge.End) to CommunalScenes.Communal)
+ userActions = mapOf(Swipe.Start(fromSource = Edge.End) to CommunalScenes.Communal),
) {
// This scene shows nothing only allowing for transitions to the communal scene.
Box(modifier = Modifier.fillMaxSize())
}
- val userActions = mapOf(Swipe(SwipeDirection.End) to CommunalScenes.Blank)
+ val userActions = mapOf(Swipe.End to CommunalScenes.Blank)
scene(CommunalScenes.Communal, userActions = userActions) {
CommunalScene(
@@ -257,13 +255,9 @@
/** Default background of the hub, a single color */
@Composable
-private fun BoxScope.DefaultBackground(
- colors: CommunalColors,
-) {
+private fun BoxScope.DefaultBackground(colors: CommunalColors) {
val backgroundColor by colors.backgroundColor.collectAsStateWithLifecycle()
- Box(
- modifier = Modifier.matchParentSize().background(Color(backgroundColor.toArgb())),
- )
+ Box(modifier = Modifier.matchParentSize().background(Color(backgroundColor.toArgb())))
}
/** Experimental hub background, static linear gradient */
@@ -273,7 +267,7 @@
Box(
Modifier.matchParentSize()
.background(
- Brush.linearGradient(colors = listOf(colors.primary, colors.primaryContainer)),
+ Brush.linearGradient(colors = listOf(colors.primary, colors.primaryContainer))
)
)
BackgroundTopScrim()
@@ -288,7 +282,7 @@
.background(colors.primary)
.animatedRadialGradientBackground(
toColor = colors.primary,
- fromColor = colors.primaryContainer.copy(alpha = 0.6f)
+ fromColor = colors.primaryContainer.copy(alpha = 0.6f),
)
)
BackgroundTopScrim()
@@ -324,9 +318,9 @@
durationMillis = ANIMATION_DURATION_MS,
easing = CubicBezierEasing(0.33f, 0f, 0.67f, 1f),
),
- repeatMode = RepeatMode.Reverse
+ repeatMode = RepeatMode.Reverse,
),
- label = "radial gradient center fraction"
+ label = "radial gradient center fraction",
)
// Offset to place the center of the gradients offscreen. This is applied to both the
@@ -337,16 +331,9 @@
val gradientRadius = (size.width / 2) + offsetPx
val totalHeight = size.height + 2 * offsetPx
- val leftCenter =
- Offset(
- x = -offsetPx,
- y = totalHeight * centerFraction - offsetPx,
- )
+ val leftCenter = Offset(x = -offsetPx, y = totalHeight * centerFraction - offsetPx)
val rightCenter =
- Offset(
- x = offsetPx + size.width,
- y = totalHeight * (1f - centerFraction) - offsetPx,
- )
+ Offset(x = offsetPx + size.width, y = totalHeight * (1f - centerFraction) - offsetPx)
// Right gradient
drawCircle(
@@ -354,7 +341,7 @@
Brush.radialGradient(
colors = listOf(fromColor, toColor),
center = rightCenter,
- radius = gradientRadius
+ radius = gradientRadius,
),
center = rightCenter,
radius = gradientRadius,
@@ -367,7 +354,7 @@
Brush.radialGradient(
colors = listOf(fromColor, toColor),
center = leftCenter,
- radius = gradientRadius
+ radius = gradientRadius,
),
center = leftCenter,
radius = gradientRadius,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
index f2f7c87..0aef7f2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
@@ -36,6 +36,7 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
+import com.android.systemui.Flags.communalWidgetResizing
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset
import com.android.systemui.communal.util.WidgetPickerIntentUtils
@@ -82,9 +83,7 @@
* @see DragEvent
*/
@Composable
-internal fun Modifier.dragAndDropTarget(
- dragDropTargetState: DragAndDropTargetState,
-): Modifier {
+internal fun Modifier.dragAndDropTarget(dragDropTargetState: DragAndDropTargetState): Modifier {
val state by rememberUpdatedState(dragDropTargetState)
return this then
@@ -113,7 +112,7 @@
override fun onEnded(event: DragAndDropEvent) {
state.onEnded()
}
- }
+ },
)
}
@@ -146,6 +145,7 @@
*/
private var placeHolder = CommunalContentModel.WidgetPlaceholder()
private var placeHolderIndex: Int? = null
+ private var previousTargetItemKey: Any? = null
internal val scrollChannel = Channel<Float>()
@@ -164,7 +164,19 @@
.filter { item -> contentListState.isItemEditable(item.index) }
.firstItemAtOffset(dragOffset - contentOffset)
- if (targetItem != null) {
+ if (
+ targetItem != null &&
+ (!communalWidgetResizing() || targetItem.key != previousTargetItemKey)
+ ) {
+ if (communalWidgetResizing()) {
+ // Keep track of the previous target item, to avoid rapidly oscillating between
+ // items if the target item doesn't visually move as a result of the index change.
+ // In this case, even after the index changes, we'd still be colliding with the
+ // element, so it would be selected as the target item the next time this function
+ // runs again, which would trigger us to revert the index change we recently made.
+ previousTargetItemKey = targetItem.key
+ }
+
var scrollIndex: Int? = null
var scrollOffset: Int? = null
if (placeHolderIndex == state.firstVisibleItemIndex) {
@@ -183,8 +195,9 @@
// this is needed to neutralize automatic keeping the first item first.
scope.launch { state.scrollToItem(scrollIndex, scrollOffset) }
}
- } else {
+ } else if (targetItem == null) {
computeAutoscroll(dragOffset).takeIf { it != 0f }?.let { scrollChannel.trySend(it) }
+ previousTargetItemKey = null
}
}
@@ -198,7 +211,7 @@
contentListState.onSaveList(
newItemComponentName = componentName,
newItemUser = user,
- newItemIndex = dropIndex
+ newItemIndex = dropIndex,
)
return@let true
}
@@ -208,6 +221,7 @@
fun onEnded() {
placeHolderIndex = null
+ previousTargetItemKey = null
contentListState.list.remove(placeHolder)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
index 5b99670..2af5ffa 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
@@ -18,23 +18,27 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
+import androidx.compose.ui.layout.layoutId
import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.battery.BatteryMeterViewController
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
+import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn
+import com.android.systemui.keyguard.ui.composable.section.DefaultClockSection
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayActionsViewModel
import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel
import com.android.systemui.scene.session.ui.composable.SaveableSession
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.ui.composable.Overlay
-import com.android.systemui.shade.ui.composable.ExpandedShadeHeader
+import com.android.systemui.shade.ui.composable.CollapsedShadeHeader
import com.android.systemui.shade.ui.composable.OverlayShade
+import com.android.systemui.shade.ui.composable.SingleShadeMeasurePolicy
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
import com.android.systemui.statusbar.phone.ui.StatusBarIconController
import com.android.systemui.statusbar.phone.ui.TintedIconManager
@@ -53,6 +57,8 @@
private val statusBarIconController: StatusBarIconController,
private val shadeSession: SaveableSession,
private val stackScrollView: Lazy<NotificationScrollView>,
+ private val clockSection: DefaultClockSection,
+ private val clockInteractor: KeyguardClockInteractor,
) : Overlay {
override val key = Overlays.NotificationsShade
@@ -80,13 +86,28 @@
OverlayShade(modifier = modifier, onScrimClicked = viewModel::onScrimClicked) {
Column {
- ExpandedShadeHeader(
- viewModelFactory = viewModel.shadeHeaderViewModelFactory,
- createTintedIconManager = tintedIconManagerFactory::create,
- createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
- statusBarIconController = statusBarIconController,
- modifier = Modifier.padding(horizontal = 16.dp),
- )
+ if (viewModel.showHeader) {
+ val burnIn = rememberBurnIn(clockInteractor)
+
+ CollapsedShadeHeader(
+ viewModelFactory = viewModel.shadeHeaderViewModelFactory,
+ createTintedIconManager = tintedIconManagerFactory::create,
+ createBatteryMeterViewController =
+ batteryMeterViewControllerFactory::create,
+ statusBarIconController = statusBarIconController,
+ modifier =
+ Modifier.element(NotificationsShade.Elements.StatusBar)
+ .layoutId(SingleShadeMeasurePolicy.LayoutId.ShadeHeader),
+ )
+
+ with(clockSection) {
+ SmallClock(
+ burnInParams = burnIn.parameters,
+ onTopChanged = burnIn.onSmallClockTopChanged,
+ modifier = Modifier.fillMaxWidth(),
+ )
+ }
+ }
NotificationScrollingStack(
shadeSession = shadeSession,
@@ -110,3 +131,9 @@
}
}
}
+
+object NotificationsShade {
+ object Elements {
+ val StatusBar = ElementKey("NotificationsShadeStatusBar")
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
index 67f412e..2cde678 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
@@ -105,13 +105,17 @@
// Overlay transitions
+ // TODO(b/376659778): Remove this transition once nested STLs are supported.
+ from(Scenes.Gone, to = Overlays.NotificationsShade) {
+ toNotificationsShadeTransition(translateClock = true)
+ }
to(Overlays.NotificationsShade) { toNotificationsShadeTransition() }
to(Overlays.QuickSettingsShade) { toQuickSettingsShadeTransition() }
from(Overlays.NotificationsShade, to = Overlays.QuickSettingsShade) {
notificationsShadeToQuickSettingsShadeTransition()
}
from(Scenes.Gone, to = Overlays.NotificationsShade, key = SlightlyFasterShadeCollapse) {
- toNotificationsShadeTransition(durationScale = 0.9)
+ toNotificationsShadeTransition(translateClock = true, durationScale = 0.9)
}
from(Scenes.Gone, to = Overlays.QuickSettingsShade, key = SlightlyFasterShadeCollapse) {
toQuickSettingsShadeTransition(durationScale = 0.9)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
index 23c4f12..6bdb363 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
@@ -21,30 +21,42 @@
import androidx.compose.animation.core.tween
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.TransitionBuilder
+import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys
import com.android.systemui.notifications.ui.composable.Notifications
+import com.android.systemui.notifications.ui.composable.NotificationsShade
+import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.shade.ui.composable.OverlayShade
import com.android.systemui.shade.ui.composable.Shade
-import com.android.systemui.shade.ui.composable.ShadeHeader
import kotlin.time.Duration.Companion.milliseconds
-fun TransitionBuilder.toNotificationsShadeTransition(durationScale: Double = 1.0) {
+fun TransitionBuilder.toNotificationsShadeTransition(
+ translateClock: Boolean = false,
+ durationScale: Double = 1.0,
+) {
spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
swipeSpec =
spring(
stiffness = Spring.StiffnessMediumLow,
visibilityThreshold = Shade.Dimensions.ScrimVisibilityThreshold,
)
+ // Ensure the clock isn't clipped by the shade outline during the transition from lockscreen.
+ sharedElement(
+ ClockElementKeys.smallClockElementKey,
+ elevateInContent = Overlays.NotificationsShade,
+ )
scaleSize(OverlayShade.Elements.Panel, height = 0f)
+ // TODO(b/376659778): This is a temporary hack to have a shared element transition with the
+ // lockscreen clock. Remove once nested STLs are supported.
+ if (!translateClock) {
+ translate(ClockElementKeys.smallClockElementKey)
+ }
+ // Avoid translating the status bar with the shade panel.
+ translate(NotificationsShade.Elements.StatusBar)
+ // Slide in the shade panel from the top edge.
translate(OverlayShade.Elements.Panel, Edge.Top)
fractionRange(end = .5f) { fade(OverlayShade.Elements.Scrim) }
-
- fractionRange(start = .5f) {
- fade(ShadeHeader.Elements.Clock)
- fade(ShadeHeader.Elements.ExpandedContent)
- fade(ShadeHeader.Elements.PrivacyChip)
- fade(Notifications.Elements.NotificationScrim)
- }
+ fractionRange(start = .5f) { fade(Notifications.Elements.NotificationScrim) }
}
private val DefaultDuration = 300.milliseconds
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt b/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt
index e9b7335..d58e1bf 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt
@@ -98,19 +98,20 @@
theme: Int = SystemUIDialog.DEFAULT_THEME,
dismissOnDeviceLock: Boolean = SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK,
@GravityInt dialogGravity: Int? = null,
+ dialogDelegate: DialogDelegate<SystemUIDialog> =
+ object : DialogDelegate<SystemUIDialog> {
+ override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+ super.onCreate(dialog, savedInstanceState)
+ dialogGravity?.let { dialog.window?.setGravity(it) }
+ }
+ },
content: @Composable (SystemUIDialog) -> Unit,
): ComponentSystemUIDialog {
return create(
context = context,
theme = theme,
dismissOnDeviceLock = dismissOnDeviceLock,
- delegate =
- object : DialogDelegate<SystemUIDialog> {
- override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
- super.onCreate(dialog, savedInstanceState)
- dialogGravity?.let { dialog.window?.setGravity(it) }
- }
- },
+ delegate = dialogDelegate,
content = content,
)
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index 63c5d7a..e7b66c5 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -52,6 +52,7 @@
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.transformation.PropertyTransformation
import com.android.compose.animation.scene.transformation.SharedElementTransformation
+import com.android.compose.animation.scene.transformation.TransformationWithRange
import com.android.compose.modifiers.thenIf
import com.android.compose.ui.graphics.drawInContainer
import com.android.compose.ui.util.lerp
@@ -187,6 +188,7 @@
state.transformationSpec
.transformations(key, content.key)
.shared
+ ?.transformation
?.elevateInContent == content.key &&
isSharedElement(stateByContent, state) &&
isSharedElementEnabled(key, state) &&
@@ -901,7 +903,7 @@
}
val sharedTransformation = sharedElementTransformation(element.key, transition)
- if (sharedTransformation?.enabled == false) {
+ if (sharedTransformation?.transformation?.enabled == false) {
return true
}
@@ -954,13 +956,13 @@
element: ElementKey,
transition: TransitionState.Transition,
): Boolean {
- return sharedElementTransformation(element, transition)?.enabled ?: true
+ return sharedElementTransformation(element, transition)?.transformation?.enabled ?: true
}
internal fun sharedElementTransformation(
element: ElementKey,
transition: TransitionState.Transition,
-): SharedElementTransformation? {
+): TransformationWithRange<SharedElementTransformation>? {
val transformationSpec = transition.transformationSpec
val sharedInFromContent =
transformationSpec.transformations(element, transition.fromContent).shared
@@ -1244,7 +1246,7 @@
element: Element,
transition: TransitionState.Transition?,
contentValue: (Element.State) -> T,
- transformation: (ElementTransformations) -> PropertyTransformation<T>?,
+ transformation: (ElementTransformations) -> TransformationWithRange<PropertyTransformation<T>>?,
currentValue: () -> T,
isSpecified: (T) -> Boolean,
lerp: (T, T, Float) -> T,
@@ -1280,7 +1282,7 @@
checkNotNull(if (currentContent == toContent) toState else fromState)
val idleValue = contentValue(overscrollState)
val targetValue =
- with(propertySpec) {
+ with(propertySpec.transformation) {
layoutImpl.propertyTransformationScope.transform(
currentContent,
element.key,
@@ -1375,7 +1377,7 @@
val idleValue = contentValue(contentState)
val isEntering = content == toContent
val previewTargetValue =
- with(previewTransformation) {
+ with(previewTransformation.transformation) {
layoutImpl.propertyTransformationScope.transform(
content,
element.key,
@@ -1386,7 +1388,7 @@
val targetValueOrNull =
transformation?.let { transformation ->
- with(transformation) {
+ with(transformation.transformation) {
layoutImpl.propertyTransformationScope.transform(
content,
element.key,
@@ -1461,7 +1463,7 @@
val idleValue = contentValue(contentState)
val targetValue =
- with(transformation) {
+ with(transformation.transformation) {
layoutImpl.propertyTransformationScope.transform(
content,
element.key,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 21d87e1..dbf7d7b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -405,7 +405,8 @@
}
/** The user swiped on the container. */
-data class Swipe(
+data class Swipe
+private constructor(
val direction: SwipeDirection,
val pointerCount: Int = 1,
val pointersType: PointerType? = null,
@@ -418,6 +419,42 @@
val Down = Swipe(SwipeDirection.Down)
val Start = Swipe(SwipeDirection.Start)
val End = Swipe(SwipeDirection.End)
+
+ fun Left(
+ pointerCount: Int = 1,
+ pointersType: PointerType? = null,
+ fromSource: SwipeSource? = null,
+ ) = Swipe(SwipeDirection.Left, pointerCount, pointersType, fromSource)
+
+ fun Up(
+ pointerCount: Int = 1,
+ pointersType: PointerType? = null,
+ fromSource: SwipeSource? = null,
+ ) = Swipe(SwipeDirection.Up, pointerCount, pointersType, fromSource)
+
+ fun Right(
+ pointerCount: Int = 1,
+ pointersType: PointerType? = null,
+ fromSource: SwipeSource? = null,
+ ) = Swipe(SwipeDirection.Right, pointerCount, pointersType, fromSource)
+
+ fun Down(
+ pointerCount: Int = 1,
+ pointersType: PointerType? = null,
+ fromSource: SwipeSource? = null,
+ ) = Swipe(SwipeDirection.Down, pointerCount, pointersType, fromSource)
+
+ fun Start(
+ pointerCount: Int = 1,
+ pointersType: PointerType? = null,
+ fromSource: SwipeSource? = null,
+ ) = Swipe(SwipeDirection.Start, pointerCount, pointersType, fromSource)
+
+ fun End(
+ pointerCount: Int = 1,
+ pointersType: PointerType? = null,
+ fromSource: SwipeSource? = null,
+ ) = Swipe(SwipeDirection.End, pointerCount, pointersType, fromSource)
}
override fun resolve(layoutDirection: LayoutDirection): UserAction.Resolved {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index e1e2411..61332b6 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -764,7 +764,8 @@
return@fastForEach
}
- state.transformationSpec.transformations.fastForEach { transformation ->
+ state.transformationSpec.transformations.fastForEach { transformationWithRange ->
+ val transformation = transformationWithRange.transformation
if (
transformation is SharedElementTransformation &&
transformation.elevateInContent != null
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
index 8866fbf..b083f79 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
@@ -33,10 +33,10 @@
import com.android.compose.animation.scene.transformation.Fade
import com.android.compose.animation.scene.transformation.OverscrollTranslate
import com.android.compose.animation.scene.transformation.PropertyTransformation
-import com.android.compose.animation.scene.transformation.RangedPropertyTransformation
import com.android.compose.animation.scene.transformation.ScaleSize
import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.Transformation
+import com.android.compose.animation.scene.transformation.TransformationWithRange
import com.android.compose.animation.scene.transformation.Translate
/** The transitions configuration of a [SceneTransitionLayout]. */
@@ -233,7 +233,7 @@
val distance: UserActionDistance?
/** The list of [Transformation] applied to elements during this transition. */
- val transformations: List<Transformation>
+ val transformations: List<TransformationWithRange<*>>
companion object {
internal val Empty =
@@ -325,7 +325,7 @@
override val progressSpec: AnimationSpec<Float>,
override val swipeSpec: SpringSpec<Float>?,
override val distance: UserActionDistance?,
- override val transformations: List<Transformation>,
+ override val transformations: List<TransformationWithRange<*>>,
) : TransformationSpec {
private val cache = mutableMapOf<ElementKey, MutableMap<ContentKey, ElementTransformations>>()
@@ -340,42 +340,14 @@
element: ElementKey,
content: ContentKey,
): ElementTransformations {
- var shared: SharedElementTransformation? = null
- var offset: PropertyTransformation<Offset>? = null
- var size: PropertyTransformation<IntSize>? = null
- var drawScale: PropertyTransformation<Scale>? = null
- var alpha: PropertyTransformation<Float>? = null
+ var shared: TransformationWithRange<SharedElementTransformation>? = null
+ var offset: TransformationWithRange<PropertyTransformation<Offset>>? = null
+ var size: TransformationWithRange<PropertyTransformation<IntSize>>? = null
+ var drawScale: TransformationWithRange<PropertyTransformation<Scale>>? = null
+ var alpha: TransformationWithRange<PropertyTransformation<Float>>? = null
- fun <T> onPropertyTransformation(
- root: PropertyTransformation<T>,
- current: PropertyTransformation<T> = root,
- ) {
- when (current) {
- is Translate,
- is OverscrollTranslate,
- is EdgeTranslate,
- is AnchoredTranslate -> {
- throwIfNotNull(offset, element, name = "offset")
- offset = root as PropertyTransformation<Offset>
- }
- is ScaleSize,
- is AnchoredSize -> {
- throwIfNotNull(size, element, name = "size")
- size = root as PropertyTransformation<IntSize>
- }
- is DrawScale -> {
- throwIfNotNull(drawScale, element, name = "drawScale")
- drawScale = root as PropertyTransformation<Scale>
- }
- is Fade -> {
- throwIfNotNull(alpha, element, name = "alpha")
- alpha = root as PropertyTransformation<Float>
- }
- is RangedPropertyTransformation -> onPropertyTransformation(root, current.delegate)
- }
- }
-
- transformations.fastForEach { transformation ->
+ transformations.fastForEach { transformationWithRange ->
+ val transformation = transformationWithRange.transformation
if (!transformation.matcher.matches(element, content)) {
return@fastForEach
}
@@ -383,16 +355,50 @@
when (transformation) {
is SharedElementTransformation -> {
throwIfNotNull(shared, element, name = "shared")
- shared = transformation
+ shared =
+ transformationWithRange
+ as TransformationWithRange<SharedElementTransformation>
}
- is PropertyTransformation<*> -> onPropertyTransformation(transformation)
+ is Translate,
+ is OverscrollTranslate,
+ is EdgeTranslate,
+ is AnchoredTranslate -> {
+ throwIfNotNull(offset, element, name = "offset")
+ offset =
+ transformationWithRange
+ as TransformationWithRange<PropertyTransformation<Offset>>
+ }
+ is ScaleSize,
+ is AnchoredSize -> {
+ throwIfNotNull(size, element, name = "size")
+ size =
+ transformationWithRange
+ as TransformationWithRange<PropertyTransformation<IntSize>>
+ }
+ is DrawScale -> {
+ throwIfNotNull(drawScale, element, name = "drawScale")
+ drawScale =
+ transformationWithRange
+ as TransformationWithRange<PropertyTransformation<Scale>>
+ }
+ is Fade -> {
+ throwIfNotNull(alpha, element, name = "alpha")
+ alpha =
+ transformationWithRange
+ as TransformationWithRange<PropertyTransformation<Float>>
+ }
+ else -> error("Unknown transformation: $transformation")
}
}
return ElementTransformations(shared, offset, size, drawScale, alpha)
}
- private fun throwIfNotNull(previous: Transformation?, element: ElementKey, name: String) {
+ private fun throwIfNotNull(
+ previous: TransformationWithRange<*>?,
+ element: ElementKey,
+ name: String,
+ ) {
if (previous != null) {
error("$element has multiple $name transformations")
}
@@ -401,9 +407,9 @@
/** The transformations of an element during a transition. */
internal class ElementTransformations(
- val shared: SharedElementTransformation?,
- val offset: PropertyTransformation<Offset>?,
- val size: PropertyTransformation<IntSize>?,
- val drawScale: PropertyTransformation<Scale>?,
- val alpha: PropertyTransformation<Float>?,
+ val shared: TransformationWithRange<SharedElementTransformation>?,
+ val offset: TransformationWithRange<PropertyTransformation<Offset>>?,
+ val size: TransformationWithRange<PropertyTransformation<IntSize>>?,
+ val drawScale: TransformationWithRange<PropertyTransformation<Scale>>?,
+ val alpha: TransformationWithRange<PropertyTransformation<Float>>?,
)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
index 269d91b0..e461f9c 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
@@ -34,12 +34,11 @@
import com.android.compose.animation.scene.transformation.EdgeTranslate
import com.android.compose.animation.scene.transformation.Fade
import com.android.compose.animation.scene.transformation.OverscrollTranslate
-import com.android.compose.animation.scene.transformation.PropertyTransformation
-import com.android.compose.animation.scene.transformation.RangedPropertyTransformation
import com.android.compose.animation.scene.transformation.ScaleSize
import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.Transformation
import com.android.compose.animation.scene.transformation.TransformationRange
+import com.android.compose.animation.scene.transformation.TransformationWithRange
import com.android.compose.animation.scene.transformation.Translate
internal fun transitionsImpl(builder: SceneTransitionsBuilder.() -> Unit): SceneTransitions {
@@ -158,7 +157,7 @@
}
internal abstract class BaseTransitionBuilderImpl : BaseTransitionBuilder {
- val transformations = mutableListOf<Transformation>()
+ val transformations = mutableListOf<TransformationWithRange<*>>()
private var range: TransformationRange? = null
protected var reversed = false
override var distance: UserActionDistance? = null
@@ -174,19 +173,13 @@
range = null
}
- protected fun transformation(transformation: PropertyTransformation<*>) {
- val transformation =
- if (range != null) {
- RangedPropertyTransformation(transformation, range!!)
- } else {
- transformation
- }
-
+ protected fun transformation(transformation: Transformation) {
+ val transformationWithRange = TransformationWithRange(transformation, range)
transformations.add(
if (reversed) {
- transformation.reversed()
+ transformationWithRange.reversed()
} else {
- transformation
+ transformationWithRange
}
)
}
@@ -264,7 +257,7 @@
"(${transition.toContent.debugName})"
}
- transformations.add(SharedElementTransformation(matcher, enabled, elevateInContent))
+ transformation(SharedElementTransformation(matcher, enabled, elevateInContent))
}
override fun timestampRange(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt
index 5936d25..0ddeb7c 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt
@@ -33,7 +33,7 @@
content: ContentKey,
element: ElementKey,
transition: TransitionState.Transition,
- value: IntSize,
+ idleValue: IntSize,
): IntSize {
fun anchorSizeIn(content: ContentKey): IntSize {
val size =
@@ -45,8 +45,8 @@
)
return IntSize(
- width = if (anchorWidth) size.width else value.width,
- height = if (anchorHeight) size.height else value.height,
+ width = if (anchorWidth) size.width else idleValue.width,
+ height = if (anchorHeight) size.height else idleValue.height,
)
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt
index 0a59dfe..47508b4 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt
@@ -31,7 +31,7 @@
content: ContentKey,
element: ElementKey,
transition: TransitionState.Transition,
- value: Offset,
+ idleValue: Offset,
): Offset {
fun throwException(content: ContentKey?): Nothing {
throwMissingAnchorException(
@@ -51,9 +51,9 @@
val offset = anchorToOffset - anchorFromOffset
return if (content == transition.toContent) {
- Offset(value.x - offset.x, value.y - offset.y)
+ Offset(idleValue.x - offset.x, idleValue.y - offset.y)
} else {
- Offset(value.x + offset.x, value.y + offset.y)
+ Offset(idleValue.x + offset.x, idleValue.y + offset.y)
}
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt
index 7223dad..8488ae5 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt
@@ -33,12 +33,11 @@
private val scaleY: Float,
private val pivot: Offset = Offset.Unspecified,
) : PropertyTransformation<Scale> {
-
override fun PropertyTransformationScope.transform(
content: ContentKey,
element: ElementKey,
transition: TransitionState.Transition,
- value: Scale,
+ idleValue: Scale,
): Scale {
return Scale(scaleX, scaleY, pivot)
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt
index 4ae07c5..884aae4b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt
@@ -33,37 +33,37 @@
content: ContentKey,
element: ElementKey,
transition: TransitionState.Transition,
- value: Offset,
+ idleValue: Offset,
): Offset {
val sceneSize =
content.targetSize()
?: error("Content ${content.debugName} does not have a target size")
- val elementSize = element.targetSize(content) ?: return value
+ val elementSize = element.targetSize(content) ?: return idleValue
return when (edge.resolve(layoutDirection)) {
Edge.Resolved.Top ->
if (startsOutsideLayoutBounds) {
- Offset(value.x, -elementSize.height.toFloat())
+ Offset(idleValue.x, -elementSize.height.toFloat())
} else {
- Offset(value.x, 0f)
+ Offset(idleValue.x, 0f)
}
Edge.Resolved.Left ->
if (startsOutsideLayoutBounds) {
- Offset(-elementSize.width.toFloat(), value.y)
+ Offset(-elementSize.width.toFloat(), idleValue.y)
} else {
- Offset(0f, value.y)
+ Offset(0f, idleValue.y)
}
Edge.Resolved.Bottom ->
if (startsOutsideLayoutBounds) {
- Offset(value.x, sceneSize.height.toFloat())
+ Offset(idleValue.x, sceneSize.height.toFloat())
} else {
- Offset(value.x, (sceneSize.height - elementSize.height).toFloat())
+ Offset(idleValue.x, (sceneSize.height - elementSize.height).toFloat())
}
Edge.Resolved.Right ->
if (startsOutsideLayoutBounds) {
- Offset(sceneSize.width.toFloat(), value.y)
+ Offset(sceneSize.width.toFloat(), idleValue.y)
} else {
- Offset((sceneSize.width - elementSize.width).toFloat(), value.y)
+ Offset((sceneSize.width - elementSize.width).toFloat(), idleValue.y)
}
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt
index c11ec97..ef769e7 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt
@@ -27,7 +27,7 @@
content: ContentKey,
element: ElementKey,
transition: TransitionState.Transition,
- value: Float,
+ idleValue: Float,
): Float {
// Return the alpha value of [element] either when it starts fading in or when it finished
// fading out, which is `0` in both cases.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt
index a159a5b..ef3654b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt
@@ -36,11 +36,11 @@
content: ContentKey,
element: ElementKey,
transition: TransitionState.Transition,
- value: IntSize,
+ idleValue: IntSize,
): IntSize {
return IntSize(
- width = (value.width * width).roundToInt(),
- height = (value.height * height).roundToInt(),
+ width = (idleValue.width * width).roundToInt(),
+ height = (idleValue.height * height).roundToInt(),
)
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
index d38067d..74a3ead 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
@@ -36,14 +36,6 @@
*/
val matcher: ElementMatcher
- /**
- * The range during which the transformation is applied. If it is `null`, then the
- * transformation will be applied throughout the whole scene transition.
- */
- // TODO(b/240432457): Move this back to PropertyTransformation.
- val range: TransformationRange?
- get() = null
-
/*
* Reverse this transformation. This is called when we use Transition(from = A, to = B) when
* animating from B to A and there is no Transition(from = B, to = A) defined.
@@ -66,14 +58,14 @@
* - the value at progress = 100% for elements that are leaving the layout (i.e. elements in the
* content we are transitioning from).
*
- * The returned value will be interpolated using the [transition] progress and [value], the
+ * The returned value will be interpolated using the [transition] progress and [idleValue], the
* value of the property when we are idle.
*/
fun PropertyTransformationScope.transform(
content: ContentKey,
element: ElementKey,
transition: TransitionState.Transition,
- value: T,
+ idleValue: T,
): T
}
@@ -82,20 +74,15 @@
val layoutDirection: LayoutDirection
}
-/**
- * A [PropertyTransformation] associated to a range. This is a helper class so that normal
- * implementations of [PropertyTransformation] don't have to take care of reversing their range when
- * they are reversed.
- */
-internal class RangedPropertyTransformation<T>(
- val delegate: PropertyTransformation<T>,
- override val range: TransformationRange,
-) : PropertyTransformation<T> by delegate {
- override fun reversed(): Transformation {
- return RangedPropertyTransformation(
- delegate.reversed() as PropertyTransformation<T>,
- range.reversed(),
- )
+/** A pair consisting of a [transformation] and optional [range]. */
+class TransformationWithRange<out T : Transformation>(
+ val transformation: T,
+ val range: TransformationRange?,
+) {
+ fun reversed(): TransformationWithRange<T> {
+ if (range == null) return this
+
+ return TransformationWithRange(transformation = transformation, range = range.reversed())
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt
index af0a6ed..356ed99 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt
@@ -35,9 +35,9 @@
content: ContentKey,
element: ElementKey,
transition: TransitionState.Transition,
- value: Offset,
+ idleValue: Offset,
): Offset {
- return Offset(value.x + x.toPx(), value.y + y.toPx())
+ return Offset(idleValue.x + x.toPx(), idleValue.y + y.toPx())
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt
index e924ebf..20a0b39 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt
@@ -207,6 +207,9 @@
}
override suspend fun onPreFling(available: Velocity): Velocity {
+ // Note: This method may be called multiple times. Due to NestedScrollDispatcher, the order
+ // of method calls (pre/post scroll/fling) cannot be guaranteed.
+ if (isStopping) return Velocity.Zero
val controller = currentController ?: return Velocity.Zero
// If in priority mode and can stop on pre-fling phase, stop the scroll.
@@ -219,6 +222,9 @@
}
override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
+ // Note: This method may be called multiple times. Due to NestedScrollDispatcher, the order
+ // of method calls (pre/post scroll/fling) cannot be guaranteed.
+ if (isStopping) return Velocity.Zero
val availableFloat = available.toFloat()
val controller = currentController
@@ -315,6 +321,7 @@
* @return The consumed velocity.
*/
suspend fun stop(velocity: Float): Velocity {
+ if (isStopping) return Velocity.Zero
val controller = requireController(isStopping = false)
return coroutineScope {
try {
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index 5dad0d7..098673e 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -101,10 +101,7 @@
scene(
key = SceneC,
userActions =
- mapOf(
- Swipe.Up to SceneB,
- Swipe(SwipeDirection.Up, fromSource = Edge.Bottom) to SceneA,
- ),
+ mapOf(Swipe.Up to SceneB, Swipe.Up(fromSource = Edge.Bottom) to SceneA),
) {
Text("SceneC")
}
@@ -1231,7 +1228,7 @@
assertTransition(
currentScene = SceneC,
fromScene = SceneC,
- // userAction: Swipe(SwipeDirection.Up, fromSource = Edge.Bottom) to SceneA
+ // userAction: Swipe.Up(fromSource = Edge.Bottom) to SceneA
toScene = SceneA,
progress = 0.1f,
)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index ee807e6..4a90515 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -869,10 +869,7 @@
state = state,
modifier = Modifier.size(layoutWidth, layoutHeight),
) {
- scene(
- SceneA,
- userActions = mapOf(Swipe(SwipeDirection.Down, pointerCount = 2) to SceneB),
- ) {
+ scene(SceneA, userActions = mapOf(Swipe.Down(pointerCount = 2) to SceneB)) {
Box(
Modifier
// A scrollable that does not consume the scroll gesture
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
index aaeaba9..3b2ee98 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
@@ -128,10 +128,10 @@
if (swipesEnabled())
mapOf(
Swipe.Down to SceneA,
- Swipe(SwipeDirection.Down, pointerCount = 2) to SceneB,
- Swipe(SwipeDirection.Down, pointersType = PointerType.Mouse) to SceneD,
- Swipe(SwipeDirection.Right, fromSource = Edge.Left) to SceneB,
- Swipe(SwipeDirection.Down, fromSource = Edge.Top) to SceneB,
+ Swipe.Down(pointerCount = 2) to SceneB,
+ Swipe.Down(pointersType = PointerType.Mouse) to SceneD,
+ Swipe.Down(fromSource = Edge.Top) to SceneB,
+ Swipe.Right(fromSource = Edge.Left) to SceneB,
)
else emptyMap(),
) {
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
index d66d6b3..d317114 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
@@ -28,8 +28,8 @@
import com.android.compose.animation.scene.TestScenes.SceneC
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.transformation.OverscrollTranslate
-import com.android.compose.animation.scene.transformation.Transformation
import com.android.compose.animation.scene.transformation.TransformationRange
+import com.android.compose.animation.scene.transformation.TransformationWithRange
import com.android.compose.test.transition
import com.google.common.truth.Correspondence
import com.google.common.truth.Truth.assertThat
@@ -310,7 +310,8 @@
}
val overscrollSpec = transitions.overscrollSpecs.single()
- val transformation = overscrollSpec.transformationSpec.transformations.single()
+ val transformation =
+ overscrollSpec.transformationSpec.transformations.single().transformation
assertThat(transformation).isInstanceOf(OverscrollTranslate::class.java)
}
@@ -344,7 +345,7 @@
companion object {
private val TRANSFORMATION_RANGE =
- Correspondence.transforming<Transformation, TransformationRange?>(
+ Correspondence.transforming<TransformationWithRange<*>, TransformationRange?>(
{ it?.range },
"has range equal to",
)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt
index 5442840..91079b8 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt
@@ -29,6 +29,8 @@
import com.android.compose.test.runMonotonicClockTest
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
@@ -262,4 +264,16 @@
scrollConnection.onPostFling(consumed = Velocity.Zero, available = Velocity.Zero)
assertThat(isStarted).isEqualTo(true)
}
+
+ @Test
+ fun handleMultipleOnPreFlingCalls() = runTest {
+ startPriorityModePostScroll()
+
+ coroutineScope {
+ launch { scrollConnection.onPreFling(available = Velocity.Zero) }
+ launch { scrollConnection.onPreFling(available = Velocity.Zero) }
+ }
+
+ assertThat(lastStop).isEqualTo(0f)
+ }
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index 7014826..300a3e2 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -55,7 +55,6 @@
private val layoutInflater: LayoutInflater,
private val resources: Resources,
private val settings: ClockSettings?,
- private val hasStepClockAnimation: Boolean = false,
private val migratedClocks: Boolean = false,
messageBuffers: ClockMessageBuffers? = null,
) : ClockController {
@@ -197,12 +196,11 @@
views[0].id =
resources.getIdentifier("lockscreen_clock_view_large", "id", ctx.packageName)
}
- override val config =
- ClockFaceConfig(hasCustomPositionUpdatedAnimation = hasStepClockAnimation)
+ override val config = ClockFaceConfig(hasCustomPositionUpdatedAnimation = true)
init {
view.migratedClocks = migratedClocks
- view.hasCustomPositionUpdatedAnimation = hasStepClockAnimation
+ view.hasCustomPositionUpdatedAnimation = true
animations = LargeClockAnimations(view, 0f, 0f)
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index e9b58b0..be4ebdf 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -38,7 +38,6 @@
val ctx: Context,
val layoutInflater: LayoutInflater,
val resources: Resources,
- private val hasStepClockAnimation: Boolean = false,
private val migratedClocks: Boolean = false,
private val isClockReactiveVariantsEnabled: Boolean = false,
) : ClockProvider {
@@ -75,7 +74,6 @@
layoutInflater,
resources,
settings,
- hasStepClockAnimation,
migratedClocks,
messageBuffers,
)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
index 0b55a6e..d86c0d6 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
@@ -39,7 +39,7 @@
val digitLeftTopMap = mutableMapOf<Int, Point>()
var maxSingleDigitSize = Point(-1, -1)
val lockscreenTranslate = Point(0, 0)
- val aodTranslate = Point(0, 0)
+ var aodTranslate = Point(0, 0)
init {
setWillNotDraw(false)
@@ -64,8 +64,7 @@
maxSingleDigitSize.y = max(maxSingleDigitSize.y, textView.measuredHeight)
}
val textView = digitalClockTextViewMap[R.id.HOUR_FIRST_DIGIT]!!
- aodTranslate.x = -(maxSingleDigitSize.x * AOD_HORIZONTAL_TRANSLATE_RATIO).toInt()
- aodTranslate.y = (maxSingleDigitSize.y * AOD_VERTICAL_TRANSLATE_RATIO).toInt()
+ aodTranslate = Point(0, 0)
return Point(
((maxSingleDigitSize.x + abs(aodTranslate.x)) * 2),
((maxSingleDigitSize.y + abs(aodTranslate.y)) * 2),
@@ -162,9 +161,6 @@
val AOD_TRANSITION_DURATION = 750L
val CHARGING_TRANSITION_DURATION = 300L
- val AOD_HORIZONTAL_TRANSLATE_RATIO = 0.15F
- val AOD_VERTICAL_TRANSLATE_RATIO = 0.075F
-
// Use the sign of targetTranslation to control the direction of digit translation
fun updateDirectionalTargetTranslate(id: Int, targetTranslation: Point): Point {
val outPoint = Point(targetTranslation)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
index c0899e3..5c84f2d 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
@@ -148,7 +148,11 @@
lsFontVariation = ClockFontAxisSetting.toFVar(axes + OPTICAL_SIZE_AXIS)
lockScreenPaint.typeface = typefaceCache.getTypefaceForVariant(lsFontVariation)
typeface = lockScreenPaint.typeface
- textAnimator.setTextStyle(fvar = lsFontVariation, animate = true)
+
+ lockScreenPaint.getTextBounds(text, 0, text.length, textBounds)
+ targetTextBounds.set(textBounds)
+
+ textAnimator.setTextStyle(fvar = lsFontVariation, animate = false)
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
recomputeMaxSingleDigitSizes()
requestLayout()
@@ -201,7 +205,7 @@
} else {
textBounds.height() + 2 * lockScreenPaint.strokeWidth.toInt()
},
- MeasureSpec.getMode(measuredHeight),
+ MeasureSpec.getMode(measuredHeightAndState),
)
}
@@ -215,10 +219,10 @@
} else {
max(
textBounds.width() + 2 * lockScreenPaint.strokeWidth.toInt(),
- MeasureSpec.getSize(measuredWidth),
+ MeasureSpec.getSize(measuredWidthAndState),
)
},
- MeasureSpec.getMode(measuredWidth),
+ MeasureSpec.getMode(measuredWidthAndState),
)
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepository.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepository.kt
index ae18aac..052e60e 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepository.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepository.kt
@@ -25,6 +25,9 @@
/** Returns a [Flow] tracking the value of a setting as an [Int]. */
fun intSetting(name: String, defaultValue: Int = 0): Flow<Int>
+ /** Returns a [Flow] tracking the value of a setting as a [Boolean]. */
+ fun boolSetting(name: String, defaultValue: Boolean = false): Flow<Boolean>
+
/** Updates the value of the setting with the given name. */
suspend fun setInt(name: String, value: Int)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepositoryImpl.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepositoryImpl.kt
index 8b9fcb4..9f37959 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepositoryImpl.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepositoryImpl.kt
@@ -63,6 +63,10 @@
.flowOn(backgroundDispatcher)
}
+ override fun boolSetting(name: String, defaultValue: Boolean): Flow<Boolean> {
+ return intSetting(name, if (defaultValue) 1 else 0).map { it != 0 }
+ }
+
override suspend fun setInt(name: String, value: Int) {
withContext(backgroundDispatcher) { Settings.Secure.putInt(contentResolver, name, value) }
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SystemSettingsRepository.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SystemSettingsRepository.kt
index 8cda9b3..b5f991c 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SystemSettingsRepository.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SystemSettingsRepository.kt
@@ -25,6 +25,9 @@
/** Returns a [Flow] tracking the value of a setting as an [Int]. */
fun intSetting(name: String, defaultValue: Int = 0): Flow<Int>
+ /** Returns a [Flow] tracking the value of a setting as a [Boolean]. */
+ fun boolSetting(name: String, defaultValue: Boolean = false): Flow<Boolean>
+
/** Updates the value of the setting with the given name. */
suspend fun setInt(name: String, value: Int)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SystemSettingsRepositoryImpl.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SystemSettingsRepositoryImpl.kt
index b039a32..8485d4d 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SystemSettingsRepositoryImpl.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SystemSettingsRepositoryImpl.kt
@@ -63,6 +63,10 @@
.flowOn(backgroundDispatcher)
}
+ override fun boolSetting(name: String, defaultValue: Boolean): Flow<Boolean> {
+ return intSetting(name, if (defaultValue) 1 else 0).map { it != 0 }
+ }
+
override suspend fun setInt(name: String, value: Int) {
withContext(backgroundDispatcher) { Settings.System.putInt(contentResolver, name, value) }
}
diff --git a/packages/SystemUI/customization/tests/utils/src/com/android/systemui/shared/settings/data/repository/FakeSecureSettingsRepository.kt b/packages/SystemUI/customization/tests/utils/src/com/android/systemui/shared/settings/data/repository/FakeSecureSettingsRepository.kt
index 37b9792..21d8d46 100644
--- a/packages/SystemUI/customization/tests/utils/src/com/android/systemui/shared/settings/data/repository/FakeSecureSettingsRepository.kt
+++ b/packages/SystemUI/customization/tests/utils/src/com/android/systemui/shared/settings/data/repository/FakeSecureSettingsRepository.kt
@@ -28,6 +28,10 @@
return settings.map { it.getOrDefault(name, defaultValue.toString()) }.map { it.toInt() }
}
+ override fun boolSetting(name: String, defaultValue: Boolean): Flow<Boolean> {
+ return intSetting(name, if (defaultValue) 1 else 0).map { it != 0 }
+ }
+
override suspend fun setInt(name: String, value: Int) {
settings.value = settings.value.toMutableMap().apply { this[name] = value.toString() }
}
diff --git a/packages/SystemUI/customization/tests/utils/src/com/android/systemui/shared/settings/data/repository/FakeSystemSettingsRepository.kt b/packages/SystemUI/customization/tests/utils/src/com/android/systemui/shared/settings/data/repository/FakeSystemSettingsRepository.kt
index 7da2b40..f6c053f 100644
--- a/packages/SystemUI/customization/tests/utils/src/com/android/systemui/shared/settings/data/repository/FakeSystemSettingsRepository.kt
+++ b/packages/SystemUI/customization/tests/utils/src/com/android/systemui/shared/settings/data/repository/FakeSystemSettingsRepository.kt
@@ -28,6 +28,10 @@
return settings.map { it.getOrDefault(name, defaultValue.toString()) }.map { it.toInt() }
}
+ override fun boolSetting(name: String, defaultValue: Boolean): Flow<Boolean> {
+ return intSetting(name, if (defaultValue) 1 else 0).map { it != 0 }
+ }
+
override suspend fun setInt(name: String, value: Int) {
settings.value = settings.value.toMutableMap().apply { this[name] = value.toString() }
}
diff --git a/packages/SystemUI/docs/demo_mode.md b/packages/SystemUI/docs/demo_mode.md
index ade5171..c18d1f1 100644
--- a/packages/SystemUI/docs/demo_mode.md
+++ b/packages/SystemUI/docs/demo_mode.md
@@ -35,6 +35,7 @@
| | ```fully``` | | Sets MCS state to fully connected (```true```, ```false```)
| | ```wifi``` | | ```show``` to show icon, any other value to hide
| | | ```level``` | Sets wifi level (null or 0-4)
+| | | ```hotspot``` | Sets the wifi to be from an Instant Hotspot. Values: ```none```, ```unknown```, ```phone```, ```tablet```, ```laptop```, ```watch```, ```auto```. (See `DemoModeWifiDataSource.kt`.)
| | ```mobile``` | | ```show``` to show icon, any other value to hide
| | | ```datatype``` | Values: ```1x```, ```3g```, ```4g```, ```e```, ```g```, ```h```, ```lte```, ```roam```, any other value to hide
| | | ```level``` | Sets mobile signal strength level (null or 0-4)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
index c74d340..b087ecf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
@@ -19,7 +19,6 @@
import static com.android.systemui.accessibility.MagnificationImpl.DELAY_SHOW_MAGNIFICATION_TIMEOUT_MS;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -190,8 +189,7 @@
@Test
public void showMagnificationButton_delayedShowButton() throws RemoteException {
- // magnification settings panel should not be showing
- assertFalse(mMagnification.isMagnificationSettingsPanelShowing(TEST_DISPLAY));
+ when(mMagnificationSettingsController.isMagnificationSettingsShowing()).thenReturn(false);
mIMagnificationConnection.showMagnificationButton(TEST_DISPLAY,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
@@ -237,8 +235,7 @@
@Test
public void removeMagnificationButton_delayingShowButton_doNotShowButtonAfterTimeout()
throws RemoteException {
- // magnification settings panel should not be showing
- assertFalse(mMagnification.isMagnificationSettingsPanelShowing(TEST_DISPLAY));
+ when(mMagnificationSettingsController.isMagnificationSettingsShowing()).thenReturn(false);
mIMagnificationConnection.showMagnificationButton(TEST_DISPLAY,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/OWNERS b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/OWNERS
new file mode 100644
index 0000000..a2001e6
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/accessibility/OWNERS
\ No newline at end of file
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 25696bf..f41d5c8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
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.view.Choreographer.FrameCallback;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowInsets.Type.systemGestures;
@@ -28,14 +27,8 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.hasItems;
-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.assertThat;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.AdditionalAnswers.returnsSecondArg;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
@@ -45,13 +38,17 @@
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static java.util.Arrays.asList;
+
import android.animation.ValueAnimator;
import android.annotation.IdRes;
import android.annotation.Nullable;
@@ -63,38 +60,36 @@
import android.graphics.Insets;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.Region;
-import android.graphics.RegionIterator;
import android.os.Handler;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
import android.testing.TestableLooper;
import android.testing.TestableResources;
-import android.text.TextUtils;
import android.util.Size;
+import android.view.AttachedSurfaceControl;
import android.view.Display;
-import android.view.IWindowSession;
+import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewRootImpl;
import android.view.WindowInsets;
import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
+import android.widget.FrameLayout;
+import android.window.InputTransferToken;
import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
-import com.android.app.viewcapture.ViewCapture;
-import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
-import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.AnimatorTestRule;
@@ -109,8 +104,6 @@
import com.google.common.util.concurrent.AtomicDouble;
-import kotlin.Lazy;
-
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
@@ -118,31 +111,27 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
@LargeTest
@TestableLooper.RunWithLooper
@RunWith(AndroidJUnit4.class)
-@RequiresFlagsDisabled(Flags.FLAG_CREATE_WINDOWLESS_WINDOW_MAGNIFIER)
public class WindowMagnificationControllerTest extends SysuiTestCase {
@Rule
// NOTE: pass 'null' to allow this test advances time on the main thread.
- public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(null);
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+ public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(/* test= */ null);
private static final int LAYOUT_CHANGE_TIMEOUT_MS = 5000;
@Mock
- private SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
- @Mock
private MirrorWindowControl mMirrorWindowControl;
@Mock
private WindowMagnifierCallback mWindowMagnifierCallback;
@@ -150,12 +139,10 @@
IRemoteMagnificationAnimationCallback mAnimationCallback;
@Mock
IRemoteMagnificationAnimationCallback mAnimationCallback2;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
+
+ private SurfaceControl.Transaction mTransaction;
@Mock
private SecureSettings mSecureSettings;
- @Mock
- private Lazy<ViewCapture> mLazyViewCapture;
private long mWaitAnimationDuration;
private long mWaitBounceEffectDuration;
@@ -170,11 +157,17 @@
private final ValueAnimator mValueAnimator = ValueAnimator.ofFloat(0, 1.0f).setDuration(0);
private final FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
- private IWindowSession mWindowSessionSpy;
-
private View mSpyView;
private View.OnTouchListener mTouchListener;
+
private MotionEventHelper mMotionEventHelper = new MotionEventHelper();
+
+ // This list contains all SurfaceControlViewHosts created during a given test. If the
+ // magnification window is recreated during a test, the list will contain more than a single
+ // element.
+ private List<SurfaceControlViewHost> mSurfaceControlViewHosts = new ArrayList<>();
+ // The most recently created SurfaceControlViewHost.
+ private SurfaceControlViewHost mSurfaceControlViewHost;
private KosmosJavaAdapter mKosmos;
private FakeSharedPreferences mSharedPreferences;
@@ -196,15 +189,7 @@
final WindowManager wm = mContext.getSystemService(WindowManager.class);
mWindowManager = spy(new TestableWindowManager(wm));
- mWindowSessionSpy = spy(WindowManagerGlobal.getWindowSession());
-
mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
- doAnswer(invocation -> {
- FrameCallback callback = invocation.getArgument(0);
- callback.doFrame(0);
- return null;
- }).when(mSfVsyncFrameProvider).postFrameCallback(
- any(FrameCallback.class));
mSysUiState = new SysUiState(mDisplayTracker, mKosmos.getSceneContainerPlugin());
mSysUiState.addCallback(Mockito.mock(SysUiState.SysUiStateCallback.class));
when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).then(
@@ -228,13 +213,20 @@
mWindowMagnificationAnimationController = new WindowMagnificationAnimationController(
mContext, mValueAnimator);
+ Supplier<SurfaceControlViewHost> scvhSupplier = () -> {
+ mSurfaceControlViewHost = spy(new SurfaceControlViewHost(
+ mContext, mContext.getDisplay(), new InputTransferToken(),
+ "WindowMagnification"));
+ ViewRootImpl viewRoot = mock(ViewRootImpl.class);
+ when(mSurfaceControlViewHost.getRootSurfaceControl()).thenReturn(viewRoot);
+ mSurfaceControlViewHosts.add(mSurfaceControlViewHost);
+ return mSurfaceControlViewHost;
+ };
+ mTransaction = spy(new SurfaceControl.Transaction());
mSharedPreferences = new FakeSharedPreferences();
when(mContext.getSharedPreferences(
eq("window_magnification_preferences"), anyInt()))
.thenReturn(mSharedPreferences);
- ViewCaptureAwareWindowManager viewCaptureAwareWindowManager = new
- ViewCaptureAwareWindowManager(mWindowManager, mLazyViewCapture,
- /* isViewCaptureEnabled= */ false);
mWindowMagnificationController =
new WindowMagnificationController(
mContext,
@@ -245,10 +237,7 @@
mWindowMagnifierCallback,
mSysUiState,
mSecureSettings,
- /* scvhSupplier= */ () -> null,
- mSfVsyncFrameProvider,
- /* globalWindowSessionSupplier= */ () -> mWindowSessionSpy,
- viewCaptureAwareWindowManager);
+ scvhSupplier);
verify(mMirrorWindowControl).setWindowDelegate(
any(MirrorWindowControl.MirrorWindowDelegate.class));
@@ -277,7 +266,7 @@
verify(mSecureSettings).getIntForUser(
eq(Settings.Secure.ACCESSIBILITY_ALLOW_DIAGONAL_SCROLLING),
/* def */ eq(1), /* userHandle= */ anyInt());
- assertTrue(mWindowMagnificationController.isDiagonalScrollingEnabled());
+ assertThat(mWindowMagnificationController.isDiagonalScrollingEnabled()).isTrue();
}
@Test
@@ -325,7 +314,8 @@
});
advanceTimeBy(LAYOUT_CHANGE_TIMEOUT_MS);
- verify(mSfVsyncFrameProvider, atLeast(2)).postFrameCallback(any());
+ verify(mTransaction, atLeastOnce()).setGeometry(any(), any(), any(),
+ eq(Surface.ROTATION_0));
}
@Test
@@ -342,10 +332,10 @@
final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
verify(mWindowMagnifierCallback, atLeast(2)).onSourceBoundsChanged(
(eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
- assertEquals(mWindowMagnificationController.getCenterX(),
- sourceBoundsCaptor.getValue().exactCenterX(), 0);
- assertEquals(mWindowMagnificationController.getCenterY(),
- sourceBoundsCaptor.getValue().exactCenterY(), 0);
+ assertThat(mWindowMagnificationController.getCenterX())
+ .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
+ assertThat(mWindowMagnificationController.getCenterY())
+ .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
}
@Test
@@ -357,8 +347,8 @@
// Wait for Rects updated.
waitForIdleSync();
- List<Rect> rects = mWindowManager.getAttachedView().getSystemGestureExclusionRects();
- assertFalse(rects.isEmpty());
+ List<Rect> rects = mSurfaceControlViewHost.getView().getSystemGestureExclusionRects();
+ assertThat(rects).isNotEmpty();
}
@Ignore("The default window size should be constrained after fixing b/288056772")
@@ -373,11 +363,11 @@
});
final int halfScreenSize = screenSize / 2;
- WindowManager.LayoutParams params = mWindowManager.getLayoutParamsFromAttachedView();
+ ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
// The frame size should be the half of smaller value of window height/width unless it
//exceed the max frame size.
- assertTrue(params.width < halfScreenSize);
- assertTrue(params.height < halfScreenSize);
+ assertThat(params.width).isLessThan(halfScreenSize);
+ assertThat(params.height).isLessThan(halfScreenSize);
}
@Test
@@ -411,7 +401,7 @@
});
verify(mMirrorWindowControl).destroyControl();
- assertFalse(hasMagnificationOverlapFlag());
+ assertThat(hasMagnificationOverlapFlag()).isFalse();
}
@Test
@@ -435,10 +425,14 @@
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
- mWindowMagnificationController.moveWindowMagnifier(100f, 100f);
});
- verify(mSfVsyncFrameProvider, atLeastOnce()).postFrameCallback(any());
+ waitForIdleSync();
+ mInstrumentation.runOnMainSync(
+ () -> mWindowMagnificationController.moveWindowMagnifier(100f, 100f));
+
+ verify(mTransaction, atLeastOnce()).setGeometry(any(), any(), any(),
+ eq(Surface.ROTATION_0));
}
@Test
@@ -455,6 +449,7 @@
final float targetCenterX = sourceBoundsCaptor.getValue().exactCenterX() + 10;
final float targetCenterY = sourceBoundsCaptor.getValue().exactCenterY() + 10;
+ reset(mWindowMagnifierCallback);
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.moveWindowMagnifierToPosition(
targetCenterX, targetCenterY, mAnimationCallback);
@@ -465,12 +460,12 @@
verify(mAnimationCallback, never()).onResult(eq(false));
verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
.onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
- assertEquals(mWindowMagnificationController.getCenterX(),
- sourceBoundsCaptor.getValue().exactCenterX(), 0);
- assertEquals(mWindowMagnificationController.getCenterY(),
- sourceBoundsCaptor.getValue().exactCenterY(), 0);
- assertEquals(mWindowMagnificationController.getCenterX(), targetCenterX, 0);
- assertEquals(mWindowMagnificationController.getCenterY(), targetCenterY, 0);
+ assertThat(mWindowMagnificationController.getCenterX())
+ .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
+ assertThat(mWindowMagnificationController.getCenterY())
+ .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
+ assertThat(mWindowMagnificationController.getCenterX()).isEqualTo(targetCenterX);
+ assertThat(mWindowMagnificationController.getCenterY()).isEqualTo(targetCenterY);
}
@Test
@@ -487,6 +482,7 @@
final float centerX = sourceBoundsCaptor.getValue().exactCenterX();
final float centerY = sourceBoundsCaptor.getValue().exactCenterY();
+ reset(mWindowMagnifierCallback);
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.moveWindowMagnifierToPosition(
centerX + 10, centerY + 10, mAnimationCallback);
@@ -505,12 +501,12 @@
verify(mAnimationCallback, times(3)).onResult(eq(false));
verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
.onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
- assertEquals(mWindowMagnificationController.getCenterX(),
- sourceBoundsCaptor.getValue().exactCenterX(), 0);
- assertEquals(mWindowMagnificationController.getCenterY(),
- sourceBoundsCaptor.getValue().exactCenterY(), 0);
- assertEquals(mWindowMagnificationController.getCenterX(), centerX + 40, 0);
- assertEquals(mWindowMagnificationController.getCenterY(), centerY + 40, 0);
+ assertThat(mWindowMagnificationController.getCenterX())
+ .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
+ assertThat(mWindowMagnificationController.getCenterY())
+ .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
+ assertThat(mWindowMagnificationController.getCenterX()).isEqualTo(centerX + 40);
+ assertThat(mWindowMagnificationController.getCenterY()).isEqualTo(centerY + 40);
}
@Test
@@ -521,10 +517,10 @@
mInstrumentation.runOnMainSync(() -> mWindowMagnificationController.setScale(3.0f));
- assertEquals(3.0f, mWindowMagnificationController.getScale(), 0);
- final View mirrorView = mWindowManager.getAttachedView();
- assertNotNull(mirrorView);
- assertThat(mirrorView.getStateDescription().toString(), containsString("300"));
+ assertThat(mWindowMagnificationController.getScale()).isEqualTo(3.0f);
+ final View mirrorView = mSurfaceControlViewHost.getView();
+ assertThat(mirrorView).isNotNull();
+ assertThat(mirrorView.getStateDescription().toString()).contains("300");
}
@Test
@@ -563,12 +559,12 @@
mInstrumentation.runOnMainSync(() -> mWindowMagnificationController.onConfigurationChanged(
ActivityInfo.CONFIG_ORIENTATION));
- assertEquals(newRotation, mWindowMagnificationController.mRotation);
+ assertThat(mWindowMagnificationController.mRotation).isEqualTo(newRotation);
final PointF expectedCenter = new PointF(magnifiedCenter.y,
displayWidth - magnifiedCenter.x);
final PointF actualCenter = new PointF(mWindowMagnificationController.getCenterX(),
mWindowMagnificationController.getCenterY());
- assertEquals(expectedCenter, actualCenter);
+ assertThat(actualCenter).isEqualTo(expectedCenter);
}
@Test
@@ -583,7 +579,7 @@
mInstrumentation.runOnMainSync(() -> mWindowMagnificationController.onConfigurationChanged(
ActivityInfo.CONFIG_ORIENTATION));
- assertEquals(newRotation, mWindowMagnificationController.mRotation);
+ assertThat(mWindowMagnificationController.mRotation).isEqualTo(newRotation);
}
@Test
@@ -610,14 +606,13 @@
});
// The ratio of center to window size should be the same.
- assertEquals(expectedRatio,
- mWindowMagnificationController.getCenterX() / testWindowBounds.width(),
- 0);
- assertEquals(expectedRatio,
- mWindowMagnificationController.getCenterY() / testWindowBounds.height(),
- 0);
+ assertThat(mWindowMagnificationController.getCenterX() / testWindowBounds.width())
+ .isEqualTo(expectedRatio);
+ assertThat(mWindowMagnificationController.getCenterY() / testWindowBounds.height())
+ .isEqualTo(expectedRatio);
}
+ @DisableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
@Test
public void onScreenSizeAndDensityChanged_enabled_restoreSavedMagnifierWindow() {
int newSmallestScreenWidthDp =
@@ -635,7 +630,7 @@
Float.NaN);
});
- // Change screen density and size to trigger restoring the preferred window size
+ // Screen density and size change
mContext.getResources().getConfiguration().smallestScreenWidthDp = newSmallestScreenWidthDp;
final Rect testWindowBounds = new Rect(
mWindowManager.getCurrentWindowMetrics().getBounds());
@@ -648,12 +643,56 @@
// wait for rect update
waitForIdleSync();
- WindowManager.LayoutParams params = mWindowManager.getLayoutParamsFromAttachedView();
+ ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
R.dimen.magnification_mirror_surface_margin);
// The width and height of the view include the magnification frame and the margins.
- assertTrue(params.width == (windowFrameSize + 2 * mirrorSurfaceMargin));
- assertTrue(params.height == (windowFrameSize + 2 * mirrorSurfaceMargin));
+ assertThat(params.width).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
+ assertThat(params.height).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
+ }
+
+ @EnableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
+ @Test
+ public void onScreenSizeAndDensityChanged_enabled_restoreSavedMagnifierIndexAndWindow() {
+ int newSmallestScreenWidthDp =
+ mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
+ int windowFrameSize = mResources.getDimensionPixelSize(
+ com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
+ Size preferredWindowSize = new Size(windowFrameSize, windowFrameSize);
+ mSharedPreferences
+ .edit()
+ .putString(String.valueOf(newSmallestScreenWidthDp),
+ WindowMagnificationFrameSpec.serialize(
+ WindowMagnificationSettings.MagnificationSize.CUSTOM,
+ preferredWindowSize))
+ .commit();
+ mInstrumentation.runOnMainSync(() -> {
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
+ Float.NaN);
+ });
+
+ // Screen density and size change
+ mContext.getResources().getConfiguration().smallestScreenWidthDp = newSmallestScreenWidthDp;
+ final Rect testWindowBounds = new Rect(
+ mWindowManager.getCurrentWindowMetrics().getBounds());
+ testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
+ testWindowBounds.right + 100, testWindowBounds.bottom + 100);
+ mWindowManager.setWindowBounds(testWindowBounds);
+ mInstrumentation.runOnMainSync(() -> {
+ mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
+ });
+
+ // wait for rect update
+ waitForIdleSync();
+ verify(mWindowMagnifierCallback).onWindowMagnifierBoundsRestored(
+ eq(mContext.getDisplayId()),
+ eq(WindowMagnificationSettings.MagnificationSize.CUSTOM));
+ ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
+ final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
+ R.dimen.magnification_mirror_surface_margin);
+ // The width and height of the view include the magnification frame and the margins.
+ assertThat(params.width).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
+ assertThat(params.height).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
}
@Test
@@ -675,10 +714,10 @@
final int defaultWindowSize =
mWindowMagnificationController.getMagnificationWindowSizeFromIndex(
WindowMagnificationSettings.MagnificationSize.MEDIUM);
- WindowManager.LayoutParams params = mWindowManager.getLayoutParamsFromAttachedView();
+ ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
- assertTrue(params.width == defaultWindowSize);
- assertTrue(params.height == defaultWindowSize);
+ assertThat(params.width).isEqualTo(defaultWindowSize);
+ assertThat(params.height).isEqualTo(defaultWindowSize);
}
@Test
@@ -695,9 +734,9 @@
});
verify(mResources, atLeastOnce()).getDimensionPixelSize(anyInt());
- verify(mWindowManager).removeView(any());
+ verify(mSurfaceControlViewHosts.get(0)).release();
verify(mMirrorWindowControl).destroyControl();
- verify(mWindowManager).addView(any(), any());
+ verify(mSurfaceControlViewHosts.get(1)).setView(any(), any());
verify(mMirrorWindowControl).showControl();
}
@@ -716,21 +755,30 @@
mWindowMagnificationController.updateWindowMagnificationInternal(2.5f, Float.NaN,
Float.NaN);
});
- final View mirrorView = mWindowManager.getAttachedView();
- assertNotNull(mirrorView);
+ final View mirrorView = mSurfaceControlViewHost.getView();
+ assertThat(mirrorView).isNotNull();
final AccessibilityNodeInfo nodeInfo = new AccessibilityNodeInfo();
mirrorView.onInitializeAccessibilityNodeInfo(nodeInfo);
- assertNotNull(nodeInfo.getContentDescription());
- assertThat(nodeInfo.getStateDescription().toString(), containsString("250"));
- assertThat(nodeInfo.getActionList(),
- hasItems(new AccessibilityAction(R.id.accessibility_action_zoom_in, null),
- new AccessibilityAction(R.id.accessibility_action_zoom_out, null),
- new AccessibilityAction(R.id.accessibility_action_move_right, null),
- new AccessibilityAction(R.id.accessibility_action_move_left, null),
- new AccessibilityAction(R.id.accessibility_action_move_down, null),
- new AccessibilityAction(R.id.accessibility_action_move_up, null)));
+ assertThat(nodeInfo.getContentDescription()).isNotNull();
+ assertThat(nodeInfo.getStateDescription().toString()).contains("250");
+ assertThat(nodeInfo.getActionList()).containsExactlyElementsIn(asList(
+ new AccessibilityAction(AccessibilityAction.ACTION_CLICK.getId(),
+ mContext.getResources().getString(
+ R.string.magnification_open_settings_click_label)),
+ new AccessibilityAction(R.id.accessibility_action_zoom_in,
+ mContext.getString(R.string.accessibility_control_zoom_in)),
+ new AccessibilityAction(R.id.accessibility_action_zoom_out,
+ mContext.getString(R.string.accessibility_control_zoom_out)),
+ new AccessibilityAction(R.id.accessibility_action_move_right,
+ mContext.getString(R.string.accessibility_control_move_right)),
+ new AccessibilityAction(R.id.accessibility_action_move_left,
+ mContext.getString(R.string.accessibility_control_move_left)),
+ new AccessibilityAction(R.id.accessibility_action_move_down,
+ mContext.getString(R.string.accessibility_control_move_down)),
+ new AccessibilityAction(R.id.accessibility_action_move_up,
+ mContext.getString(R.string.accessibility_control_move_up))));
}
@Test
@@ -741,29 +789,34 @@
Float.NaN);
});
- final View mirrorView = mWindowManager.getAttachedView();
- assertTrue(
- mirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_out, null));
+ final View mirrorView = mSurfaceControlViewHost.getView();
+ assertThat(mirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_out, null))
+ .isTrue();
// Minimum scale is 1.0.
verify(mWindowMagnifierCallback).onPerformScaleAction(
eq(displayId), /* scale= */ eq(1.0f), /* updatePersistence= */ eq(true));
- assertTrue(mirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_in, null));
+ assertThat(mirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_in, null))
+ .isTrue();
verify(mWindowMagnifierCallback).onPerformScaleAction(
eq(displayId), /* scale= */ eq(2.5f), /* updatePersistence= */ eq(true));
// TODO: Verify the final state when the mirror surface is visible.
- assertTrue(mirrorView.performAccessibilityAction(R.id.accessibility_action_move_up, null));
- assertTrue(
- mirrorView.performAccessibilityAction(R.id.accessibility_action_move_down, null));
- assertTrue(
- mirrorView.performAccessibilityAction(R.id.accessibility_action_move_right, null));
- assertTrue(
- mirrorView.performAccessibilityAction(R.id.accessibility_action_move_left, null));
+ assertThat(mirrorView.performAccessibilityAction(R.id.accessibility_action_move_up, null))
+ .isTrue();
+ assertThat(
+ mirrorView.performAccessibilityAction(R.id.accessibility_action_move_down, null))
+ .isTrue();
+ assertThat(
+ mirrorView.performAccessibilityAction(R.id.accessibility_action_move_right, null))
+ .isTrue();
+ assertThat(
+ mirrorView.performAccessibilityAction(R.id.accessibility_action_move_left, null))
+ .isTrue();
verify(mWindowMagnifierCallback, times(4)).onMove(eq(displayId));
- assertTrue(mirrorView.performAccessibilityAction(
- AccessibilityAction.ACTION_CLICK.getId(), null));
+ assertThat(mirrorView.performAccessibilityAction(
+ AccessibilityAction.ACTION_CLICK.getId(), null)).isTrue();
verify(mWindowMagnifierCallback).onClickSettingsButton(eq(displayId));
}
@@ -775,7 +828,7 @@
Float.NaN);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
mirrorView.performAccessibilityAction(R.id.accessibility_action_move_up, null);
verify(mWindowMagnifierCallback).onAccessibilityActionPerformed(eq(displayId));
@@ -795,20 +848,22 @@
View topRightCorner = getInternalView(R.id.top_right_corner);
View topLeftCorner = getInternalView(R.id.top_left_corner);
- assertEquals(View.VISIBLE, closeButton.getVisibility());
- assertEquals(View.VISIBLE, bottomRightCorner.getVisibility());
- assertEquals(View.VISIBLE, bottomLeftCorner.getVisibility());
- assertEquals(View.VISIBLE, topRightCorner.getVisibility());
- assertEquals(View.VISIBLE, topLeftCorner.getVisibility());
+ assertThat(closeButton.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(bottomRightCorner.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(bottomLeftCorner.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(topRightCorner.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(topLeftCorner.getVisibility()).isEqualTo(View.VISIBLE);
- final View mirrorView = mWindowManager.getAttachedView();
- mirrorView.performAccessibilityAction(AccessibilityAction.ACTION_CLICK.getId(), null);
+ final View mirrorView = mSurfaceControlViewHost.getView();
+ mInstrumentation.runOnMainSync(() ->
+ mirrorView.performAccessibilityAction(AccessibilityAction.ACTION_CLICK.getId(),
+ null));
- assertEquals(View.GONE, closeButton.getVisibility());
- assertEquals(View.GONE, bottomRightCorner.getVisibility());
- assertEquals(View.GONE, bottomLeftCorner.getVisibility());
- assertEquals(View.GONE, topRightCorner.getVisibility());
- assertEquals(View.GONE, topLeftCorner.getVisibility());
+ assertThat(closeButton.getVisibility()).isEqualTo(View.GONE);
+ assertThat(bottomRightCorner.getVisibility()).isEqualTo(View.GONE);
+ assertThat(bottomLeftCorner.getVisibility()).isEqualTo(View.GONE);
+ assertThat(topRightCorner.getVisibility()).isEqualTo(View.GONE);
+ assertThat(topLeftCorner.getVisibility()).isEqualTo(View.GONE);
}
@Test
@@ -828,7 +883,7 @@
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
final AtomicInteger actualWindowHeight = new AtomicInteger();
final AtomicInteger actualWindowWidth = new AtomicInteger();
@@ -836,8 +891,10 @@
() -> {
mirrorView.performAccessibilityAction(
R.id.accessibility_action_increase_window_width, null);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().width);
});
final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
@@ -847,8 +904,8 @@
int newWindowWidth =
(int) ((startingWidth - 2 * mirrorSurfaceMargin) * (1 + changeWindowSizeAmount))
+ 2 * mirrorSurfaceMargin;
- assertEquals(newWindowWidth, actualWindowWidth.get());
- assertEquals(startingHeight, actualWindowHeight.get());
+ assertThat(actualWindowWidth.get()).isEqualTo(newWindowWidth);
+ assertThat(actualWindowHeight.get()).isEqualTo(startingHeight);
}
@Test
@@ -868,7 +925,7 @@
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
final AtomicInteger actualWindowHeight = new AtomicInteger();
final AtomicInteger actualWindowWidth = new AtomicInteger();
@@ -876,8 +933,10 @@
() -> {
mirrorView.performAccessibilityAction(
R.id.accessibility_action_increase_window_height, null);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().width);
});
final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
@@ -887,8 +946,8 @@
int newWindowHeight =
(int) ((startingHeight - 2 * mirrorSurfaceMargin) * (1 + changeWindowSizeAmount))
+ 2 * mirrorSurfaceMargin;
- assertEquals(startingWidth, actualWindowWidth.get());
- assertEquals(newWindowHeight, actualWindowHeight.get());
+ assertThat(actualWindowWidth.get()).isEqualTo(startingWidth);
+ assertThat(actualWindowHeight.get()).isEqualTo(newWindowHeight);
}
@Test
@@ -904,11 +963,14 @@
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
final AccessibilityNodeInfo accessibilityNodeInfo =
mirrorView.createAccessibilityNodeInfo();
- assertFalse(accessibilityNodeInfo.getActionList().contains(
- new AccessibilityAction(R.id.accessibility_action_increase_window_width, null)));
+ assertThat(accessibilityNodeInfo.getActionList()).doesNotContain(
+ new AccessibilityAction(
+ R.id.accessibility_action_increase_window_width,
+ mContext.getString(
+ R.string.accessibility_control_increase_window_width)));
}
@Test
@@ -924,11 +986,12 @@
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
final AccessibilityNodeInfo accessibilityNodeInfo =
mirrorView.createAccessibilityNodeInfo();
- assertFalse(accessibilityNodeInfo.getActionList().contains(
- new AccessibilityAction(R.id.accessibility_action_increase_window_height, null)));
+ assertThat(accessibilityNodeInfo.getActionList()).doesNotContain(
+ new AccessibilityAction(
+ R.id.accessibility_action_increase_window_height, null));
}
@Test
@@ -947,7 +1010,7 @@
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
final AtomicInteger actualWindowHeight = new AtomicInteger();
final AtomicInteger actualWindowWidth = new AtomicInteger();
@@ -955,8 +1018,10 @@
() -> {
mirrorView.performAccessibilityAction(
R.id.accessibility_action_decrease_window_width, null);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().width);
});
final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
@@ -966,8 +1031,8 @@
int newWindowWidth =
(int) ((startingSize - 2 * mirrorSurfaceMargin) * (1 - changeWindowSizeAmount))
+ 2 * mirrorSurfaceMargin;
- assertEquals(newWindowWidth, actualWindowWidth.get());
- assertEquals(startingSize, actualWindowHeight.get());
+ assertThat(actualWindowWidth.get()).isEqualTo(newWindowWidth);
+ assertThat(actualWindowHeight.get()).isEqualTo(startingSize);
}
@Test
@@ -987,7 +1052,7 @@
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
final AtomicInteger actualWindowHeight = new AtomicInteger();
final AtomicInteger actualWindowWidth = new AtomicInteger();
@@ -995,8 +1060,10 @@
() -> {
mirrorView.performAccessibilityAction(
R.id.accessibility_action_decrease_window_height, null);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().width);
});
final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
@@ -1006,8 +1073,8 @@
int newWindowHeight =
(int) ((startingSize - 2 * mirrorSurfaceMargin) * (1 - changeWindowSizeAmount))
+ 2 * mirrorSurfaceMargin;
- assertEquals(startingSize, actualWindowWidth.get());
- assertEquals(newWindowHeight, actualWindowHeight.get());
+ assertThat(actualWindowWidth.get()).isEqualTo(startingSize);
+ assertThat(actualWindowHeight.get()).isEqualTo(newWindowHeight);
}
@Test
@@ -1023,15 +1090,16 @@
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
final AccessibilityNodeInfo accessibilityNodeInfo =
mirrorView.createAccessibilityNodeInfo();
- assertFalse(accessibilityNodeInfo.getActionList().contains(
- new AccessibilityAction(R.id.accessibility_action_decrease_window_width, null)));
+ assertThat(accessibilityNodeInfo.getActionList()).doesNotContain(
+ new AccessibilityAction(
+ R.id.accessibility_action_decrease_window_width, null));
}
@Test
- public void windowHeightIsMin_noDecreaseWindowHeightA11yAcyion() {
+ public void windowHeightIsMin_noDecreaseWindowHeightA11yAction() {
int mMinWindowSize = mResources.getDimensionPixelSize(
com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
final int startingSize = mMinWindowSize;
@@ -1043,11 +1111,12 @@
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
final AccessibilityNodeInfo accessibilityNodeInfo =
mirrorView.createAccessibilityNodeInfo();
- assertFalse(accessibilityNodeInfo.getActionList().contains(
- new AccessibilityAction(R.id.accessibility_action_decrease_window_height, null)));
+ assertThat(accessibilityNodeInfo.getActionList()).doesNotContain(
+ new AccessibilityAction(
+ R.id.accessibility_action_decrease_window_height, null));
}
@Test
@@ -1057,8 +1126,8 @@
Float.NaN);
});
- assertEquals(getContext().getResources().getString(
- com.android.internal.R.string.android_system_label), getAccessibilityWindowTitle());
+ assertThat(getAccessibilityWindowTitle()).isEqualTo(getContext().getResources().getString(
+ com.android.internal.R.string.android_system_label));
}
@Test
@@ -1073,14 +1142,14 @@
Float.NaN);
});
- assertEquals(Float.NaN, mWindowMagnificationController.getScale(), 0);
+ assertThat(mWindowMagnificationController.getScale()).isEqualTo(Float.NaN);
}
@Test
public void enableWindowMagnification_rotationIsChanged_updateRotationValue() {
// the config orientation should not be undefined, since it would cause config.diff
// returning 0 and thus the orientation changed would not be detected
- assertNotEquals(ORIENTATION_UNDEFINED, mResources.getConfiguration().orientation);
+ assertThat(mResources.getConfiguration().orientation).isNotEqualTo(ORIENTATION_UNDEFINED);
final Configuration config = mResources.getConfiguration();
config.orientation = config.orientation == ORIENTATION_LANDSCAPE ? ORIENTATION_PORTRAIT
@@ -1091,7 +1160,7 @@
() -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
- assertEquals(newRotation, mWindowMagnificationController.mRotation);
+ assertThat(mWindowMagnificationController.mRotation).isEqualTo(newRotation);
}
@Test
@@ -1119,7 +1188,7 @@
mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_LOCALE);
});
- assertTrue(TextUtils.equals(newA11yWindowTitle, getAccessibilityWindowTitle()));
+ assertThat(getAccessibilityWindowTitle()).isEqualTo(newA11yWindowTitle);
}
@Ignore("it's flaky in presubmit but works in abtd, filter for now. b/305654925")
@@ -1134,7 +1203,7 @@
mWindowMagnificationController.onSingleTap(mSpyView);
});
- final View mirrorView = mWindowManager.getAttachedView();
+ final View mirrorView = mSurfaceControlViewHost.getView();
final AtomicDouble maxScaleX = new AtomicDouble();
advanceTimeBy(mWaitBounceEffectDuration, /* runnableOnEachRefresh= */ () -> {
@@ -1142,10 +1211,10 @@
// maxScaleX.getAndAccumulate(mirrorView.getScaleX(), Math::max);
final double oldMax = maxScaleX.get();
final double newMax = Math.max(mirrorView.getScaleX(), oldMax);
- assertTrue(maxScaleX.compareAndSet(oldMax, newMax));
+ assertThat(maxScaleX.compareAndSet(oldMax, newMax)).isTrue();
});
- assertTrue(maxScaleX.get() > 1.0);
+ assertThat(maxScaleX.get()).isGreaterThan(1.0);
}
@Test
@@ -1174,30 +1243,23 @@
mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN);
});
+ // Wait for Region updated.
+ waitForIdleSync();
mInstrumentation.runOnMainSync(
() -> {
mWindowMagnificationController.moveWindowMagnifier(bounds.width(), 0);
});
-
// Wait for Region updated.
waitForIdleSync();
- final ArgumentCaptor<Region> tapExcludeRegionCapturer =
- ArgumentCaptor.forClass(Region.class);
- verify(mWindowSessionSpy, times(2))
- .updateTapExcludeRegion(any(), tapExcludeRegionCapturer.capture());
- Region tapExcludeRegion = tapExcludeRegionCapturer.getValue();
- RegionIterator iterator = new RegionIterator(tapExcludeRegion);
+ AttachedSurfaceControl viewRoot = mSurfaceControlViewHost.getRootSurfaceControl();
+ // Verifying two times in: (1) enable window magnification (2) reposition drag handle
+ verify(viewRoot, times(2)).setTouchableRegion(any());
- final Rect topRect = new Rect();
- final Rect bottomRect = new Rect();
- assertTrue(iterator.next(topRect));
- assertTrue(iterator.next(bottomRect));
- assertFalse(iterator.next(new Rect()));
-
- assertEquals(topRect.right, bottomRect.right);
- assertNotEquals(topRect.left, bottomRect.left);
+ View dragButton = getInternalView(R.id.drag_handle);
+ FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) dragButton.getLayoutParams();
+ assertThat(params.gravity).isEqualTo(Gravity.BOTTOM | Gravity.LEFT);
}
@Test
@@ -1210,29 +1272,23 @@
mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN);
});
+ // Wait for Region updated.
+ waitForIdleSync();
mInstrumentation.runOnMainSync(
() -> {
mWindowMagnificationController.moveWindowMagnifier(-bounds.width(), 0);
});
-
// Wait for Region updated.
waitForIdleSync();
- final ArgumentCaptor<Region> tapExcludeRegionCapturer =
- ArgumentCaptor.forClass(Region.class);
- verify(mWindowSessionSpy).updateTapExcludeRegion(any(), tapExcludeRegionCapturer.capture());
- Region tapExcludeRegion = tapExcludeRegionCapturer.getValue();
- RegionIterator iterator = new RegionIterator(tapExcludeRegion);
+ AttachedSurfaceControl viewRoot = mSurfaceControlViewHost.getRootSurfaceControl();
+ // Verifying one times in: (1) enable window magnification
+ verify(viewRoot).setTouchableRegion(any());
- final Rect topRect = new Rect();
- final Rect bottomRect = new Rect();
- assertTrue(iterator.next(topRect));
- assertTrue(iterator.next(bottomRect));
- assertFalse(iterator.next(new Rect()));
-
- assertEquals(topRect.left, bottomRect.left);
- assertNotEquals(topRect.right, bottomRect.right);
+ View dragButton = getInternalView(R.id.drag_handle);
+ FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) dragButton.getLayoutParams();
+ assertThat(params.gravity).isEqualTo(Gravity.BOTTOM | Gravity.RIGHT);
}
@Test
@@ -1249,13 +1305,13 @@
final AtomicInteger actualWindowWidth = new AtomicInteger();
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.setWindowSize(expectedWindowWidth, expectedWindowHeight);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(mSurfaceControlViewHost.getView().getLayoutParams().width);
});
- assertEquals(expectedWindowHeight, actualWindowHeight.get());
- assertEquals(expectedWindowWidth, actualWindowWidth.get());
+ assertThat(actualWindowHeight.get()).isEqualTo(expectedWindowHeight);
+ assertThat(actualWindowWidth.get()).isEqualTo(expectedWindowWidth);
}
@Test
@@ -1271,12 +1327,12 @@
mWindowMagnificationController.setWindowSize(expectedWindowWidth, expectedWindowHeight);
mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(mSurfaceControlViewHost.getView().getLayoutParams().width);
});
- assertEquals(expectedWindowHeight, actualWindowHeight.get());
- assertEquals(expectedWindowWidth, actualWindowWidth.get());
+ assertThat(actualWindowHeight.get()).isEqualTo(expectedWindowHeight);
+ assertThat(actualWindowWidth.get()).isEqualTo(expectedWindowWidth);
}
@Test
@@ -1292,12 +1348,12 @@
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.setWindowSize(minimumWindowSize - 10,
minimumWindowSize - 10);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(mSurfaceControlViewHost.getView().getLayoutParams().width);
});
- assertEquals(minimumWindowSize, actualWindowHeight.get());
- assertEquals(minimumWindowSize, actualWindowWidth.get());
+ assertThat(actualWindowHeight.get()).isEqualTo(minimumWindowSize);
+ assertThat(actualWindowWidth.get()).isEqualTo(minimumWindowSize);
}
@Test
@@ -1311,12 +1367,12 @@
final AtomicInteger actualWindowWidth = new AtomicInteger();
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.setWindowSize(bounds.width() + 10, bounds.height() + 10);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(mSurfaceControlViewHost.getView().getLayoutParams().width);
});
- assertEquals(bounds.height(), actualWindowHeight.get());
- assertEquals(bounds.width(), actualWindowWidth.get());
+ assertThat(actualWindowHeight.get()).isEqualTo(bounds.height());
+ assertThat(actualWindowWidth.get()).isEqualTo(bounds.width());
}
@Test
@@ -1342,12 +1398,14 @@
() -> {
mWindowMagnificationController.changeMagnificationSize(
WindowMagnificationSettings.MagnificationSize.LARGE);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().width);
});
- assertEquals(expectedWindowHeight, actualWindowHeight.get());
- assertEquals(expectedWindowWidth, actualWindowWidth.get());
+ assertThat(actualWindowHeight.get()).isEqualTo(expectedWindowHeight);
+ assertThat(actualWindowWidth.get()).isEqualTo(expectedWindowWidth);
}
@Test
@@ -1376,12 +1434,14 @@
() -> {
mWindowMagnificationController
.onDrag(getInternalView(R.id.bottom_right_corner), 2f, 1f);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().width);
});
- assertEquals(startingSize + 1, actualWindowHeight.get());
- assertEquals(startingSize + 2, actualWindowWidth.get());
+ assertThat(actualWindowHeight.get()).isEqualTo(startingSize + 1);
+ assertThat(actualWindowWidth.get()).isEqualTo(startingSize + 2);
}
@Test
@@ -1404,11 +1464,13 @@
mWindowMagnificationController.setEditMagnifierSizeMode(true);
mWindowMagnificationController
.onDrag(getInternalView(R.id.bottom_handle), 2f, 1f);
- actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
- actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
+ actualWindowHeight.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().height);
+ actualWindowWidth.set(
+ mSurfaceControlViewHost.getView().getLayoutParams().width);
});
- assertEquals(startingSize + 1, actualWindowHeight.get());
- assertEquals(startingSize, actualWindowWidth.get());
+ assertThat(actualWindowHeight.get()).isEqualTo(startingSize + 1);
+ assertThat(actualWindowWidth.get()).isEqualTo(startingSize);
}
@Test
@@ -1430,8 +1492,8 @@
magnificationCenterY.set((int) mWindowMagnificationController.getCenterY());
});
- assertTrue(magnificationCenterX.get() < bounds.right);
- assertTrue(magnificationCenterY.get() < bounds.bottom);
+ assertThat(magnificationCenterX.get()).isLessThan(bounds.right);
+ assertThat(magnificationCenterY.get()).isLessThan(bounds.bottom);
}
@Test
@@ -1451,13 +1513,13 @@
dragButton.dispatchTouchEvent(
obtainMotionEvent(downTime, downTime, ACTION_UP, 100, 100));
- verify(mWindowManager).addView(any(View.class), any());
+ verify(mSurfaceControlViewHost).setView(any(View.class), any());
}
private <T extends View> T getInternalView(@IdRes int idRes) {
- View mirrorView = mWindowManager.getAttachedView();
+ View mirrorView = mSurfaceControlViewHost.getView();
T view = mirrorView.findViewById(idRes);
- assertNotNull(view);
+ assertThat(view).isNotNull();
return view;
}
@@ -1466,14 +1528,14 @@
return mMotionEventHelper.obtainMotionEvent(downTime, eventTime, action, x, y);
}
- private CharSequence getAccessibilityWindowTitle() {
- final View mirrorView = mWindowManager.getAttachedView();
+ private String getAccessibilityWindowTitle() {
+ final View mirrorView = mSurfaceControlViewHost.getView();
if (mirrorView == null) {
return null;
}
WindowManager.LayoutParams layoutParams =
(WindowManager.LayoutParams) mirrorView.getLayoutParams();
- return layoutParams.accessibilityTitle;
+ return layoutParams.accessibilityTitle.toString();
}
private boolean hasMagnificationOverlapFlag() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
index a8c3af9..8db82d5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
@@ -24,8 +24,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
-class
-ViewHierarchyAnimatorTest : SysuiTestCase() {
+class ViewHierarchyAnimatorTest : SysuiTestCase() {
companion object {
private const val TEST_DURATION = 1000L
private val TEST_INTERPOLATOR = Interpolators.LINEAR
@@ -49,9 +48,12 @@
rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
// animate()
- var success = ViewHierarchyAnimator.animate(
- rootView, interpolator = TEST_INTERPOLATOR, duration = TEST_DURATION
- )
+ var success =
+ ViewHierarchyAnimator.animate(
+ rootView,
+ interpolator = TEST_INTERPOLATOR,
+ duration = TEST_DURATION,
+ )
rootView.layout(0 /* l */, 0 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -64,9 +66,12 @@
ViewHierarchyAnimator.stopAnimating(rootView)
// animateNextUpdate()
- success = ViewHierarchyAnimator.animateNextUpdate(
- rootView, interpolator = TEST_INTERPOLATOR, duration = TEST_DURATION
- )
+ success =
+ ViewHierarchyAnimator.animateNextUpdate(
+ rootView,
+ interpolator = TEST_INTERPOLATOR,
+ duration = TEST_DURATION,
+ )
rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
assertTrue(success)
@@ -79,9 +84,12 @@
// animateAddition()
rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView, interpolator = TEST_INTERPOLATOR, duration = TEST_DURATION
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ interpolator = TEST_INTERPOLATOR,
+ duration = TEST_DURATION,
+ )
rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
assertTrue(success)
@@ -93,9 +101,12 @@
// animateRemoval()
setUpRootWithChildren()
val child = rootView.getChildAt(0)
- success = ViewHierarchyAnimator.animateRemoval(
- child, interpolator = TEST_INTERPOLATOR, duration = TEST_DURATION
- )
+ success =
+ ViewHierarchyAnimator.animateRemoval(
+ child,
+ interpolator = TEST_INTERPOLATOR,
+ duration = TEST_DURATION,
+ )
assertTrue(success)
assertNotNull(child.getTag(R.id.tag_animator))
@@ -185,7 +196,7 @@
// Change all bounds.
rootView.measure(
View.MeasureSpec.makeMeasureSpec(190, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
+ View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY),
)
rootView.layout(10 /* l */, 20 /* t */, 200 /* r */, 120 /* b */)
@@ -211,14 +222,12 @@
fun animatesRootAndChildren_withExcludedViews() {
setUpRootWithChildren()
- val success = ViewHierarchyAnimator.animate(
- rootView,
- excludedViews = setOf(rootView.getChildAt(0))
- )
+ val success =
+ ViewHierarchyAnimator.animate(rootView, excludedViews = setOf(rootView.getChildAt(0)))
// Change all bounds.
rootView.measure(
- View.MeasureSpec.makeMeasureSpec(180, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
+ View.MeasureSpec.makeMeasureSpec(180, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY),
)
rootView.layout(10 /* l */, 20 /* t */, 200 /* r */, 120 /* b */)
@@ -245,14 +254,11 @@
fun animatesRootOnly() {
setUpRootWithChildren()
- val success = ViewHierarchyAnimator.animate(
- rootView,
- animateChildren = false
- )
+ val success = ViewHierarchyAnimator.animate(rootView, animateChildren = false)
// Change all bounds.
rootView.measure(
- View.MeasureSpec.makeMeasureSpec(180, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
+ View.MeasureSpec.makeMeasureSpec(180, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY),
)
rootView.layout(10 /* l */, 20 /* t */, 200 /* r */, 120 /* b */)
@@ -351,10 +357,11 @@
fun animatesAppearingViewsRespectingOrigin() {
// CENTER.
rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */)
- var success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.CENTER
- )
+ var success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.CENTER,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -364,10 +371,11 @@
// LEFT.
rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.LEFT
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.LEFT,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -377,10 +385,11 @@
// TOP_LEFT.
rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.TOP_LEFT
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.TOP_LEFT,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -390,10 +399,11 @@
// TOP.
rootView.layout(150 /* l */, 0 /* t */, 150 /* r */, 0 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.TOP
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.TOP,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -403,10 +413,11 @@
// TOP_RIGHT.
rootView.layout(150 /* l */, 0 /* t */, 150 /* r */, 0 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.TOP_RIGHT
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.TOP_RIGHT,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -416,10 +427,11 @@
// RIGHT.
rootView.layout(150 /* l */, 150 /* t */, 150 /* r */, 150 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.RIGHT
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.RIGHT,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -429,10 +441,11 @@
// BOTTOM_RIGHT.
rootView.layout(150 /* l */, 150 /* t */, 150 /* r */, 150 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.BOTTOM_RIGHT
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.BOTTOM_RIGHT,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -442,10 +455,11 @@
// BOTTOM.
rootView.layout(0 /* l */, 150 /* t */, 0 /* r */, 150 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.BOTTOM
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.BOTTOM,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -455,10 +469,11 @@
// BOTTOM_LEFT.
rootView.layout(0 /* l */, 150 /* t */, 0 /* r */, 150 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.BOTTOM_LEFT
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.BOTTOM_LEFT,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -471,11 +486,12 @@
fun animatesAppearingViewsRespectingMargins() {
// CENTER.
rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */)
- var success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.CENTER,
- includeMargins = true
- )
+ var success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.CENTER,
+ includeMargins = true,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -485,10 +501,12 @@
// LEFT.
rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView, origin = ViewHierarchyAnimator.Hotspot.LEFT,
- includeMargins = true
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.LEFT,
+ includeMargins = true,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -498,11 +516,12 @@
// TOP_LEFT.
rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.TOP_LEFT,
- includeMargins = true
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.TOP_LEFT,
+ includeMargins = true,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -512,10 +531,12 @@
// TOP.
rootView.layout(150 /* l */, 0 /* t */, 150 /* r */, 0 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView, origin = ViewHierarchyAnimator.Hotspot.TOP,
- includeMargins = true
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.TOP,
+ includeMargins = true,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -525,11 +546,12 @@
// TOP_RIGHT.
rootView.layout(150 /* l */, 0 /* t */, 150 /* r */, 0 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.TOP_RIGHT,
- includeMargins = true
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.TOP_RIGHT,
+ includeMargins = true,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -539,11 +561,12 @@
// RIGHT.
rootView.layout(150 /* l */, 150 /* t */, 150 /* r */, 150 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.RIGHT,
- includeMargins = true
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.RIGHT,
+ includeMargins = true,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -553,11 +576,12 @@
// BOTTOM_RIGHT.
rootView.layout(150 /* l */, 150 /* t */, 150 /* r */, 150 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.BOTTOM_RIGHT,
- includeMargins = true
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.BOTTOM_RIGHT,
+ includeMargins = true,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -567,11 +591,12 @@
// BOTTOM.
rootView.layout(0 /* l */, 150 /* t */, 0 /* r */, 150 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.BOTTOM,
- includeMargins = true
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.BOTTOM,
+ includeMargins = true,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -581,11 +606,12 @@
// BOTTOM_LEFT.
rootView.layout(0 /* l */, 150 /* t */, 0 /* r */, 150 /* b */)
- success = ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.BOTTOM_LEFT,
- includeMargins = true
- )
+ success =
+ ViewHierarchyAnimator.animateAddition(
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.BOTTOM_LEFT,
+ includeMargins = true,
+ )
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
assertTrue(success)
@@ -626,7 +652,7 @@
ViewHierarchyAnimator.animateAddition(
rootView,
includeFadeIn = true,
- fadeInInterpolator = Interpolators.LINEAR
+ fadeInInterpolator = Interpolators.LINEAR,
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
@@ -641,7 +667,7 @@
ViewHierarchyAnimator.animateAddition(
rootView,
includeFadeIn = true,
- fadeInInterpolator = Interpolators.LINEAR
+ fadeInInterpolator = Interpolators.LINEAR,
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
@@ -663,7 +689,7 @@
ViewHierarchyAnimator.animateAddition(
rootView,
includeFadeIn = true,
- fadeInInterpolator = Interpolators.LINEAR
+ fadeInInterpolator = Interpolators.LINEAR,
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
@@ -680,7 +706,7 @@
ViewHierarchyAnimator.animateAddition(
rootView,
includeFadeIn = true,
- fadeInInterpolator = Interpolators.LINEAR
+ fadeInInterpolator = Interpolators.LINEAR,
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
@@ -692,7 +718,7 @@
ViewHierarchyAnimator.animateAddition(
rootView,
includeFadeIn = true,
- fadeInInterpolator = Interpolators.LINEAR
+ fadeInInterpolator = Interpolators.LINEAR,
)
// THEN the alpha remains at its current value (it doesn't get reset to 0)
@@ -721,7 +747,7 @@
ViewHierarchyAnimator.animateAddition(
rootView,
includeFadeIn = false,
- fadeInInterpolator = Interpolators.LINEAR
+ fadeInInterpolator = Interpolators.LINEAR,
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
@@ -738,10 +764,10 @@
val onAnimationEndRunnable = { runnableRun = true }
ViewHierarchyAnimator.animateAddition(
- rootView,
- origin = ViewHierarchyAnimator.Hotspot.CENTER,
- includeMargins = true,
- onAnimationEnd = onAnimationEndRunnable
+ rootView,
+ origin = ViewHierarchyAnimator.Hotspot.CENTER,
+ includeMargins = true,
+ onAnimationEnd = onAnimationEndRunnable,
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
@@ -751,7 +777,7 @@
}
@Test
- fun animateAddition_runnableDoesNotRunWhenAnimationCancelled() {
+ fun animateAddition_runnableRunsWhenAnimationCancelled() {
var runnableRun = false
val onAnimationEndRunnable = { runnableRun = true }
@@ -759,13 +785,13 @@
rootView,
origin = ViewHierarchyAnimator.Hotspot.CENTER,
includeMargins = true,
- onAnimationEnd = onAnimationEndRunnable
+ onAnimationEnd = onAnimationEndRunnable,
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
cancelAnimation(rootView)
- assertEquals(false, runnableRun)
+ assertEquals(true, runnableRun)
}
@Test
@@ -777,7 +803,7 @@
rootView,
origin = ViewHierarchyAnimator.Hotspot.CENTER,
includeMargins = true,
- onAnimationEnd = onAnimationEndRunnable
+ onAnimationEnd = onAnimationEndRunnable,
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
@@ -791,11 +817,12 @@
setUpRootWithChildren()
val child = rootView.getChildAt(0)
- val success = ViewHierarchyAnimator.animateRemoval(
- child,
- destination = ViewHierarchyAnimator.Hotspot.LEFT,
- interpolator = Interpolators.LINEAR
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ child,
+ destination = ViewHierarchyAnimator.Hotspot.LEFT,
+ interpolator = Interpolators.LINEAR,
+ )
assertTrue(success)
assertNotNull(child.getTag(R.id.tag_animator))
@@ -820,11 +847,12 @@
rootView.addView(onlyChild)
forceLayout()
- val success = ViewHierarchyAnimator.animateRemoval(
- onlyChild,
- destination = ViewHierarchyAnimator.Hotspot.LEFT,
- interpolator = Interpolators.LINEAR
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ onlyChild,
+ destination = ViewHierarchyAnimator.Hotspot.LEFT,
+ interpolator = Interpolators.LINEAR,
+ )
assertTrue(success)
assertNotNull(onlyChild.getTag(R.id.tag_animator))
@@ -845,9 +873,11 @@
setUpRootWithChildren()
var removedChild = rootView.getChildAt(0)
var remainingChild = rootView.getChildAt(1)
- var success = ViewHierarchyAnimator.animateRemoval(
- removedChild, destination = ViewHierarchyAnimator.Hotspot.CENTER
- )
+ var success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.CENTER,
+ )
// Ensure that the layout happens before the checks.
forceLayout()
@@ -863,9 +893,11 @@
setUpRootWithChildren()
removedChild = rootView.getChildAt(0)
remainingChild = rootView.getChildAt(1)
- success = ViewHierarchyAnimator.animateRemoval(
- removedChild, destination = ViewHierarchyAnimator.Hotspot.LEFT
- )
+ success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.LEFT,
+ )
// Ensure that the layout happens before the checks.
forceLayout()
@@ -881,9 +913,11 @@
setUpRootWithChildren()
removedChild = rootView.getChildAt(0)
remainingChild = rootView.getChildAt(1)
- success = ViewHierarchyAnimator.animateRemoval(
- removedChild, destination = ViewHierarchyAnimator.Hotspot.TOP_LEFT
- )
+ success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.TOP_LEFT,
+ )
// Ensure that the layout happens before the checks.
forceLayout()
@@ -899,9 +933,11 @@
setUpRootWithChildren()
removedChild = rootView.getChildAt(0)
remainingChild = rootView.getChildAt(1)
- success = ViewHierarchyAnimator.animateRemoval(
- removedChild, destination = ViewHierarchyAnimator.Hotspot.TOP
- )
+ success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.TOP,
+ )
// Ensure that the layout happens before the checks.
forceLayout()
@@ -917,9 +953,11 @@
setUpRootWithChildren()
removedChild = rootView.getChildAt(0)
remainingChild = rootView.getChildAt(1)
- success = ViewHierarchyAnimator.animateRemoval(
- removedChild, destination = ViewHierarchyAnimator.Hotspot.TOP_RIGHT
- )
+ success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.TOP_RIGHT,
+ )
// Ensure that the layout happens before the checks.
forceLayout()
@@ -935,9 +973,11 @@
setUpRootWithChildren()
removedChild = rootView.getChildAt(0)
remainingChild = rootView.getChildAt(1)
- success = ViewHierarchyAnimator.animateRemoval(
- removedChild, destination = ViewHierarchyAnimator.Hotspot.RIGHT
- )
+ success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.RIGHT,
+ )
// Ensure that the layout happens before the checks.
forceLayout()
@@ -953,9 +993,11 @@
setUpRootWithChildren()
removedChild = rootView.getChildAt(0)
remainingChild = rootView.getChildAt(1)
- success = ViewHierarchyAnimator.animateRemoval(
- removedChild, destination = ViewHierarchyAnimator.Hotspot.BOTTOM_RIGHT
- )
+ success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.BOTTOM_RIGHT,
+ )
// Ensure that the layout happens before the checks.
forceLayout()
@@ -971,9 +1013,11 @@
setUpRootWithChildren()
removedChild = rootView.getChildAt(0)
remainingChild = rootView.getChildAt(1)
- success = ViewHierarchyAnimator.animateRemoval(
- removedChild, destination = ViewHierarchyAnimator.Hotspot.BOTTOM
- )
+ success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.BOTTOM,
+ )
// Ensure that the layout happens before the checks.
forceLayout()
@@ -989,9 +1033,11 @@
setUpRootWithChildren()
removedChild = rootView.getChildAt(0)
remainingChild = rootView.getChildAt(1)
- success = ViewHierarchyAnimator.animateRemoval(
- removedChild, destination = ViewHierarchyAnimator.Hotspot.BOTTOM_LEFT
- )
+ success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.BOTTOM_LEFT,
+ )
// Ensure that the layout happens before the checks.
forceLayout()
@@ -1014,11 +1060,12 @@
val originalRight = removedChild.right
val originalBottom = removedChild.bottom
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild,
- destination = ViewHierarchyAnimator.Hotspot.CENTER,
- includeMargins = true,
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.CENTER,
+ includeMargins = true,
+ )
forceLayout()
assertTrue(success)
@@ -1027,13 +1074,7 @@
val expectedX = ((originalLeft - M_LEFT) + (originalRight + M_RIGHT)) / 2
val expectedY = ((originalTop - M_TOP) + (originalBottom + M_BOTTOM)) / 2
- checkBounds(
- removedChild,
- l = expectedX,
- t = expectedY,
- r = expectedX,
- b = expectedY
- )
+ checkBounds(removedChild, l = expectedX, t = expectedY, r = expectedX, b = expectedY)
}
@Test
@@ -1044,11 +1085,12 @@
val originalTop = removedChild.top
val originalBottom = removedChild.bottom
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild,
- destination = ViewHierarchyAnimator.Hotspot.LEFT,
- includeMargins = true,
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.LEFT,
+ includeMargins = true,
+ )
forceLayout()
assertTrue(success)
@@ -1059,7 +1101,7 @@
l = originalLeft - M_LEFT,
t = originalTop,
r = originalLeft - M_LEFT,
- b = originalBottom
+ b = originalBottom,
)
}
@@ -1070,11 +1112,12 @@
val originalLeft = removedChild.left
val originalTop = removedChild.top
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild,
- destination = ViewHierarchyAnimator.Hotspot.TOP_LEFT,
- includeMargins = true,
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.TOP_LEFT,
+ includeMargins = true,
+ )
forceLayout()
assertTrue(success)
@@ -1085,7 +1128,7 @@
l = originalLeft - M_LEFT,
t = originalTop - M_TOP,
r = originalLeft - M_LEFT,
- b = originalTop - M_TOP
+ b = originalTop - M_TOP,
)
}
@@ -1097,11 +1140,12 @@
val originalTop = removedChild.top
val originalRight = removedChild.right
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild,
- destination = ViewHierarchyAnimator.Hotspot.TOP,
- includeMargins = true,
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.TOP,
+ includeMargins = true,
+ )
forceLayout()
assertTrue(success)
@@ -1112,7 +1156,7 @@
l = originalLeft,
t = originalTop - M_TOP,
r = originalRight,
- b = originalTop - M_TOP
+ b = originalTop - M_TOP,
)
}
@@ -1123,11 +1167,12 @@
val originalTop = removedChild.top
val originalRight = removedChild.right
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild,
- destination = ViewHierarchyAnimator.Hotspot.TOP_RIGHT,
- includeMargins = true,
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.TOP_RIGHT,
+ includeMargins = true,
+ )
forceLayout()
assertTrue(success)
@@ -1138,7 +1183,7 @@
l = originalRight + M_RIGHT,
t = originalTop - M_TOP,
r = originalRight + M_RIGHT,
- b = originalTop - M_TOP
+ b = originalTop - M_TOP,
)
}
@@ -1150,11 +1195,12 @@
val originalRight = removedChild.right
val originalBottom = removedChild.bottom
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild,
- destination = ViewHierarchyAnimator.Hotspot.RIGHT,
- includeMargins = true,
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.RIGHT,
+ includeMargins = true,
+ )
forceLayout()
assertTrue(success)
@@ -1165,7 +1211,7 @@
l = originalRight + M_RIGHT,
t = originalTop,
r = originalRight + M_RIGHT,
- b = originalBottom
+ b = originalBottom,
)
}
@@ -1176,11 +1222,12 @@
val originalRight = removedChild.right
val originalBottom = removedChild.bottom
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild,
- destination = ViewHierarchyAnimator.Hotspot.BOTTOM_RIGHT,
- includeMargins = true,
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.BOTTOM_RIGHT,
+ includeMargins = true,
+ )
forceLayout()
assertTrue(success)
@@ -1191,7 +1238,7 @@
l = originalRight + M_RIGHT,
t = originalBottom + M_BOTTOM,
r = originalRight + M_RIGHT,
- b = originalBottom + M_BOTTOM
+ b = originalBottom + M_BOTTOM,
)
}
@@ -1203,11 +1250,12 @@
val originalRight = removedChild.right
val originalBottom = removedChild.bottom
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild,
- destination = ViewHierarchyAnimator.Hotspot.BOTTOM,
- includeMargins = true,
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.BOTTOM,
+ includeMargins = true,
+ )
forceLayout()
assertTrue(success)
@@ -1218,7 +1266,7 @@
l = originalLeft,
t = originalBottom + M_BOTTOM,
r = originalRight,
- b = originalBottom + M_BOTTOM
+ b = originalBottom + M_BOTTOM,
)
}
@@ -1229,11 +1277,12 @@
val originalLeft = removedChild.left
val originalBottom = removedChild.bottom
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild,
- destination = ViewHierarchyAnimator.Hotspot.BOTTOM_LEFT,
- includeMargins = true,
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(
+ removedChild,
+ destination = ViewHierarchyAnimator.Hotspot.BOTTOM_LEFT,
+ includeMargins = true,
+ )
forceLayout()
assertTrue(success)
@@ -1244,9 +1293,10 @@
l = originalLeft - M_LEFT,
t = originalBottom + M_BOTTOM,
r = originalLeft - M_LEFT,
- b = originalBottom + M_BOTTOM
+ b = originalBottom + M_BOTTOM,
)
}
+
/* ******** end of animatesViewRemoval_includeMarginsTrue tests ******** */
@Test
@@ -1256,9 +1306,8 @@
val child = rootView.getChildAt(0) as ViewGroup
val firstGrandChild = child.getChildAt(0)
val secondGrandChild = child.getChildAt(1)
- val success = ViewHierarchyAnimator.animateRemoval(
- child, interpolator = Interpolators.LINEAR
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(child, interpolator = Interpolators.LINEAR)
assertTrue(success)
assertNotNull(child.getTag(R.id.tag_animator))
@@ -1288,9 +1337,8 @@
val removedChild = rootView.getChildAt(0)
val remainingChild = rootView.getChildAt(1)
- val success = ViewHierarchyAnimator.animateRemoval(
- removedChild, interpolator = Interpolators.LINEAR
- )
+ val success =
+ ViewHierarchyAnimator.animateRemoval(removedChild, interpolator = Interpolators.LINEAR)
// Ensure that the layout happens before the checks.
forceLayout()
@@ -1315,17 +1363,14 @@
forceLayout()
val removedView = rootView.getChildAt(0)
- ViewHierarchyAnimator.animateRemoval(
- removedView,
- onAnimationEnd = onAnimationEndRunnable
- )
+ ViewHierarchyAnimator.animateRemoval(removedView, onAnimationEnd = onAnimationEndRunnable)
endAnimation(removedView)
assertEquals(true, runnableRun)
}
@Test
- fun animateRemoval_runnableDoesNotRunWhenAnimationCancelled() {
+ fun animateRemoval_runnableRunsWhenAnimationCancelled() {
var runnableRun = false
val onAnimationEndRunnable = { runnableRun = true }
@@ -1333,13 +1378,10 @@
forceLayout()
val removedView = rootView.getChildAt(0)
- ViewHierarchyAnimator.animateRemoval(
- removedView,
- onAnimationEnd = onAnimationEndRunnable
- )
+ ViewHierarchyAnimator.animateRemoval(removedView, onAnimationEnd = onAnimationEndRunnable)
cancelAnimation(removedView)
- assertEquals(false, runnableRun)
+ assertEquals(true, runnableRun)
}
@Test
@@ -1351,10 +1393,7 @@
forceLayout()
val removedView = rootView.getChildAt(0)
- ViewHierarchyAnimator.animateRemoval(
- removedView,
- onAnimationEnd = onAnimationEndRunnable
- )
+ ViewHierarchyAnimator.animateRemoval(removedView, onAnimationEnd = onAnimationEndRunnable)
advanceAnimation(removedView, 0.5f)
assertEquals(false, runnableRun)
@@ -1370,7 +1409,7 @@
rootView.addView(secondChild)
rootView.measure(
View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
+ View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY),
)
rootView.layout(0 /* l */, 0 /* t */, 100 /* r */, 100 /* b */)
@@ -1378,7 +1417,7 @@
// Change all bounds.
rootView.measure(
View.MeasureSpec.makeMeasureSpec(150, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
+ View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY),
)
rootView.layout(0 /* l */, 0 /* t */, 150 /* r */, 100 /* b */)
@@ -1501,7 +1540,7 @@
checkBounds(rootView, l = 0, t = 15, r = 70, b = 80)
// Change all bounds again.
- rootView.layout(10 /* l */, 10 /* t */, 50/* r */, 50 /* b */)
+ rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
assertNull(rootView.getTag(R.id.tag_animator))
checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
@@ -1523,7 +1562,7 @@
ViewHierarchyAnimator.stopAnimating(rootView)
// Change all bounds again.
- rootView.layout(10 /* l */, 10 /* t */, 50/* r */, 50 /* b */)
+ rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
assertNull(rootView.getTag(R.id.tag_animator))
checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
@@ -1543,10 +1582,8 @@
val secondChild = View(mContext)
rootView.addView(secondChild)
- val firstChildParams = LinearLayout.LayoutParams(
- 0 /* width */,
- LinearLayout.LayoutParams.MATCH_PARENT
- )
+ val firstChildParams =
+ LinearLayout.LayoutParams(0 /* width */, LinearLayout.LayoutParams.MATCH_PARENT)
firstChildParams.weight = 0.5f
if (includeMarginsOnFirstChild) {
firstChildParams.leftMargin = M_LEFT
@@ -1556,23 +1593,25 @@
}
firstChild.layoutParams = firstChildParams
- val secondChildParams = LinearLayout.LayoutParams(
- 0 /* width */,
- LinearLayout.LayoutParams.MATCH_PARENT
- )
+ val secondChildParams =
+ LinearLayout.LayoutParams(0 /* width */, LinearLayout.LayoutParams.MATCH_PARENT)
secondChildParams.weight = 0.5f
secondChild.layoutParams = secondChildParams
firstGrandChild.layoutParams = RelativeLayout.LayoutParams(40 /* width */, 40 /* height */)
- (firstGrandChild.layoutParams as RelativeLayout.LayoutParams)
- .addRule(RelativeLayout.ALIGN_PARENT_START)
- (firstGrandChild.layoutParams as RelativeLayout.LayoutParams)
- .addRule(RelativeLayout.ALIGN_PARENT_TOP)
+ (firstGrandChild.layoutParams as RelativeLayout.LayoutParams).addRule(
+ RelativeLayout.ALIGN_PARENT_START
+ )
+ (firstGrandChild.layoutParams as RelativeLayout.LayoutParams).addRule(
+ RelativeLayout.ALIGN_PARENT_TOP
+ )
secondGrandChild.layoutParams = RelativeLayout.LayoutParams(40 /* width */, 40 /* height */)
- (secondGrandChild.layoutParams as RelativeLayout.LayoutParams)
- .addRule(RelativeLayout.ALIGN_PARENT_END)
- (secondGrandChild.layoutParams as RelativeLayout.LayoutParams)
- .addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
+ (secondGrandChild.layoutParams as RelativeLayout.LayoutParams).addRule(
+ RelativeLayout.ALIGN_PARENT_END
+ )
+ (secondGrandChild.layoutParams as RelativeLayout.LayoutParams).addRule(
+ RelativeLayout.ALIGN_PARENT_BOTTOM
+ )
forceLayout()
}
@@ -1580,7 +1619,7 @@
private fun forceLayout() {
rootView.measure(
View.MeasureSpec.makeMeasureSpec(200 /* width */, View.MeasureSpec.AT_MOST),
- View.MeasureSpec.makeMeasureSpec(100 /* height */, View.MeasureSpec.AT_MOST)
+ View.MeasureSpec.makeMeasureSpec(100 /* height */, View.MeasureSpec.AT_MOST),
)
rootView.layout(0 /* l */, 0 /* t */, 200 /* r */, 100 /* b */)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
index f58bbc3..d371592 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
@@ -20,7 +20,6 @@
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -71,7 +70,7 @@
assertThat(actions)
.containsEntriesExactly(
Back to UserActionResult(Scenes.QuickSettings),
- Swipe(SwipeDirection.Down) to UserActionResult(Scenes.QuickSettings),
+ Swipe.Down to UserActionResult(Scenes.QuickSettings),
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
index 0983105..f4cffc5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
@@ -20,7 +20,7 @@
import android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE
import android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF
import android.hardware.display.DisplayManager
-import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+import android.hardware.display.DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS
import android.view.Display
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -119,7 +119,8 @@
.registerDisplayListener(
capture(listenerCaptor),
eq(null),
- eq(EVENT_FLAG_DISPLAY_BRIGHTNESS),
+ eq(0),
+ eq(PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS),
)
val newBrightness = BrightnessInfo(0.6f, 0.3f, 0.9f)
@@ -157,7 +158,8 @@
.registerDisplayListener(
capture(listenerCaptor),
eq(null),
- eq(EVENT_FLAG_DISPLAY_BRIGHTNESS),
+ eq(0),
+ eq(PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS),
)
changeBrightnessInfoAndNotify(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
index 116b705..7cdfb0e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
@@ -30,6 +30,7 @@
import com.android.systemui.common.shared.model.Text
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
+import com.android.systemui.kosmos.brightnessWarningToast
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.res.R
@@ -61,6 +62,7 @@
sliderHapticsViewModelFactory,
brightnessMirrorShowingInteractor,
supportsMirroring = true,
+ brightnessWarningToast,
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
index cd8b2e1..e6e5665 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
@@ -540,7 +540,8 @@
.registerDisplayListener(
connectedDisplayListener.capture(),
eq(testHandler),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED),
+ eq(0),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED),
)
return flowValue
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/flags/FeatureFlagsClassicDebugTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/flags/FeatureFlagsClassicDebugTest.kt
index 3388a78..20cd860 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/flags/FeatureFlagsClassicDebugTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/flags/FeatureFlagsClassicDebugTest.kt
@@ -28,11 +28,13 @@
import com.android.systemui.Flags.FLAG_SYSUI_TEAMFOOD
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.mockito.withArgCaptor
import com.android.systemui.util.settings.GlobalSettings
+import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.io.PrintWriter
import java.io.Serializable
@@ -68,6 +70,7 @@
@Mock private lateinit var systemProperties: SystemPropertiesHelper
@Mock private lateinit var resources: Resources
@Mock private lateinit var restarter: Restarter
+ private lateinit var fakeExecutor: FakeExecutor
private lateinit var userTracker: FakeUserTracker
private val flagMap = mutableMapOf<String, Flag<*>>()
private lateinit var broadcastReceiver: BroadcastReceiver
@@ -83,6 +86,7 @@
flagMap.put(teamfoodableFlagA.name, teamfoodableFlagA)
flagMap.put(releasedFlagB.name, releasedFlagB)
+ fakeExecutor = FakeExecutor(FakeSystemClock())
userTracker = FakeUserTracker(onCreateCurrentUserContext = { mockContext })
mFeatureFlagsClassicDebug =
@@ -95,7 +99,8 @@
serverFlagReader,
flagMap,
restarter,
- userTracker
+ userTracker,
+ fakeExecutor,
)
mFeatureFlagsClassicDebug.init()
verify(flagManager).onSettingsChangedAction = any()
@@ -325,14 +330,14 @@
// trying to erase an id not in the map does nothing
broadcastReceiver.onReceive(
mockContext,
- Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_NAME, "")
+ Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_NAME, ""),
)
verifyNoMoreInteractions(flagManager, globalSettings)
// valid id with no value puts empty string in the setting
broadcastReceiver.onReceive(
mockContext,
- Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_NAME, "1")
+ Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_NAME, "1"),
)
verifyPutData("1", "", numReads = 0)
}
@@ -415,7 +420,7 @@
serverFlagReader.setFlagValue(
teamfoodableFlagA.namespace,
teamfoodableFlagA.name,
- !teamfoodableFlagA.default
+ !teamfoodableFlagA.default,
)
verify(restarter, never()).restartSystemUI(anyString())
}
@@ -428,7 +433,7 @@
serverFlagReader.setFlagValue(
teamfoodableFlagA.namespace,
teamfoodableFlagA.name,
- !teamfoodableFlagA.default
+ !teamfoodableFlagA.default,
)
verify(restarter).restartSystemUI(anyString())
}
@@ -441,7 +446,7 @@
serverFlagReader.setFlagValue(
teamfoodableFlagA.namespace,
teamfoodableFlagA.name,
- teamfoodableFlagA.default
+ teamfoodableFlagA.default,
)
verify(restarter, never()).restartSystemUI(anyString())
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
index d1431ee..1580ea5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
@@ -22,6 +22,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyboard.shortcut.data.source.FakeKeyboardShortcutGroupsSource
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts
+import com.android.systemui.keyboard.shortcut.shortcutCustomizationDialogStarterFactory
import com.android.systemui.keyboard.shortcut.shortcutHelperAppCategoriesShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperCurrentAppShortcutsSource
import com.android.systemui.keyboard.shortcut.shortcutHelperInputShortcutsSource
@@ -71,7 +72,13 @@
private val starter: ShortcutHelperDialogStarter =
with(kosmos) {
- ShortcutHelperDialogStarter(coroutineScope, viewModel, dialogFactory, activityStarter)
+ ShortcutHelperDialogStarter(
+ coroutineScope,
+ viewModel,
+ shortcutCustomizationDialogStarterFactory,
+ dialogFactory,
+ activityStarter,
+ )
}
@Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
index 7f31356..2c12f87 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
@@ -193,7 +193,7 @@
@Test
@EnableSceneContainer
- fun surfaceBehindVisibility_fromLockscreenToGone_noUserInput_trueThroughout() =
+ fun surfaceBehindVisibility_fromLockscreenToGone_dependsOnDeviceEntry() =
testScope.runTest {
val isSurfaceBehindVisible by collectLastValue(underTest.value.surfaceBehindVisibility)
val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
@@ -208,7 +208,7 @@
SuccessFingerprintAuthenticationStatus(0, true)
)
- // Start the transition to Gone, the surface should become immediately visible.
+ // Start the transition to Gone, the surface should remain invisible.
kosmos.setSceneTransition(
ObservableTransitionState.Transition(
fromScene = Scenes.Lockscreen,
@@ -220,9 +220,9 @@
)
)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
- assertThat(isSurfaceBehindVisible).isTrue()
+ assertThat(isSurfaceBehindVisible).isFalse()
- // Towards the end of the transition, the surface should continue to be visible.
+ // Towards the end of the transition, the surface should continue to remain invisible.
kosmos.setSceneTransition(
ObservableTransitionState.Transition(
fromScene = Scenes.Lockscreen,
@@ -234,7 +234,7 @@
)
)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
- assertThat(isSurfaceBehindVisible).isTrue()
+ assertThat(isSurfaceBehindVisible).isFalse()
// After the transition, settles on Gone. Surface behind should stay visible now.
kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone))
@@ -245,43 +245,6 @@
@Test
@EnableSceneContainer
- fun surfaceBehindVisibility_fromLockscreenToGone_withUserInput_falseUntilInputStops() =
- testScope.runTest {
- val isSurfaceBehindVisible by collectLastValue(underTest.value.surfaceBehindVisibility)
- val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
-
- // Before the transition, we start on Lockscreen so the surface should start invisible.
- kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Lockscreen))
- assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
- assertThat(isSurfaceBehindVisible).isFalse()
-
- // Unlocked with fingerprint.
- kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus(
- SuccessFingerprintAuthenticationStatus(0, true)
- )
-
- // Start the transition to Gone, the surface should not be visible while
- // isUserInputOngoing is true
- val isUserInputOngoing = MutableStateFlow(true)
- kosmos.setSceneTransition(
- ObservableTransitionState.Transition(
- fromScene = Scenes.Lockscreen,
- toScene = Scenes.Gone,
- isInitiatedByUserInput = true,
- isUserInputOngoing = isUserInputOngoing,
- progress = flowOf(0.51f),
- currentScene = flowOf(Scenes.Gone),
- )
- )
- assertThat(isSurfaceBehindVisible).isFalse()
-
- // When isUserInputOngoing becomes false, then the surface should become visible.
- isUserInputOngoing.value = false
- assertThat(isSurfaceBehindVisible).isTrue()
- }
-
- @Test
- @EnableSceneContainer
fun surfaceBehindVisibility_fromBouncerToGone_becomesTrue() =
testScope.runTest {
val isSurfaceBehindVisible by collectLastValue(underTest.value.surfaceBehindVisibility)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
index 7f09370..0e3b03f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
@@ -44,6 +44,7 @@
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Ignore
@@ -107,6 +108,7 @@
fun translationAndScale_whenNotDozing() =
testScope.runTest {
val movement by collectLastValue(underTest.movement)
+ assertThat(movement?.translationX).isEqualTo(0)
// Set to not dozing (on lockscreen)
keyguardTransitionRepository.sendTransitionStep(
@@ -180,6 +182,7 @@
testScope.runTest {
underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100))
val movement by collectLastValue(underTest.movement)
+ assertThat(movement?.translationX).isEqualTo(0)
// Set to dozing (on AOD)
keyguardTransitionRepository.sendTransitionStep(
@@ -221,6 +224,7 @@
testScope.runTest {
underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100, topInset = 80))
val movement by collectLastValue(underTest.movement)
+ assertThat(movement?.translationX).isEqualTo(0)
// Set to dozing (on AOD)
keyguardTransitionRepository.sendTransitionStep(
@@ -263,6 +267,7 @@
testScope.runTest {
underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100, topInset = 80))
val movement by collectLastValue(underTest.movement)
+ assertThat(movement?.translationX).isEqualTo(0)
// Set to dozing (on AOD)
keyguardTransitionRepository.sendTransitionStep(
@@ -305,6 +310,7 @@
whenever(clockController.config.useAlternateSmartspaceAODTransition).thenReturn(true)
val movement by collectLastValue(underTest.movement)
+ assertThat(movement?.translationX).isEqualTo(0)
// Set to dozing (on AOD)
keyguardTransitionRepository.sendTransitionStep(
@@ -423,6 +429,7 @@
.thenReturn(if (isWeatherClock) true else false)
val movement by collectLastValue(underTest.movement)
+ assertThat(movement?.translationX).isEqualTo(0)
// Set to dozing (on AOD)
keyguardTransitionRepository.sendTransitionStep(
@@ -434,6 +441,7 @@
),
validateStep = false,
)
+ runCurrent()
// Trigger a change to the burn-in model
burnInFlow.value = BurnInModel(translationX = 20, translationY = 30, scale = 0.5f)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
index 6397979..5c4b743 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
@@ -25,7 +25,6 @@
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.TransitionKey
import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.UserActionResult.ShowOverlay
@@ -201,8 +200,7 @@
val userActions by collectLastValue(underTest.actions)
val downDestination =
userActions?.get(
- Swipe(
- SwipeDirection.Down,
+ Swipe.Down(
fromSource = Edge.Top.takeIf { downFromEdge },
pointerCount = if (downWithTwoPointers) 2 else 1,
)
@@ -292,8 +290,7 @@
val downDestination =
userActions?.get(
- Swipe(
- SwipeDirection.Down,
+ Swipe.Down(
fromSource = Edge.Top.takeIf { downFromEdge },
pointerCount = if (downWithTwoPointers) 2 else 1,
)
@@ -310,8 +307,7 @@
val downFromTopRightDestination =
userActions?.get(
- Swipe(
- SwipeDirection.Down,
+ Swipe.Down(
fromSource = SceneContainerEdge.TopRight,
pointerCount = if (downWithTwoPointers) 2 else 1,
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt
index 9e3fdf3..8e67e60 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt
@@ -20,7 +20,6 @@
import android.os.Bundle
import android.os.Handler
import android.os.looper
-import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import androidx.media.utils.MediaConstants
import androidx.media3.common.Player
@@ -69,10 +68,9 @@
private val testScope = kosmos.testScope
private val controllerFactory = kosmos.fakeMediaControllerFactory
private val tokenFactory = kosmos.fakeSessionTokenFactory
- private lateinit var testableLooper: TestableLooper
- private var commandCaptor = argumentCaptor<SessionCommand>()
- private var runnableCaptor = argumentCaptor<Runnable>()
+ private val commandCaptor = argumentCaptor<SessionCommand>()
+ private val runnableCaptor = argumentCaptor<Runnable>()
private val legacyToken = MediaSession.Token(1, null)
private val token = mock<SessionToken>()
@@ -97,8 +95,6 @@
@Before
fun setup() {
- testableLooper = TestableLooper.get(this)
-
underTest =
Media3ActionFactory(
context,
@@ -246,7 +242,6 @@
assertThat(actions.custom0!!.contentDescription).isEqualTo("$CUSTOM_ACTION_NAME 2")
actions.custom0!!.action!!.run()
runCurrent()
- testableLooper.processAllMessages()
verify(media3Controller).sendCustomCommand(commandCaptor.capture(), any<Bundle>())
assertThat(commandCaptor.lastValue.customAction).isEqualTo("$CUSTOM_ACTION_COMMAND 2")
verify(media3Controller).release()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt
index 1a7265b..cf503bb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt
@@ -82,7 +82,7 @@
private val fakeFeatureFlags = kosmos.fakeFeatureFlagsClassic
private val mediaFlags = kosmos.mediaFlags
private val mediaControllerFactory = kosmos.fakeMediaControllerFactory
- private val media3ActionFactory = kosmos.media3ActionFactory
+ private lateinit var media3ActionFactory: Media3ActionFactory
private val session = MediaSession(context, "MediaDataLoaderTestSession")
private val metadataBuilder =
MediaMetadata.Builder().apply {
@@ -94,6 +94,7 @@
@Before
fun setUp() {
+ media3ActionFactory = kosmos.media3ActionFactory
mediaControllerFactory.setControllerForToken(session.sessionToken, mediaController)
whenever(mediaController.sessionToken).thenReturn(session.sessionToken)
whenever(mediaController.metadata).then { metadataBuilder.build() }
@@ -311,7 +312,6 @@
}
build()
}
-
val result = underTest.loadMediaData(KEY, mediaNotification)
assertThat(result).isNotNull()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/data/ShellRecentTaskListProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/data/ShellRecentTaskListProviderTest.kt
index e12c67b..104aa51 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/data/ShellRecentTaskListProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/data/ShellRecentTaskListProviderTest.kt
@@ -16,7 +16,7 @@
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.wm.shell.recents.RecentTasks
-import com.android.wm.shell.shared.GroupedRecentTaskInfo
+import com.android.wm.shell.shared.GroupedTaskInfo
import com.android.wm.shell.shared.split.SplitBounds
import com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50
import com.google.common.truth.Truth.assertThat
@@ -219,9 +219,9 @@
}
@Suppress("UNCHECKED_CAST")
- private fun givenRecentTasks(vararg tasks: GroupedRecentTaskInfo) {
+ private fun givenRecentTasks(vararg tasks: GroupedTaskInfo) {
whenever(recentTasks.getRecentTasks(any(), any(), any(), any(), any())).thenAnswer {
- val consumer = it.arguments.last() as Consumer<List<GroupedRecentTaskInfo>>
+ val consumer = it.arguments.last() as Consumer<List<GroupedTaskInfo>>
consumer.accept(tasks.toList())
}
}
@@ -247,7 +247,7 @@
userId: Int = 0,
isVisible: Boolean = false,
userType: RecentTask.UserType = STANDARD,
- ): GroupedRecentTaskInfo {
+ ): GroupedTaskInfo {
val userInfo =
mock<UserInfo> {
whenever(isCloneProfile).thenReturn(userType == CLONED)
@@ -255,7 +255,7 @@
whenever(isPrivateProfile).thenReturn(userType == PRIVATE)
}
whenever(userManager.getUserInfo(userId)).thenReturn(userInfo)
- return GroupedRecentTaskInfo.forSingleTask(createTaskInfo(taskId, userId, isVisible))
+ return GroupedTaskInfo.forFullscreenTasks(createTaskInfo(taskId, userId, isVisible))
}
private fun createTaskPair(
@@ -263,9 +263,9 @@
userId1: Int = 0,
taskId2: Int,
userId2: Int = 0,
- isVisible: Boolean = false
- ): GroupedRecentTaskInfo =
- GroupedRecentTaskInfo.forSplitTasks(
+ isVisible: Boolean = false,
+ ): GroupedTaskInfo =
+ GroupedTaskInfo.forSplitTasks(
createTaskInfo(taskId1, userId1, isVisible),
createTaskInfo(taskId2, userId2, isVisible),
SplitBounds(Rect(), Rect(), taskId1, taskId2, SNAP_TO_2_50_50)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModelTest.kt
index 642d9a0..855931c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModelTest.kt
@@ -21,7 +21,6 @@
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -76,12 +75,8 @@
underTest.activateIn(this)
assertThat(
- (actions?.get(
- Swipe(
- direction = SwipeDirection.Down,
- fromSource = SceneContainerEdge.TopRight,
- )
- ) as? UserActionResult.ReplaceByOverlay)
+ (actions?.get(Swipe.Down(fromSource = SceneContainerEdge.TopRight))
+ as? UserActionResult.ReplaceByOverlay)
?.overlay
)
.isEqualTo(Overlays.QuickSettingsShade)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
index ada2138..b30313e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
@@ -35,9 +35,12 @@
import com.android.systemui.scene.domain.startable.sceneContainerStartable
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.shared.flag.DualShade
import com.android.systemui.shade.ui.viewmodel.notificationsShadeOverlayContentViewModel
+import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -121,6 +124,38 @@
assertThat(currentOverlays).doesNotContain(Overlays.NotificationsShade)
}
+ @Test
+ fun showHeader_showsOnNarrowScreen() =
+ testScope.runTest {
+ kosmos.shadeRepository.setShadeLayoutWide(false)
+
+ // Shown when notifications are present.
+ kosmos.activeNotificationListRepository.setActiveNotifs(1)
+ runCurrent()
+ assertThat(underTest.showHeader).isTrue()
+
+ // Hidden when notifications are not present.
+ kosmos.activeNotificationListRepository.setActiveNotifs(0)
+ runCurrent()
+ assertThat(underTest.showHeader).isFalse()
+ }
+
+ @Test
+ fun showHeader_hidesOnWideScreen() =
+ testScope.runTest {
+ kosmos.shadeRepository.setShadeLayoutWide(true)
+
+ // Hidden when notifications are present.
+ kosmos.activeNotificationListRepository.setActiveNotifs(1)
+ runCurrent()
+ assertThat(underTest.showHeader).isFalse()
+
+ // Hidden when notifications are not present.
+ kosmos.activeNotificationListRepository.setActiveNotifs(0)
+ runCurrent()
+ assertThat(underTest.showHeader).isFalse()
+ }
+
private fun TestScope.lockDevice() {
val currentScene by collectLastValue(sceneInteractor.currentScene)
kosmos.powerInteractor.setAsleepForTest()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java
index 16ae466..0356422 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java
@@ -42,6 +42,7 @@
import android.os.Binder;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
import android.provider.DeviceConfig;
import android.testing.TestableLooper;
@@ -49,6 +50,7 @@
import androidx.test.filters.SmallTest;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogTransitionAnimator;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -315,13 +317,36 @@
}
@Test
+ @EnableFlags(Flags.FLAG_STOPPABLE_FGS_SYSTEM_APP)
+ public void testButtonVisibilityOfStoppableApps() throws Exception {
+ setUserProfiles(0);
+ setBackgroundRestrictionExemptionReason("pkg", 12345, REASON_ALLOWLISTED_PACKAGE);
+ setBackgroundRestrictionExemptionReason("vendor_pkg", 67890, REASON_ALLOWLISTED_PACKAGE);
+
+ // Same as above, but apps are opt-in to be stoppable
+ setStoppableApps(new String[] {"pkg"}, /* vendor */ false);
+ setStoppableApps(new String[] {"vendor_pkg"}, /* vendor */ true);
+
+ final Binder binder = new Binder();
+ setShowStopButtonForUserAllowlistedApps(true);
+ // Both are foreground.
+ mIForegroundServiceObserver.onForegroundStateChanged(binder, "pkg", 0, true);
+ mIForegroundServiceObserver.onForegroundStateChanged(binder, "vendor_pkg", 0, true);
+ Assert.assertEquals(2, mFmc.visibleButtonsCount());
+
+ // The vendor package is no longer foreground. Only `pkg` remains.
+ mIForegroundServiceObserver.onForegroundStateChanged(binder, "vendor_pkg", 0, false);
+ Assert.assertEquals(1, mFmc.visibleButtonsCount());
+ }
+
+ @Test
public void testShowUserVisibleJobsOnCreation() {
// Test when the default is on.
mDeviceConfigProxyFake.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS,
"true", false);
FgsManagerController fmc = new FgsManagerControllerImpl(
- mContext,
+ mContext.getResources(),
mMainExecutor,
mBackgroundExecutor,
mSystemClock,
@@ -348,7 +373,7 @@
SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS,
"false", false);
fmc = new FgsManagerControllerImpl(
- mContext,
+ mContext.getResources(),
mMainExecutor,
mBackgroundExecutor,
mSystemClock,
@@ -446,6 +471,11 @@
.getBackgroundRestrictionExemptionReason(uid);
}
+ private void setStoppableApps(String[] packageNames, boolean vendor) throws Exception {
+ overrideResource(vendor ? com.android.internal.R.array.vendor_stoppable_fgs_system_apps
+ : com.android.internal.R.array.stoppable_fgs_system_apps, packageNames);
+ }
+
FgsManagerController createFgsManagerController() throws RemoteException {
ArgumentCaptor<IForegroundServiceObserver> iForegroundServiceObserverArgumentCaptor =
ArgumentCaptor.forClass(IForegroundServiceObserver.class);
@@ -455,7 +485,7 @@
ArgumentCaptor.forClass(BroadcastReceiver.class);
FgsManagerController result = new FgsManagerControllerImpl(
- mContext,
+ mContext.getResources(),
mMainExecutor,
mBackgroundExecutor,
mSystemClock,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
index 9fe9ed2..5cba325 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
@@ -36,6 +36,7 @@
import com.android.systemui.qs.composefragment.viewmodel.MediaState.NO_MEDIA
import com.android.systemui.qs.fgsManagerController
import com.android.systemui.qs.panels.domain.interactor.tileSquishinessInteractor
+import com.android.systemui.qs.panels.ui.viewmodel.setConfigurationForMediaInRow
import com.android.systemui.res.R
import com.android.systemui.shade.largeScreenHeaderHelper
import com.android.systemui.statusbar.StatusBarState
@@ -269,6 +270,54 @@
}
}
+ @Test
+ fun mediaNotInRow() =
+ with(kosmos) {
+ testScope.testWithinLifecycle {
+ setConfigurationForMediaInRow(mediaInRow = false)
+ setMediaState(ACTIVE_MEDIA)
+
+ assertThat(underTest.qqsMediaInRow).isFalse()
+ assertThat(underTest.qsMediaInRow).isFalse()
+ }
+ }
+
+ @Test
+ fun mediaInRow_mediaActive_bothInRow() =
+ with(kosmos) {
+ testScope.testWithinLifecycle {
+ setConfigurationForMediaInRow(mediaInRow = true)
+ setMediaState(ACTIVE_MEDIA)
+
+ assertThat(underTest.qqsMediaInRow).isTrue()
+ assertThat(underTest.qsMediaInRow).isTrue()
+ }
+ }
+
+ @Test
+ fun mediaInRow_mediaRecommendation_onlyQSInRow() =
+ with(kosmos) {
+ testScope.testWithinLifecycle {
+ setConfigurationForMediaInRow(mediaInRow = true)
+ setMediaState(ANY_MEDIA)
+
+ assertThat(underTest.qqsMediaInRow).isFalse()
+ assertThat(underTest.qsMediaInRow).isTrue()
+ }
+ }
+
+ @Test
+ fun mediaInRow_correctConfig_noMediaVisible_noMediaInRow() =
+ with(kosmos) {
+ testScope.testWithinLifecycle {
+ setConfigurationForMediaInRow(mediaInRow = true)
+ setMediaState(NO_MEDIA)
+
+ assertThat(underTest.qqsMediaInRow).isFalse()
+ assertThat(underTest.qsMediaInRow).isFalse()
+ }
+ }
+
private fun TestScope.setMediaState(state: MediaState) {
with(kosmos) {
val activeMedia = state == ACTIVE_MEDIA
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/QSFragmentComposeTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/QSFragmentComposeTest.kt
new file mode 100644
index 0000000..ab78029
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/QSFragmentComposeTest.kt
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.panels.ui
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.getBoundsInRoot
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpRect
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.width
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.composefragment.QuickQuickSettingsLayout
+import com.android.systemui.qs.composefragment.QuickSettingsLayout
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class QSFragmentComposeTest : SysuiTestCase() {
+
+ @get:Rule val composeTestRule = createComposeRule()
+
+ @Test
+ fun portraitLayout_qqs() {
+ composeTestRule.setContent {
+ QuickQuickSettingsLayout(
+ tiles = { Tiles(TILES_HEIGHT_PORTRAIT) },
+ media = { Media() },
+ mediaInRow = false,
+ )
+ }
+
+ composeTestRule.waitForIdle()
+
+ val tilesBounds = composeTestRule.onNodeWithTag(TILES).getBoundsInRoot()
+ val mediaBounds = composeTestRule.onNodeWithTag(MEDIA).getBoundsInRoot()
+
+ // All nodes aligned in a column
+ assertThat(tilesBounds.left).isEqualTo(mediaBounds.left)
+ assertThat(tilesBounds.right).isEqualTo(mediaBounds.right)
+ assertThat(tilesBounds.bottom).isLessThan(mediaBounds.top)
+ }
+
+ @Test
+ fun landscapeLayout_qqs() {
+ composeTestRule.setContent {
+ QuickQuickSettingsLayout(
+ tiles = { Tiles(TILES_HEIGHT_LANDSCAPE) },
+ media = { Media() },
+ mediaInRow = true,
+ )
+ }
+
+ composeTestRule.waitForIdle()
+
+ val tilesBounds = composeTestRule.onNodeWithTag(TILES).getBoundsInRoot()
+ val mediaBounds = composeTestRule.onNodeWithTag(MEDIA).getBoundsInRoot()
+
+ // Media to the right of tiles
+ assertThat(tilesBounds.right).isLessThan(mediaBounds.left)
+ // "Same" width
+ assertThat((tilesBounds.width - mediaBounds.width).abs()).isAtMost(1.dp)
+ // Vertically centered
+ assertThat((tilesBounds.centerY - mediaBounds.centerY).abs()).isAtMost(1.dp)
+ }
+
+ @Test
+ fun portraitLayout_qs() {
+ composeTestRule.setContent {
+ QuickSettingsLayout(
+ brightness = { Brightness() },
+ tiles = { Tiles(TILES_HEIGHT_PORTRAIT) },
+ media = { Media() },
+ mediaInRow = false,
+ )
+ }
+
+ composeTestRule.waitForIdle()
+
+ val brightnessBounds = composeTestRule.onNodeWithTag(BRIGHTNESS).getBoundsInRoot()
+ val tilesBounds = composeTestRule.onNodeWithTag(TILES).getBoundsInRoot()
+ val mediaBounds = composeTestRule.onNodeWithTag(MEDIA).getBoundsInRoot()
+
+ assertThat(brightnessBounds.left).isEqualTo(tilesBounds.left)
+ assertThat(tilesBounds.left).isEqualTo(mediaBounds.left)
+
+ assertThat(brightnessBounds.right).isEqualTo(tilesBounds.right)
+ assertThat(tilesBounds.right).isEqualTo(mediaBounds.right)
+
+ assertThat(brightnessBounds.bottom).isLessThan(tilesBounds.top)
+ assertThat(tilesBounds.bottom).isLessThan(mediaBounds.top)
+ }
+
+ @Test
+ fun landscapeLayout_qs() {
+ composeTestRule.setContent {
+ QuickSettingsLayout(
+ brightness = { Brightness() },
+ tiles = { Tiles(TILES_HEIGHT_PORTRAIT) },
+ media = { Media() },
+ mediaInRow = true,
+ )
+ }
+
+ composeTestRule.waitForIdle()
+
+ val brightnessBounds = composeTestRule.onNodeWithTag(BRIGHTNESS).getBoundsInRoot()
+ val tilesBounds = composeTestRule.onNodeWithTag(TILES).getBoundsInRoot()
+ val mediaBounds = composeTestRule.onNodeWithTag(MEDIA).getBoundsInRoot()
+
+ // Brightness takes full width, with left end aligned with tiles and right end aligned with
+ // media
+ assertThat(brightnessBounds.left).isEqualTo(tilesBounds.left)
+ assertThat(brightnessBounds.right).isEqualTo(mediaBounds.right)
+
+ // Brightness above tiles and media
+ assertThat(brightnessBounds.bottom).isLessThan(tilesBounds.top)
+ assertThat(brightnessBounds.bottom).isLessThan(mediaBounds.top)
+
+ // Media to the right of tiles
+ assertThat(tilesBounds.right).isLessThan(mediaBounds.left)
+ // "Same" width
+ assertThat((tilesBounds.width - mediaBounds.width).abs()).isAtMost(1.dp)
+ // Vertically centered
+ assertThat((tilesBounds.centerY - mediaBounds.centerY).abs()).isAtMost(1.dp)
+ }
+
+ private companion object {
+ const val BRIGHTNESS = "brightness"
+ const val TILES = "tiles"
+ const val MEDIA = "media"
+ val TILES_HEIGHT_PORTRAIT = 300.dp
+ val TILES_HEIGHT_LANDSCAPE = 150.dp
+ val MEDIA_HEIGHT = 100.dp
+ val BRIGHTNESS_HEIGHT = 64.dp
+
+ @Composable
+ fun Brightness() {
+ Box(modifier = Modifier.testTag(BRIGHTNESS).height(BRIGHTNESS_HEIGHT).fillMaxWidth())
+ }
+
+ @Composable
+ fun Tiles(height: Dp) {
+ Box(modifier = Modifier.testTag(TILES).height(height).fillMaxWidth())
+ }
+
+ @Composable
+ fun Media() {
+ Box(modifier = Modifier.testTag(MEDIA).height(MEDIA_HEIGHT).fillMaxWidth())
+ }
+
+ val DpRect.centerY: Dp
+ get() = (top + bottom) / 2
+
+ fun Dp.abs() = if (this > 0.dp) this else -this
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt
new file mode 100644
index 0000000..635bada
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.panels.ui.viewmodel
+
+import android.content.res.Configuration
+import android.content.res.mainResources
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.flags.setFlagValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QQS
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
+import com.android.systemui.media.controls.ui.controller.MediaLocation
+import com.android.systemui.media.controls.ui.controller.mediaHostStatesManager
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
+import com.android.systemui.shade.data.repository.shadeRepository
+import com.android.systemui.shade.shared.flag.DualShade
+import com.android.systemui.shade.shared.model.ShadeMode
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.runner.RunWith
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(ParameterizedAndroidJunit4::class)
+@SmallTest
+class MediaInRowInLandscapeViewModelTest(private val testData: TestData) : SysuiTestCase() {
+
+ private val kosmos = testKosmos().apply { usingMediaInComposeFragment = testData.usingMedia }
+
+ private val underTest by lazy {
+ kosmos.mediaInRowInLandscapeViewModelFactory.create(TESTED_MEDIA_LOCATION)
+ }
+
+ @Before
+ fun setUp() {
+ mSetFlagsRule.setFlagValue(DualShade.FLAG_NAME, testData.shadeMode == ShadeMode.Dual)
+ }
+
+ @Test
+ fun shouldMediaShowInRow() =
+ with(kosmos) {
+ testScope.runTest {
+ underTest.activateIn(testScope)
+
+ shadeRepository.setShadeLayoutWide(testData.shadeMode != ShadeMode.Single)
+ val config =
+ Configuration(mainResources.configuration).apply {
+ orientation = testData.orientation
+ screenLayout = testData.screenLayoutLong
+ }
+ fakeConfigurationRepository.onConfigurationChange(config)
+ mainResources.configuration.updateFrom(config)
+ mediaHostStatesManager.updateHostState(
+ testData.mediaLocation,
+ MediaHost.MediaHostStateHolder().apply { visible = testData.mediaVisible },
+ )
+ runCurrent()
+
+ assertThat(underTest.shouldMediaShowInRow).isEqualTo(testData.mediaInRowExpected)
+ }
+ }
+
+ data class TestData(
+ val usingMedia: Boolean,
+ val shadeMode: ShadeMode,
+ val orientation: Int,
+ val screenLayoutLong: Int,
+ val mediaVisible: Boolean,
+ @MediaLocation val mediaLocation: Int,
+ ) {
+ val mediaInRowExpected: Boolean
+ get() =
+ usingMedia &&
+ shadeMode == ShadeMode.Single &&
+ orientation == Configuration.ORIENTATION_LANDSCAPE &&
+ screenLayoutLong == Configuration.SCREENLAYOUT_LONG_YES &&
+ mediaVisible &&
+ mediaLocation == TESTED_MEDIA_LOCATION
+ }
+
+ companion object {
+ private const val TESTED_MEDIA_LOCATION = LOCATION_QS
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun data(): Collection<TestData> {
+ val usingMediaValues = setOf(true, false)
+ val shadeModeValues = setOf(ShadeMode.Single, ShadeMode.Split, ShadeMode.Dual)
+ val orientationValues =
+ setOf(Configuration.ORIENTATION_LANDSCAPE, Configuration.ORIENTATION_PORTRAIT)
+ val screenLayoutLongValues =
+ setOf(Configuration.SCREENLAYOUT_LONG_YES, Configuration.SCREENLAYOUT_LONG_NO)
+ val mediaVisibleValues = setOf(true, false)
+ val mediaLocationsValues = setOf(LOCATION_QS, LOCATION_QQS)
+
+ return usingMediaValues.flatMap { usingMedia ->
+ shadeModeValues.flatMap { shadeMode ->
+ orientationValues.flatMap { orientation ->
+ screenLayoutLongValues.flatMap { screenLayoutLong ->
+ mediaVisibleValues.flatMap { mediaVisible ->
+ mediaLocationsValues.map { mediaLocation ->
+ TestData(
+ usingMedia,
+ shadeMode,
+ orientation,
+ screenLayoutLong,
+ mediaVisible,
+ mediaLocation,
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelTest.kt
new file mode 100644
index 0000000..4ae8589
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelTest.kt
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.panels.ui.viewmodel
+
+import android.content.res.mainResources
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QQS
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
+import com.android.systemui.media.controls.ui.controller.MediaLocation
+import com.android.systemui.media.controls.ui.controller.mediaHostStatesManager
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
+import com.android.systemui.qs.panels.data.repository.QSColumnsRepository
+import com.android.systemui.qs.panels.data.repository.qsColumnsRepository
+import com.android.systemui.res.R
+import com.android.systemui.shade.shared.flag.DualShade
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class QSColumnsViewModelTest : SysuiTestCase() {
+ private val kosmos =
+ testKosmos().apply {
+ usingMediaInComposeFragment = true
+ testCase.context.orCreateTestableResources.addOverride(
+ R.integer.quick_settings_infinite_grid_num_columns,
+ SINGLE_SPLIT_SHADE_COLUMNS,
+ )
+ testCase.context.orCreateTestableResources.addOverride(
+ R.integer.quick_settings_dual_shade_num_columns,
+ DUAL_SHADE_COLUMNS,
+ )
+ testCase.context.orCreateTestableResources.addOverride(
+ R.integer.quick_settings_split_shade_num_columns,
+ SINGLE_SPLIT_SHADE_COLUMNS,
+ )
+ qsColumnsRepository = QSColumnsRepository(mainResources, configurationRepository)
+ }
+
+ @Test
+ @DisableFlags(DualShade.FLAG_NAME)
+ fun mediaLocationNull_singleOrSplit_alwaysSingleShadeColumns() =
+ with(kosmos) {
+ testScope.runTest {
+ val underTest = qsColumnsViewModelFactory.create(null)
+ underTest.activateIn(testScope)
+
+ setConfigurationForMediaInRow(mediaInRow = false)
+
+ makeMediaVisible(LOCATION_QQS, visible = true)
+ makeMediaVisible(LOCATION_QS, visible = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(SINGLE_SPLIT_SHADE_COLUMNS)
+
+ setConfigurationForMediaInRow(mediaInRow = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(SINGLE_SPLIT_SHADE_COLUMNS)
+ }
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ fun mediaLocationNull_dualShade_alwaysDualShadeColumns() =
+ with(kosmos) {
+ testScope.runTest {
+ val underTest = qsColumnsViewModelFactory.create(null)
+ underTest.activateIn(testScope)
+
+ setConfigurationForMediaInRow(mediaInRow = false)
+
+ makeMediaVisible(LOCATION_QQS, visible = true)
+ makeMediaVisible(LOCATION_QS, visible = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(DUAL_SHADE_COLUMNS)
+
+ setConfigurationForMediaInRow(mediaInRow = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(DUAL_SHADE_COLUMNS)
+ }
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ fun mediaLocationQS_dualShade_alwaysDualShadeColumns() =
+ with(kosmos) {
+ testScope.runTest {
+ val underTest = qsColumnsViewModelFactory.create(LOCATION_QS)
+ underTest.activateIn(testScope)
+
+ setConfigurationForMediaInRow(mediaInRow = false)
+
+ makeMediaVisible(LOCATION_QS, visible = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(DUAL_SHADE_COLUMNS)
+
+ setConfigurationForMediaInRow(mediaInRow = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(DUAL_SHADE_COLUMNS)
+ }
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ fun mediaLocationQQS_dualShade_alwaysDualShadeColumns() =
+ with(kosmos) {
+ testScope.runTest {
+ val underTest = qsColumnsViewModelFactory.create(LOCATION_QQS)
+ underTest.activateIn(testScope)
+
+ setConfigurationForMediaInRow(mediaInRow = false)
+
+ makeMediaVisible(LOCATION_QQS, visible = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(DUAL_SHADE_COLUMNS)
+
+ setConfigurationForMediaInRow(mediaInRow = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(DUAL_SHADE_COLUMNS)
+ }
+ }
+
+ @Test
+ @DisableFlags(DualShade.FLAG_NAME)
+ fun mediaLocationQS_singleOrSplit_halfColumnsOnCorrectConfigurationAndVisible() =
+ with(kosmos) {
+ testScope.runTest {
+ val underTest = qsColumnsViewModelFactory.create(LOCATION_QS)
+ underTest.activateIn(testScope)
+
+ setConfigurationForMediaInRow(mediaInRow = false)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(SINGLE_SPLIT_SHADE_COLUMNS)
+
+ setConfigurationForMediaInRow(mediaInRow = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(SINGLE_SPLIT_SHADE_COLUMNS)
+
+ makeMediaVisible(LOCATION_QS, visible = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(SINGLE_SPLIT_SHADE_COLUMNS / 2)
+ }
+ }
+
+ @Test
+ @DisableFlags(DualShade.FLAG_NAME)
+ fun mediaLocationQQS_singleOrSplit_halfColumnsOnCorrectConfigurationAndVisible() =
+ with(kosmos) {
+ testScope.runTest {
+ val underTest = qsColumnsViewModelFactory.create(LOCATION_QQS)
+ underTest.activateIn(testScope)
+
+ setConfigurationForMediaInRow(mediaInRow = false)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(SINGLE_SPLIT_SHADE_COLUMNS)
+
+ setConfigurationForMediaInRow(mediaInRow = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(SINGLE_SPLIT_SHADE_COLUMNS)
+
+ makeMediaVisible(LOCATION_QQS, visible = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(SINGLE_SPLIT_SHADE_COLUMNS / 2)
+ }
+ }
+
+ companion object {
+ private const val SINGLE_SPLIT_SHADE_COLUMNS = 4
+ private const val DUAL_SHADE_COLUMNS = 2
+
+ private fun Kosmos.makeMediaVisible(@MediaLocation location: Int, visible: Boolean) {
+ mediaHostStatesManager.updateHostState(
+ location,
+ MediaHost.MediaHostStateHolder().apply { this.visible = visible },
+ )
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
index ab5a049..3d1265a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
@@ -24,6 +24,11 @@
import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QQS
+import com.android.systemui.media.controls.ui.controller.MediaLocation
+import com.android.systemui.media.controls.ui.controller.mediaHostStatesManager
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
import com.android.systemui.qs.panels.domain.interactor.qsPreferencesInteractor
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
@@ -67,6 +72,7 @@
4,
)
fakeConfigurationRepository.onConfigurationChange()
+ usingMediaInComposeFragment = true
}
private val underTest =
@@ -145,6 +151,33 @@
}
}
+ @Test
+ fun mediaVisibleInLandscape_doubleRows_halfColumns() =
+ with(kosmos) {
+ testScope.runTest {
+ setRows(1)
+ assertThat(underTest.columns).isEqualTo(4)
+ // All tiles in 4 columns (but we only show the first 3 tiles)
+ // [1] [2] [3 3]
+ // [4] [5 5]
+ // [6 6] [7] [8]
+ // [9 9]
+
+ runCurrent()
+ assertThat(underTest.tileViewModels.map { it.tile.spec }).isEqualTo(tiles.take(3))
+
+ makeMediaVisible(LOCATION_QQS, visible = true)
+ setConfigurationForMediaInRow(mediaInRow = true)
+ runCurrent()
+
+ assertThat(underTest.columns).isEqualTo(2)
+ // Tiles in 4 columns
+ // [1] [2]
+ // [3 3]
+ assertThat(underTest.tileViewModels.map { it.tile.spec }).isEqualTo(tiles.take(3))
+ }
+ }
+
private fun Kosmos.setTiles(tiles: List<TileSpec>) {
currentTilesInteractor.setTiles(tiles)
}
@@ -163,5 +196,12 @@
private companion object {
const val PREFIX_SMALL = "small"
const val PREFIX_LARGE = "large"
+
+ private fun Kosmos.makeMediaVisible(@MediaLocation location: Int, visible: Boolean) {
+ mediaHostStatesManager.updateHostState(
+ location,
+ MediaHost.MediaHostStateHolder().apply { this.visible = visible },
+ )
+ }
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index 0d12483..53708fd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -23,7 +23,6 @@
import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -160,9 +159,7 @@
mTestableLooper.processAllMessages();
ArgumentCaptor<Runnable> onStartRecordingClicked = ArgumentCaptor.forClass(Runnable.class);
- verify(mController).createScreenRecordDialog(any(), eq(mFeatureFlags),
- eq(mDialogTransitionAnimator), eq(mActivityStarter),
- onStartRecordingClicked.capture());
+ verify(mController).createScreenRecordDialog(onStartRecordingClicked.capture());
// When starting the recording, we collapse the shade and disable the dialog animation.
assertNotNull(onStartRecordingClicked.getValue());
@@ -298,14 +295,13 @@
public void showingDialogPrompt_logsMediaProjectionPermissionRequested() {
when(mController.isStarting()).thenReturn(false);
when(mController.isRecording()).thenReturn(false);
- when(mController.createScreenRecordDialog(any(), any(), any(), any(), any()))
+ when(mController.createScreenRecordDialog(any()))
.thenReturn(mPermissionDialogPrompt);
mTile.handleClick(null /* view */);
mTestableLooper.processAllMessages();
- verify(mController).createScreenRecordDialog(any(), eq(mFeatureFlags),
- eq(mDialogTransitionAnimator), eq(mActivityStarter), any());
+ verify(mController).createScreenRecordDialog(any());
var onDismissAction = ArgumentCaptor.forClass(ActivityStarter.OnDismissAction.class);
verify(mKeyguardDismissUtil).executeWhenUnlocked(
onDismissAction.capture(), anyBoolean(), anyBoolean());
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapperTest.kt
new file mode 100644
index 0000000..2ac3e08
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapperTest.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.tiles.impl.notes.domain
+
+import android.graphics.drawable.TestStubDrawable
+import android.widget.Button
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
+import com.android.systemui.qs.tiles.impl.notes.qsNotesTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import kotlin.test.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class NotesTileMapperTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val qsTileConfig = kosmos.qsNotesTileConfig
+
+ private val mapper by lazy {
+ NotesTileMapper(
+ context.orCreateTestableResources
+ .apply { addOverride(R.drawable.ic_qs_notes, TestStubDrawable()) }
+ .resources,
+ context.theme,
+ )
+ }
+
+ @Test
+ fun mappedStateMatchesModel() {
+ val inputModel = NotesTileModel
+
+ val outputState = mapper.map(qsTileConfig, inputModel)
+
+ val expectedState = createNotesTileState()
+ QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+ }
+
+ private fun createNotesTileState(): QSTileState =
+ QSTileState(
+ Icon.Loaded(context.getDrawable(R.drawable.ic_qs_notes)!!, null),
+ R.drawable.ic_qs_notes,
+ context.getString(R.string.quick_settings_notes_label),
+ QSTileState.ActivationState.INACTIVE,
+ /* secondaryLabel= */ null,
+ setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK),
+ context.getString(R.string.quick_settings_notes_label),
+ /* stateDescription= */ null,
+ QSTileState.SideViewIcon.Chevron,
+ QSTileState.EnabledState.ENABLED,
+ Button::class.qualifiedName,
+ )
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt
new file mode 100644
index 0000000..35d6d5a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.tiles.impl.notes.domain.interactor
+
+import android.os.UserHandle
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.toCollection
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class NotesTileDataInteractorTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val testScope = kosmos.testScope
+ private val testUser = UserHandle.of(1)
+ private lateinit var underTest: NotesTileDataInteractor
+
+
+ @EnableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE)
+ @Test
+ fun availability_qsFlagEnabled_notesRoleEnabled_returnTrue() =
+ testScope.runTest {
+ underTest = NotesTileDataInteractor(isNoteTaskEnabled = true)
+
+ val availability = underTest.availability(testUser).toCollection(mutableListOf())
+
+ assertThat(availability).containsExactly(true)
+ }
+
+ @DisableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE)
+ @Test
+ fun availability_qsFlagDisabled_notesRoleEnabled_returnFalse() =
+ testScope.runTest {
+ underTest = NotesTileDataInteractor(isNoteTaskEnabled = true)
+
+ val availability = underTest.availability(testUser).toCollection(mutableListOf())
+
+ assertThat(availability).containsExactly(false)
+ }
+
+ @EnableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE)
+ @Test
+ fun availability_qsFlagEnabled_notesRoleDisabled_returnFalse() =
+ testScope.runTest {
+ underTest = NotesTileDataInteractor(isNoteTaskEnabled = false)
+
+ val availability = underTest.availability(testUser).toCollection(mutableListOf())
+
+ assertThat(availability).containsExactly(false)
+ }
+
+ @DisableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE)
+ @Test
+ fun availability_qsFlagDisabled_notesRoleDisabled_returnFalse() =
+ testScope.runTest {
+ underTest = NotesTileDataInteractor(isNoteTaskEnabled = false)
+
+ val availability = underTest.availability(testUser).toCollection(mutableListOf())
+
+ assertThat(availability).containsExactly(false)
+ }
+
+ @Test
+ fun tileData_notEmpty() = runTest {
+ underTest = NotesTileDataInteractor(isNoteTaskEnabled = true)
+ val flowValue by
+ collectLastValue(underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest)))
+
+ runCurrent()
+
+ assertThat(flowValue).isNotNull()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt
new file mode 100644
index 0000000..54911e6
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.tiles.impl.notes.domain.interactor
+
+import android.content.Intent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.notetask.NoteTaskController
+import com.android.systemui.notetask.NoteTaskEntryPoint
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
+import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class NotesTileUserActionInteractorTest : SysuiTestCase() {
+ private val kosmos = Kosmos()
+ private val testScope = kosmos.testScope
+ private val inputHandler = FakeQSTileIntentUserInputHandler()
+ private val panelInteractor = mock<PanelInteractor>()
+ private val noteTaskController = mock<NoteTaskController>()
+
+ private lateinit var underTest: NotesTileUserActionInteractor
+
+ @Before
+ fun setUp() {
+ underTest = NotesTileUserActionInteractor(inputHandler, panelInteractor, noteTaskController)
+ }
+
+ @Test
+ fun handleClick_launchDefaultNotesApp() =
+ testScope.runTest {
+ underTest.handleInput(QSTileInputTestKtx.click(NotesTileModel))
+
+ verify(noteTaskController).showNoteTask(NoteTaskEntryPoint.QS_NOTES_TILE)
+ }
+
+ @Test
+ fun handleLongClick_launchSettings() =
+ testScope.runTest {
+ underTest.handleInput(QSTileInputTestKtx.longClick(NotesTileModel))
+
+ QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
+ assertThat(it.intent.action).isEqualTo(Intent.ACTION_MANAGE_DEFAULT_APP)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt
index 899122d..0b56d7b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt
@@ -23,29 +23,27 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.animation.Expandable
-import com.android.systemui.flags.featureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
import com.android.systemui.plugins.ActivityStarter.OnDismissAction
-import com.android.systemui.plugins.activityStarter
import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
import com.android.systemui.screenrecord.RecordingController
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.ScreenRecordRepositoryImpl
import com.android.systemui.statusbar.phone.KeyguardDismissUtil
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -54,24 +52,11 @@
private val testScope = kosmos.testScope
private val keyguardInteractor = kosmos.keyguardInteractor
private val dialogTransitionAnimator = mock<DialogTransitionAnimator>()
- private val featureFlags = kosmos.featureFlagsClassic
- private val activityStarter = kosmos.activityStarter
private val keyguardDismissUtil = mock<KeyguardDismissUtil>()
private val panelInteractor = mock<PanelInteractor>()
private val dialog = mock<Dialog>()
private val recordingController =
- mock<RecordingController> {
- whenever(
- createScreenRecordDialog(
- eq(context),
- eq(featureFlags),
- eq(dialogTransitionAnimator),
- eq(activityStarter),
- any()
- )
- )
- .thenReturn(dialog)
- }
+ mock<RecordingController> { on { createScreenRecordDialog(any()) } doReturn dialog }
private val screenRecordRepository =
ScreenRecordRepositoryImpl(
@@ -81,7 +66,6 @@
private val underTest =
ScreenRecordTileUserActionInteractor(
- context,
testScope.testScheduler,
testScope.testScheduler,
screenRecordRepository,
@@ -91,8 +75,6 @@
dialogTransitionAnimator,
panelInteractor,
mock<MediaProjectionMetricsLogger>(),
- featureFlags,
- activityStarter,
)
@Test
@@ -120,22 +102,16 @@
underTest.handleInput(QSTileInputTestKtx.click(recordingModel))
val onStartRecordingClickedCaptor = argumentCaptor<Runnable>()
verify(recordingController)
- .createScreenRecordDialog(
- eq(context),
- eq(featureFlags),
- eq(dialogTransitionAnimator),
- eq(activityStarter),
- onStartRecordingClickedCaptor.capture()
- )
+ .createScreenRecordDialog(onStartRecordingClickedCaptor.capture())
val onDismissActionCaptor = argumentCaptor<OnDismissAction>()
verify(keyguardDismissUtil)
.executeWhenUnlocked(onDismissActionCaptor.capture(), eq(false), eq(true))
- onDismissActionCaptor.value.onDismiss()
+ onDismissActionCaptor.lastValue.onDismiss()
verify(dialog).show() // because the view was null
// When starting the recording, we collapse the shade and disable the dialog animation.
- onStartRecordingClickedCaptor.value.run()
+ onStartRecordingClickedCaptor.lastValue.run()
verify(dialogTransitionAnimator).disableAllCurrentDialogsExitAnimations()
verify(panelInteractor).collapsePanels()
}
@@ -145,9 +121,9 @@
*/
@Test
fun handleClickFromView_whenDoingNothing_whenKeyguardNotShowing_showDialogFromView() = runTest {
- val expandable = mock<Expandable>()
val controller = mock<DialogTransitionAnimator.Controller>()
- whenever(expandable.dialogTransitionController(any())).thenReturn(controller)
+ val expandable =
+ mock<Expandable> { on { dialogTransitionController(any()) } doReturn controller }
kosmos.fakeKeyguardRepository.setKeyguardShowing(false)
@@ -158,18 +134,12 @@
)
val onStartRecordingClickedCaptor = argumentCaptor<Runnable>()
verify(recordingController)
- .createScreenRecordDialog(
- eq(context),
- eq(featureFlags),
- eq(dialogTransitionAnimator),
- eq(activityStarter),
- onStartRecordingClickedCaptor.capture()
- )
+ .createScreenRecordDialog(onStartRecordingClickedCaptor.capture())
val onDismissActionCaptor = argumentCaptor<OnDismissAction>()
verify(keyguardDismissUtil)
.executeWhenUnlocked(onDismissActionCaptor.capture(), eq(false), eq(true))
- onDismissActionCaptor.value.onDismiss()
+ onDismissActionCaptor.lastValue.onDismiss()
verify(dialogTransitionAnimator).show(eq(dialog), eq(controller), eq(true))
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModelTest.kt
index c3a777c..9396445 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModelTest.kt
@@ -21,7 +21,6 @@
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -89,12 +88,8 @@
underTest.activateIn(this)
assertThat(
- (actions?.get(
- Swipe(
- direction = SwipeDirection.Down,
- fromSource = SceneContainerEdge.TopLeft,
- )
- ) as? UserActionResult.ReplaceByOverlay)
+ (actions?.get(Swipe.Down(fromSource = SceneContainerEdge.TopLeft))
+ as? UserActionResult.ReplaceByOverlay)
?.overlay
)
.isEqualTo(Overlays.NotificationsShade)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
index f32894d..24f6b6d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
@@ -31,6 +31,7 @@
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.startable.sceneContainerStartable
import com.android.systemui.scene.shared.model.Overlays
@@ -55,7 +56,10 @@
@EnableFlags(DualShade.FLAG_NAME)
class QuickSettingsShadeOverlayContentViewModelTest : SysuiTestCase() {
- private val kosmos = testKosmos()
+ private val kosmos =
+ testKosmos().apply {
+ usingMediaInComposeFragment = false // This is not for the compose fragment
+ }
private val testScope = kosmos.testScope
private val sceneInteractor = kosmos.sceneInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModelTest.kt
index 62b6391..d5fbe49 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModelTest.kt
@@ -22,7 +22,6 @@
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
@@ -98,9 +97,8 @@
.isEqualTo(
mapOf(
Back to UserActionResult(Scenes.Shade),
- Swipe(SwipeDirection.Up) to UserActionResult(Scenes.Shade),
- Swipe(fromSource = Edge.Bottom, direction = SwipeDirection.Up) to
- UserActionResult(SceneFamilies.Home),
+ Swipe.Up to UserActionResult(Scenes.Shade),
+ Swipe.Up(fromSource = Edge.Bottom) to UserActionResult(SceneFamilies.Home),
)
)
assertThat(homeScene).isEqualTo(Scenes.Gone)
@@ -125,9 +123,8 @@
.isEqualTo(
mapOf(
Back to UserActionResult(Scenes.Lockscreen),
- Swipe(SwipeDirection.Up) to UserActionResult(Scenes.Lockscreen),
- Swipe(fromSource = Edge.Bottom, direction = SwipeDirection.Up) to
- UserActionResult(SceneFamilies.Home),
+ Swipe.Up to UserActionResult(Scenes.Lockscreen),
+ Swipe.Up(fromSource = Edge.Bottom) to UserActionResult(SceneFamilies.Home),
)
)
assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
@@ -154,9 +151,8 @@
.isEqualTo(
mapOf(
Back to UserActionResult(Scenes.Shade),
- Swipe(SwipeDirection.Up) to UserActionResult(Scenes.Shade),
- Swipe(fromSource = Edge.Bottom, direction = SwipeDirection.Up) to
- UserActionResult(SceneFamilies.Home),
+ Swipe.Up to UserActionResult(Scenes.Shade),
+ Swipe.Up(fromSource = Edge.Bottom) to UserActionResult(SceneFamilies.Home),
)
)
assertThat(homeScene).isEqualTo(Scenes.Gone)
@@ -178,9 +174,8 @@
.isEqualTo(
mapOf(
Back to UserActionResult(Scenes.Shade),
- Swipe(SwipeDirection.Up) to UserActionResult(Scenes.Shade),
- Swipe(fromSource = Edge.Bottom, direction = SwipeDirection.Up) to
- UserActionResult(SceneFamilies.Home),
+ Swipe.Up to UserActionResult(Scenes.Shade),
+ Swipe.Up(fromSource = Edge.Bottom) to UserActionResult(SceneFamilies.Home),
)
)
assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
@@ -214,9 +209,8 @@
.isEqualTo(
mapOf(
Back to UserActionResult(Scenes.Shade),
- Swipe(SwipeDirection.Up) to UserActionResult(Scenes.Shade),
- Swipe(fromSource = Edge.Bottom, direction = SwipeDirection.Up) to
- UserActionResult(SceneFamilies.Home),
+ Swipe.Up to UserActionResult(Scenes.Shade),
+ Swipe.Up(fromSource = Edge.Bottom) to UserActionResult(SceneFamilies.Home),
)
)
assertThat(homeScene).isEqualTo(Scenes.Gone)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 2c8f7cf..55f88cc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -2119,40 +2119,6 @@
}
@Test
- fun switchToGone_whenSurfaceBehindLockscreenVisibleMidTransition() =
- testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene)
- val transitionStateFlow =
- prepareState(authenticationMethod = AuthenticationMethodModel.None)
- underTest.start()
- assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
- // Swipe to Gone, more than halfway
- transitionStateFlow.value =
- ObservableTransitionState.Transition(
- fromScene = Scenes.Lockscreen,
- toScene = Scenes.Gone,
- currentScene = flowOf(Scenes.Gone),
- progress = flowOf(0.51f),
- isInitiatedByUserInput = true,
- isUserInputOngoing = flowOf(true),
- )
- runCurrent()
- // Lift finger
- transitionStateFlow.value =
- ObservableTransitionState.Transition(
- fromScene = Scenes.Lockscreen,
- toScene = Scenes.Gone,
- currentScene = flowOf(Scenes.Gone),
- progress = flowOf(0.51f),
- isInitiatedByUserInput = true,
- isUserInputOngoing = flowOf(false),
- )
- runCurrent()
-
- assertThat(currentScene).isEqualTo(Scenes.Gone)
- }
-
- @Test
fun switchToGone_extendUnlock() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt
index 47fae9f..bb2e941 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt
@@ -23,7 +23,6 @@
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.SysuiTestCase
@@ -71,8 +70,7 @@
shadeRepository.setShadeLayoutWide(true)
runCurrent()
- assertThat(userActions?.get(Swipe(SwipeDirection.Down))?.transitionKey)
- .isEqualTo(ToSplitShade)
+ assertThat(userActions?.get(Swipe.Down)?.transitionKey).isEqualTo(ToSplitShade)
}
@Test
@@ -83,7 +81,7 @@
shadeRepository.setShadeLayoutWide(false)
runCurrent()
- assertThat(userActions?.get(Swipe(SwipeDirection.Down))?.transitionKey).isNull()
+ assertThat(userActions?.get(Swipe.Down)?.transitionKey).isNull()
}
@Test
@@ -94,7 +92,7 @@
shadeRepository.setShadeLayoutWide(true)
runCurrent()
- assertThat(userActions?.get(Swipe(SwipeDirection.Down))?.transitionKey).isNull()
+ assertThat(userActions?.get(Swipe.Down)?.transitionKey).isNull()
}
@Test
@@ -132,6 +130,6 @@
}
private fun swipeDownFromTopWithTwoFingers(): UserAction {
- return Swipe(direction = SwipeDirection.Down, pointerCount = 2, fromSource = Edge.Top)
+ return Swipe.Down(pointerCount = 2, fromSource = Edge.Top)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt
index 972afb5..d5f57da 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt
@@ -22,7 +22,6 @@
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.SysuiTestCase
@@ -77,7 +76,7 @@
val expected1 =
mapOf(
Back to UserActionResult(toScene = Scenes.Gone),
- Swipe(SwipeDirection.Up) to UserActionResult(toScene = Scenes.Shade)
+ Swipe.Up to UserActionResult(toScene = Scenes.Shade),
)
underTest.upstream.value = expected1
runCurrent()
@@ -86,7 +85,7 @@
val expected2 =
mapOf(
Back to UserActionResult(toScene = Scenes.Lockscreen),
- Swipe(SwipeDirection.Down) to UserActionResult(toScene = Scenes.Shade)
+ Swipe.Down to UserActionResult(toScene = Scenes.Shade),
)
underTest.upstream.value = expected2
runCurrent()
@@ -104,7 +103,7 @@
val expected =
mapOf(
Back to UserActionResult(toScene = Scenes.Lockscreen),
- Swipe(SwipeDirection.Down) to UserActionResult(toScene = Scenes.Shade)
+ Swipe.Down to UserActionResult(toScene = Scenes.Shade),
)
underTest.upstream.value = expected
runCurrent()
@@ -120,7 +119,7 @@
val upstream = MutableStateFlow<Map<UserAction, UserActionResult>>(emptyMap())
override suspend fun hydrateActions(
- setActions: (Map<UserAction, UserActionResult>) -> Unit,
+ setActions: (Map<UserAction, UserActionResult>) -> Unit
) {
upstream.collect { setActions(it) }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt
index 41e2467..ae7719b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt
@@ -16,13 +16,19 @@
package com.android.systemui.settings.brightness
+import android.hardware.display.BrightnessInfo
import android.hardware.display.DisplayManager
import android.os.Handler
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
import android.service.vr.IVrManager
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
+import android.view.Display
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.LogBuffer
import com.android.systemui.settings.DisplayTracker
@@ -30,13 +36,16 @@
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
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.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -44,7 +53,8 @@
@RunWith(AndroidJUnit4::class)
@RunWithLooper
class BrightnessControllerTest : SysuiTestCase() {
-
+ @get:Rule
+ public val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
private val executor = FakeExecutor(FakeSystemClock())
private val secureSettings = FakeSettings()
@Mock private lateinit var toggleSlider: ToggleSlider
@@ -53,6 +63,7 @@
@Mock private lateinit var displayManager: DisplayManager
@Mock private lateinit var iVrManager: IVrManager
@Mock private lateinit var logger: LogBuffer
+ @Mock private lateinit var display: Display
private lateinit var testableLooper: TestableLooper
@@ -63,9 +74,11 @@
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
+ val contextSpy = spy(context)
+ whenever(contextSpy.getDisplay()).thenReturn(display)
underTest =
BrightnessController(
- context,
+ contextSpy,
toggleSlider,
userTracker,
displayTracker,
@@ -105,4 +118,21 @@
assertThat(messagesProcessed).isEqualTo(1)
}
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SHOW_TOAST_WHEN_APP_CONTROL_BRIGHTNESS)
+ fun testOnChange_showToastWhenAppOverridesBrightness() {
+ val brightnessInfo = BrightnessInfo(
+ 0.45f, 0.45f, 0.0f, 1.0f, BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ 1.0f /* highBrightnessTransitionPoint */,
+ BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE,
+ true /* isBrightnessOverrideByWindow */
+ )
+ whenever(display.brightnessInfo).thenReturn(brightnessInfo)
+ underTest.registerCallbacks()
+ testableLooper.processAllMessages()
+
+ underTest.onChanged(true /* tracking */, 100 /* value */, false /* stopTracking */)
+ verify(toggleSlider).showToast(any())
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
index 637a12c..3697c31 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
@@ -27,6 +27,7 @@
import com.android.systemui.haptics.slider.HapticSlider
import com.android.systemui.haptics.slider.HapticSliderPlugin
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.settings.brightness.ui.BrightnessWarningToast
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.BrightnessMirrorController
import com.android.systemui.util.mockito.any
@@ -64,6 +65,7 @@
@Mock private lateinit var vibratorHelper: VibratorHelper
@Mock private lateinit var msdlPlayer: MSDLPlayer
@Mock private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var brightnessWarningToast: BrightnessWarningToast
@Captor
private lateinit var seekBarChangeCaptor: ArgumentCaptor<SeekBar.OnSeekBarChangeListener>
@@ -94,6 +96,7 @@
HapticSlider.SeekBar(seekBar),
),
activityStarter,
+ brightnessWarningToast,
)
mController.init()
mController.setOnChangedListener(listener)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt
index fcb366b..bbfc66a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt
@@ -92,10 +92,7 @@
AuthenticationMethodModel.Pin
)
- assertThat(
- (actions?.get(Swipe(SwipeDirection.Up)) as? UserActionResult.ChangeScene)
- ?.toScene
- )
+ assertThat((actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene)
.isEqualTo(SceneFamilies.Home)
assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
}
@@ -110,10 +107,7 @@
)
setDeviceEntered(true)
- assertThat(
- (actions?.get(Swipe(SwipeDirection.Up)) as? UserActionResult.ChangeScene)
- ?.toScene
- )
+ assertThat((actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene)
.isEqualTo(SceneFamilies.Home)
assertThat(homeScene).isEqualTo(Scenes.Gone)
}
@@ -128,10 +122,7 @@
)
kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
- assertThat(
- (actions?.get(Swipe(SwipeDirection.Up)) as? UserActionResult.ChangeScene)
- ?.toScene
- )
+ assertThat((actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene)
.isEqualTo(SceneFamilies.Home)
assertThat(homeScene).isEqualTo(Scenes.Gone)
}
@@ -147,10 +138,7 @@
)
sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
- assertThat(
- (actions?.get(Swipe(SwipeDirection.Up)) as? UserActionResult.ChangeScene)
- ?.toScene
- )
+ assertThat((actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene)
.isEqualTo(SceneFamilies.Home)
assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
}
@@ -167,10 +155,7 @@
runCurrent()
sceneInteractor.changeScene(Scenes.Gone, "reason")
- assertThat(
- (actions?.get(Swipe(SwipeDirection.Up)) as? UserActionResult.ChangeScene)
- ?.toScene
- )
+ assertThat((actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene)
.isEqualTo(SceneFamilies.Home)
assertThat(homeScene).isEqualTo(Scenes.Gone)
}
@@ -182,8 +167,7 @@
shadeRepository.setShadeLayoutWide(true)
runCurrent()
- assertThat(actions?.get(Swipe(SwipeDirection.Up))?.transitionKey)
- .isEqualTo(ToSplitShade)
+ assertThat(actions?.get(Swipe.Up)?.transitionKey).isEqualTo(ToSplitShade)
}
@Test
@@ -193,7 +177,7 @@
shadeRepository.setShadeLayoutWide(false)
runCurrent()
- assertThat(actions?.get(Swipe(SwipeDirection.Up))?.transitionKey).isNull()
+ assertThat(actions?.get(Swipe.Up)?.transitionKey).isNull()
}
@Test
@@ -202,10 +186,7 @@
overrideResource(R.bool.config_use_split_notification_shade, true)
kosmos.shadeStartable.start()
val actions by collectLastValue(underTest.actions)
- assertThat(
- (actions?.get(Swipe(SwipeDirection.Down)) as? UserActionResult.ChangeScene)
- ?.toScene
- )
+ assertThat((actions?.get(Swipe.Down) as? UserActionResult.ChangeScene)?.toScene)
.isNull()
}
@@ -215,10 +196,7 @@
overrideResource(R.bool.config_use_split_notification_shade, false)
kosmos.shadeStartable.start()
val actions by collectLastValue(underTest.actions)
- assertThat(
- (actions?.get(Swipe(SwipeDirection.Down)) as? UserActionResult.ChangeScene)
- ?.toScene
- )
+ assertThat((actions?.get(Swipe.Down) as? UserActionResult.ChangeScene)?.toScene)
.isEqualTo(Scenes.QuickSettings)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
index 4478252..33a0803 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java
@@ -86,6 +86,7 @@
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.user.domain.interactor.UserLogoutInteractor;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.wakelock.WakeLockFake;
@@ -160,6 +161,8 @@
@Mock
protected DeviceEntryFingerprintAuthInteractor mDeviceEntryFingerprintAuthInteractor;
@Mock
+ protected UserLogoutInteractor mUserLogoutInteractor;
+ @Mock
protected ScreenLifecycle mScreenLifecycle;
@Mock
protected AuthController mAuthController;
@@ -248,6 +251,9 @@
when(mFaceHelpMessageDeferralFactory.create()).thenReturn(mFaceHelpMessageDeferral);
when(mDeviceEntryFingerprintAuthInteractor.isEngaged()).thenReturn(mock(StateFlow.class));
+ StateFlow mockLogoutEnabledFlow = mock(StateFlow.class);
+ when(mockLogoutEnabledFlow.getValue()).thenReturn(false);
+ when(mUserLogoutInteractor.isLogoutEnabled()).thenReturn(mockLogoutEnabledFlow);
mIndicationHelper = new IndicationHelper(mKeyguardUpdateMonitor);
@@ -291,7 +297,8 @@
KeyguardInteractorFactory.create(mFlags).getKeyguardInteractor(),
mBiometricMessageInteractor,
mDeviceEntryFingerprintAuthInteractor,
- mDeviceEntryFaceAuthInteractor
+ mDeviceEntryFaceAuthInteractor,
+ mUserLogoutInteractor
);
mController.init();
mController.setIndicationArea(mIndicationArea);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
index d6b3b91..72a2ce5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
@@ -85,7 +85,6 @@
underTest =
OperatorNameViewController.Factory(
- darkIconDispatcher,
tunerService,
telephonyManager,
keyguardUpdateMonitor,
@@ -94,7 +93,7 @@
subscriptionManagerProxy,
javaAdapter,
)
- .create(view)
+ .create(view, darkIconDispatcher)
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 60a1855..fb7252b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar;
+import static android.app.Notification.CATEGORY_CALL;
+
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
@@ -197,6 +199,19 @@
}
@Test
+ public void testContentDescForNotification_noNotifContent() {
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(0)
+ .setContentTitle("hello")
+ .setCategory(CATEGORY_CALL)
+ .build();
+ assertThat(NotificationContentDescription.contentDescForNotification(mContext, n)
+ .toString()).startsWith("com.android.systemui.tests notification");
+ assertThat(NotificationContentDescription.contentDescForNotification(mContext, n)
+ .toString()).doesNotContain("hello");
+ }
+
+ @Test
@EnableFlags({Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS})
public void setIcon_withPreloaded_usesPreloaded() {
Icon mockIcon = mock(Icon.class);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
index 32f4164..1b41329 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
@@ -97,7 +97,7 @@
assertThat(latest).hasSize(1)
val chip = latest!![0]
- assertThat(chip).isInstanceOf(OngoingActivityChipModel.Shown.ShortTimeDelta::class.java)
+ assertThat(chip).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
assertThat(chip.icon).isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarView(icon))
}
@@ -168,8 +168,7 @@
companion object {
fun assertIsNotifChip(latest: OngoingActivityChipModel?, expectedIcon: StatusBarIconView) {
- assertThat(latest)
- .isInstanceOf(OngoingActivityChipModel.Shown.ShortTimeDelta::class.java)
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
assertThat((latest as OngoingActivityChipModel.Shown).icon)
.isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarView(expectedIcon))
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
index 0efd591..11a125a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
@@ -16,29 +16,35 @@
package com.android.systemui.statusbar.chips.screenrecord.domain.interactor
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_STATUS_BAR_AUTO_START_SCREEN_RECORD_CHIP
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.screenRecordRepository
import com.android.systemui.statusbar.chips.screenrecord.domain.model.ScreenRecordChipModel
+import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalCoroutinesApi::class)
class ScreenRecordChipInteractorTest : SysuiTestCase() {
- private val kosmos = Kosmos().also { it.testCase = this }
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
private val testScope = kosmos.testScope
private val screenRecordRepo = kosmos.screenRecordRepository
private val mediaProjectionRepo = kosmos.fakeMediaProjectionRepository
@@ -116,6 +122,137 @@
}
@Test
+ @DisableFlags(FLAG_STATUS_BAR_AUTO_START_SCREEN_RECORD_CHIP)
+ fun screenRecordState_flagOff_doesNotAutomaticallySwitchToRecordingBasedOnTime() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.screenRecordState)
+
+ // WHEN screen record should start in 900ms
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(900)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Starting(900))
+
+ // WHEN 900ms has elapsed
+ advanceTimeBy(901)
+
+ // THEN we don't automatically update to the recording state if the flag is off
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Starting(900))
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_AUTO_START_SCREEN_RECORD_CHIP)
+ fun screenRecordState_flagOn_automaticallySwitchesToRecordingBasedOnTime() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.screenRecordState)
+
+ // WHEN screen record should start in 900ms
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(900)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Starting(900))
+
+ // WHEN 900ms has elapsed
+ advanceTimeBy(901)
+
+ // THEN we automatically update to the recording state
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = null))
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_AUTO_START_SCREEN_RECORD_CHIP)
+ fun screenRecordState_recordingBeginsEarly_switchesToRecording() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.screenRecordState)
+
+ // WHEN screen record should start in 900ms
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(900)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Starting(900))
+
+ // WHEN we update to the Recording state earlier than 900ms
+ advanceTimeBy(800)
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
+ val task = createTask(taskId = 1)
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ "host.package",
+ hostDeviceName = null,
+ task,
+ )
+
+ // THEN we immediately switch to Recording, and we have the task
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = task))
+
+ // WHEN more than 900ms has elapsed
+ advanceTimeBy(200)
+
+ // THEN we still stay in the Recording state and we have the task
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = task))
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_AUTO_START_SCREEN_RECORD_CHIP)
+ fun screenRecordState_secondRecording_doesNotAutomaticallyStart() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.screenRecordState)
+
+ // First recording starts, records, and stops
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(900)
+ advanceTimeBy(900)
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
+ advanceTimeBy(5000)
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.DoingNothing
+ advanceTimeBy(10000)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.DoingNothing)
+
+ // WHEN a second recording is starting
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(2900)
+
+ // THEN we stay as starting and do not switch to Recording (verifying the auto-start
+ // timer is reset)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Starting(2900))
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_AUTO_START_SCREEN_RECORD_CHIP)
+ fun screenRecordState_startingButThenDoingNothing_doesNotAutomaticallyStart() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.screenRecordState)
+
+ // WHEN a screen recording is starting in 500ms
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(500)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Starting(500))
+
+ // But it's cancelled after 300ms
+ advanceTimeBy(300)
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.DoingNothing
+
+ // THEN we don't automatically start the recording 200ms later
+ advanceTimeBy(201)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.DoingNothing)
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_AUTO_START_SCREEN_RECORD_CHIP)
+ fun screenRecordState_multipleStartingValues_autoStartResets() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.screenRecordState)
+
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(2900)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Starting(2900))
+
+ advanceTimeBy(2800)
+
+ // WHEN there's 100ms left to go before auto-start, but then we get a new start time
+ // that's in 500ms
+ screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(500)
+
+ // THEN we don't auto-start in 100ms
+ advanceTimeBy(101)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Starting(500))
+
+ // THEN we *do* auto-start 400ms later
+ advanceTimeBy(401)
+ assertThat(latest).isEqualTo(ScreenRecordChipModel.Recording(recordedTask = null))
+ }
+
+ @Test
fun stopRecording_sendsToRepo() =
testScope.runTest {
assertThat(screenRecordRepo.stopRecordingInvoked).isFalse()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
index bfebe18..48d8add6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
@@ -26,9 +26,8 @@
import com.android.systemui.animation.mockDialogTransitionAnimator
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager
@@ -44,6 +43,7 @@
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.getStopActionFromDialog
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
+import com.android.systemui.testKosmos
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
@@ -61,7 +61,7 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
class ScreenRecordChipViewModelTest : SysuiTestCase() {
- private val kosmos = Kosmos().also { it.testCase = this }
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
private val testScope = kosmos.testScope
private val screenRecordRepo = kosmos.screenRecordRepository
private val mediaProjectionRepo = kosmos.fakeMediaProjectionRepository
@@ -254,7 +254,7 @@
MediaProjectionState.Projecting.SingleTask(
"host.package",
hostDeviceName = null,
- FakeActivityTaskManager.createTask(taskId = 1)
+ FakeActivityTaskManager.createTask(taskId = 1),
)
// THEN the start time is still the old start time
@@ -275,12 +275,7 @@
clickListener!!.onClick(chipView)
// EndScreenRecordingDialogDelegate will test that the dialog has the right message
verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockSystemUIDialog),
- eq(chipBackgroundView),
- any(),
- anyBoolean(),
- )
+ .showFromView(eq(mockSystemUIDialog), eq(chipBackgroundView), any(), anyBoolean())
}
@Test
@@ -297,12 +292,7 @@
clickListener!!.onClick(chipView)
// EndScreenRecordingDialogDelegate will test that the dialog has the right message
verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockSystemUIDialog),
- eq(chipBackgroundView),
- any(),
- anyBoolean(),
- )
+ .showFromView(eq(mockSystemUIDialog), eq(chipBackgroundView), any(), anyBoolean())
}
@Test
@@ -314,7 +304,7 @@
MediaProjectionState.Projecting.SingleTask(
"host.package",
hostDeviceName = null,
- FakeActivityTaskManager.createTask(taskId = 1)
+ FakeActivityTaskManager.createTask(taskId = 1),
)
val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
@@ -323,12 +313,7 @@
clickListener!!.onClick(chipView)
// EndScreenRecordingDialogDelegate will test that the dialog has the right message
verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockSystemUIDialog),
- eq(chipBackgroundView),
- any(),
- anyBoolean(),
- )
+ .showFromView(eq(mockSystemUIDialog), eq(chipBackgroundView), any(), anyBoolean())
}
@Test
@@ -344,12 +329,7 @@
val cujCaptor = argumentCaptor<DialogCuj>()
verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- any(),
- any(),
- cujCaptor.capture(),
- anyBoolean(),
- )
+ .showFromView(any(), any(), cujCaptor.capture(), anyBoolean())
assertThat(cujCaptor.firstValue.cujType)
.isEqualTo(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index e96def6..c5c2a94 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -29,7 +29,6 @@
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testScope
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
@@ -48,6 +47,7 @@
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
+import com.android.systemui.testKosmos
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -72,7 +72,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@DisableFlags(StatusBarNotifChips.FLAG_NAME)
class OngoingActivityChipsViewModelTest : SysuiTestCase() {
- private val kosmos = Kosmos().also { it.testCase = this }
+ private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val systemClock = kosmos.fakeSystemClock
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt
index 5be5fb4..c06da4b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt
@@ -23,9 +23,11 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.data.repository.fakeLightBarControllerStore
import com.android.systemui.statusbar.data.repository.fakePrivacyDotWindowControllerStore
import com.android.systemui.testKosmos
import com.google.common.truth.Expect
+import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -48,6 +50,7 @@
private val fakeOrchestratorFactory = kosmos.fakeStatusBarOrchestratorFactory
private val fakeInitializerStore = kosmos.fakeStatusBarInitializerStore
private val fakePrivacyDotStore = kosmos.fakePrivacyDotWindowControllerStore
+ private val fakeLightBarStore = kosmos.fakeLightBarControllerStore
// Lazy, so that @EnableFlags is set before initializer is instantiated.
private val underTest by lazy { kosmos.multiDisplayStatusBarStarter }
@@ -95,6 +98,31 @@
}
@Test
+ fun start_doesNotStartLightBarControllerForCurrentDisplays() =
+ testScope.runTest {
+ fakeDisplayRepository.addDisplay(displayId = 1)
+ fakeDisplayRepository.addDisplay(displayId = 2)
+
+ underTest.start()
+ runCurrent()
+
+ verify(fakeLightBarStore.forDisplay(displayId = 1), never()).start()
+ verify(fakeLightBarStore.forDisplay(displayId = 2), never()).start()
+ }
+
+ @Test
+ fun start_createsLightBarControllerForCurrentDisplays() =
+ testScope.runTest {
+ fakeDisplayRepository.addDisplay(displayId = 1)
+ fakeDisplayRepository.addDisplay(displayId = 2)
+
+ underTest.start()
+ runCurrent()
+
+ assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(1, 2)
+ }
+
+ @Test
fun start_doesNotStartPrivacyDotForDefaultDisplay() =
testScope.runTest {
fakeDisplayRepository.addDisplay(displayId = Display.DEFAULT_DISPLAY)
@@ -145,6 +173,30 @@
}
@Test
+ fun displayAdded_lightBarForNewDisplayIsCreated() =
+ testScope.runTest {
+ underTest.start()
+ runCurrent()
+
+ fakeDisplayRepository.addDisplay(displayId = 3)
+ runCurrent()
+
+ assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(3)
+ }
+
+ @Test
+ fun displayAdded_lightBarForNewDisplayIsNotStarted() =
+ testScope.runTest {
+ underTest.start()
+ runCurrent()
+
+ fakeDisplayRepository.addDisplay(displayId = 3)
+ runCurrent()
+
+ verify(fakeLightBarStore.forDisplay(displayId = 3), never()).start()
+ }
+
+ @Test
fun displayAddedDuringStart_initializerForNewDisplayIsStarted() =
testScope.runTest {
underTest.start()
@@ -178,4 +230,26 @@
verify(fakePrivacyDotStore.forDisplay(displayId = 3)).start()
}
+
+ @Test
+ fun displayAddedDuringStart_lightBarForNewDisplayIsCreated() =
+ testScope.runTest {
+ underTest.start()
+
+ fakeDisplayRepository.addDisplay(displayId = 3)
+ runCurrent()
+
+ assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(3)
+ }
+
+ @Test
+ fun displayAddedDuringStart_lightBarForNewDisplayIsNotStarted() =
+ testScope.runTest {
+ underTest.start()
+
+ fakeDisplayRepository.addDisplay(displayId = 3)
+ runCurrent()
+
+ verify(fakeLightBarStore.forDisplay(displayId = 3), never()).start()
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
new file mode 100644
index 0000000..a2c3c66
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.data.repository
+
+import android.platform.test.annotations.EnableFlags
+import android.view.Display.DEFAULT_DISPLAY
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
+class MultiDisplayDarkIconDispatcherStoreTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val testScope = kosmos.testScope
+ private val fakeDisplayRepository = kosmos.displayRepository
+
+ // Lazy so that @EnableFlags has time to run before underTest is instantiated.
+ private val underTest by lazy { kosmos.multiDisplayDarkIconDispatcherStore }
+
+ @Before
+ fun start() {
+ underTest.start()
+ }
+
+ @Before fun addDisplays() = runBlocking { fakeDisplayRepository.addDisplay(DEFAULT_DISPLAY) }
+
+ @Test
+ fun beforeDisplayRemoved_doesNotStopInstances() =
+ testScope.runTest {
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+
+ verify(instance, never()).stop()
+ }
+
+ @Test
+ fun displayRemoved_stopsInstance() =
+ testScope.runTest {
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+
+ fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+
+ verify(instance).stop()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationContentDescriptionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationContentDescriptionTest.kt
index 12473cb..896f940 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationContentDescriptionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationContentDescriptionTest.kt
@@ -34,31 +34,9 @@
private val TICKER = "this is a ticker"
@Test
- fun notificationWithAllDifferentFields_descriptionIsTitle() {
+ fun notificationWithAllDifferentFields_descriptionIsAppName() {
val n = createNotification(TITLE, TEXT, TICKER)
val description = contentDescForNotification(context, n)
- assertThat(description).isEqualTo(createDescriptionText(n, TITLE))
- }
-
- @Test
- fun notificationWithAllDifferentFields_titleMatchesAppName_descriptionIsText() {
- val n = createNotification(getTestAppName(), TEXT, TICKER)
- val description = contentDescForNotification(context, n)
- assertThat(description).isEqualTo(createDescriptionText(n, TEXT))
- }
-
- @Test
- fun notificationWithAllDifferentFields_titleMatchesAppNameNoText_descriptionIsTicker() {
- val n = createNotification(getTestAppName(), null, TICKER)
- val description = contentDescForNotification(context, n)
- assertThat(description).isEqualTo(createDescriptionText(n, TICKER))
- }
-
- @Test
- fun notificationWithAllDifferentFields_titleMatchesAppNameNoTextNoTicker_descriptionEmpty() {
- val appName = getTestAppName()
- val n = createNotification(appName, null, null)
- val description = contentDescForNotification(context, n)
assertThat(description).isEqualTo(createDescriptionText(n, ""))
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
index 3b5d358..c4b1b84 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar.notification
+import android.platform.test.flag.junit.FlagsParameterization
import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
@@ -26,11 +26,17 @@
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.flags.andSceneContainer
import com.android.systemui.keyguard.domain.interactor.pulseExpansionInteractor
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.ShadeViewController.Companion.WAKEUP_ANIMATION_DELAY_MS
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
@@ -41,9 +47,6 @@
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
-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
@@ -55,16 +58,21 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.anyFloat
-import org.mockito.Mockito.clearInvocations
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyNoMoreInteractions
+import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
-class NotificationWakeUpCoordinatorTest : SysuiTestCase() {
+class NotificationWakeUpCoordinatorTest(flags: FlagsParameterization) : SysuiTestCase() {
@get:Rule val animatorTestRule = AnimatorTestRule(this)
@@ -105,6 +113,18 @@
statusBarStateCallback.onDozeAmountChanged(dozeAmount, dozeAmount)
}
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return FlagsParameterization.allCombinationsOf().andSceneContainer()
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
@Before
fun setup() {
whenever(bypassController.bypassEnabled).then { bypassEnabled }
@@ -178,6 +198,7 @@
}
@Test
+ @DisableSceneContainer
fun setDozeToZeroWhenCommunalShowingWillFullyHideNotifications() =
testScope.runTest {
val transitionState =
@@ -192,6 +213,17 @@
}
@Test
+ @EnableSceneContainer
+ fun setDozeToZeroWhenCommunalShowingWillFullyHideNotifications_withSceneContainer() =
+ testScope.runTest {
+ kosmos.setSceneTransition(Idle(Scenes.Communal))
+ setDozeAmount(0f)
+ verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f)
+ assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue()
+ }
+
+ @Test
+ @DisableSceneContainer
fun closingCommunalWillShowNotifications() =
testScope.runTest {
val transitionState =
@@ -211,6 +243,20 @@
}
@Test
+ @EnableSceneContainer
+ fun closingCommunalWillShowNotifications_withSceneContainer() =
+ testScope.runTest {
+ kosmos.setSceneTransition(Idle(Scenes.Communal))
+ setDozeAmount(0f)
+ verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f)
+ assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue()
+
+ kosmos.setSceneTransition(Idle(CommunalScenes.Blank))
+ verifyStackScrollerDozeAndHideAmount(dozeAmount = 0f, hideAmount = 0f)
+ assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse()
+ }
+
+ @Test
fun switchingToShadeWithBypassEnabledWillShowNotifications() {
setDozeToZeroWithBypassWillFullyHideNotifications()
clearInvocations(stackScrollerController)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
index 740abf3..76390fd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
@@ -18,12 +18,13 @@
import android.content.res.mainResources
import android.platform.test.annotations.DisableFlags
-import androidx.test.ext.junit.runners.AndroidJUnit4
+import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.Flags
+import com.android.systemui.flags.andSceneContainer
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -51,17 +52,20 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(AndroidJUnit4::class)
-class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class NotificationIconContainerAlwaysOnDisplayViewModelTest(flags: FlagsParameterization) :
+ SysuiTestCase() {
private val kosmos =
testKosmos().apply {
fakeFeatureFlagsClassic.apply { set(Flags.FULL_SCREEN_USER_SWITCHER, value = false) }
}
- val underTest =
+ val underTest by lazy {
NotificationIconContainerAlwaysOnDisplayViewModel(
kosmos.testDispatcher,
kosmos.alwaysOnDisplayNotificationIconsInteractor,
@@ -70,11 +74,24 @@
kosmos.mainResources,
kosmos.shadeInteractor,
)
+ }
val testScope = kosmos.testScope
val keyguardRepository = kosmos.fakeKeyguardRepository
val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
val powerRepository = kosmos.fakePowerRepository
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return FlagsParameterization.allCombinationsOf().andSceneContainer()
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
@Before
fun setup() {
keyguardRepository.setKeyguardShowing(true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
index 9367a93..46c360a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
@@ -110,14 +110,10 @@
lastSleepReason = WakeSleepReason.OTHER,
)
keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- transitionState = TransitionState.STARTED,
- )
+ TransitionStep(transitionState = TransitionState.STARTED)
)
keyguardRepository.setDozeTransitionModel(
- DozeTransitionModel(
- to = DozeStateModel.DOZE_AOD,
- )
+ DozeTransitionModel(to = DozeStateModel.DOZE_AOD)
)
val animationsEnabled by collectLastValue(underTest.animationsEnabled)
runCurrent()
@@ -133,14 +129,10 @@
lastSleepReason = WakeSleepReason.OTHER,
)
keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- transitionState = TransitionState.STARTED,
- )
+ TransitionStep(transitionState = TransitionState.STARTED)
)
keyguardRepository.setDozeTransitionModel(
- DozeTransitionModel(
- to = DozeStateModel.DOZE_PULSING,
- )
+ DozeTransitionModel(to = DozeStateModel.DOZE_PULSING)
)
val animationsEnabled by collectLastValue(underTest.animationsEnabled)
runCurrent()
@@ -201,9 +193,7 @@
lastSleepReason = WakeSleepReason.OTHER,
)
keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- transitionState = TransitionState.STARTED,
- )
+ TransitionStep(transitionState = TransitionState.STARTED)
)
val animationsEnabled by collectLastValue(underTest.animationsEnabled)
runCurrent()
@@ -216,9 +206,7 @@
val animationsEnabled by collectLastValue(underTest.animationsEnabled)
keyguardTransitionRepository.sendTransitionStep(
- TransitionStep(
- transitionState = TransitionState.STARTED,
- )
+ TransitionStep(transitionState = TransitionState.STARTED)
)
keyguardRepository.setKeyguardShowing(true)
runCurrent()
@@ -234,13 +222,10 @@
@Test
fun iconColors_testsDarkBounds() =
testScope.runTest {
- darkIconRepository.darkState.value =
- SysuiDarkIconDispatcher.DarkChange(
- emptyList(),
- 0f,
- 0xAABBCC,
- )
- val iconColorsLookup by collectLastValue(underTest.iconColors)
+ val displayId = 123
+ darkIconRepository.darkState(displayId).value =
+ SysuiDarkIconDispatcher.DarkChange(emptyList(), 0f, 0xAABBCC)
+ val iconColorsLookup by collectLastValue(underTest.iconColors(displayId))
assertThat(iconColorsLookup).isNotNull()
val iconColors = iconColorsLookup?.iconColors(Rect())
@@ -257,13 +242,10 @@
@Test
fun iconColors_staticDrawableColor_notInDarkTintArea() =
testScope.runTest {
- darkIconRepository.darkState.value =
- SysuiDarkIconDispatcher.DarkChange(
- listOf(Rect(0, 0, 5, 5)),
- 0f,
- 0xAABBCC,
- )
- val iconColorsLookup by collectLastValue(underTest.iconColors)
+ val displayId = 321
+ darkIconRepository.darkState(displayId).value =
+ SysuiDarkIconDispatcher.DarkChange(listOf(Rect(0, 0, 5, 5)), 0f, 0xAABBCC)
+ val iconColorsLookup by collectLastValue(underTest.iconColors(displayId))
val iconColors = iconColorsLookup?.iconColors(Rect(1, 1, 4, 4))
val staticDrawableColor = iconColors?.staticDrawableColor(Rect(6, 6, 7, 7))
assertThat(staticDrawableColor).isEqualTo(DarkIconDispatcher.DEFAULT_ICON_TINT)
@@ -272,13 +254,10 @@
@Test
fun iconColors_notInDarkTintArea() =
testScope.runTest {
- darkIconRepository.darkState.value =
- SysuiDarkIconDispatcher.DarkChange(
- listOf(Rect(0, 0, 5, 5)),
- 0f,
- 0xAABBCC,
- )
- val iconColorsLookup by collectLastValue(underTest.iconColors)
+ val displayId = 987
+ darkIconRepository.darkState(displayId).value =
+ SysuiDarkIconDispatcher.DarkChange(listOf(Rect(0, 0, 5, 5)), 0f, 0xAABBCC)
+ val iconColorsLookup by collectLastValue(underTest.iconColors(displayId))
val iconColors = iconColorsLookup?.iconColors(Rect(6, 6, 7, 7))
assertThat(iconColors).isNull()
}
@@ -295,7 +274,7 @@
activeNotificationModel(
key = "notif1",
groupKey = "group",
- statusBarIcon = icon
+ statusBarIcon = icon,
)
)
}
@@ -322,7 +301,7 @@
activeNotificationModel(
key = "notif1",
groupKey = "group",
- statusBarIcon = icon
+ statusBarIcon = icon,
)
)
}
@@ -354,7 +333,7 @@
activeNotificationModel(
key = "notif1",
groupKey = "group",
- statusBarIcon = icon
+ statusBarIcon = icon,
)
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
new file mode 100644
index 0000000..a1b63b1
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
@@ -0,0 +1,648 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.statusbar.notification.row
+
+import android.R
+import android.app.AppOpsManager
+import android.app.INotificationManager
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Intent
+import android.content.pm.LauncherApps
+import android.content.pm.PackageManager
+import android.content.pm.ShortcutManager
+import android.graphics.Color
+import android.os.Binder
+import android.os.UserManager
+import android.os.fakeExecutorHandler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.provider.Settings
+import android.service.notification.NotificationListenerService
+import android.testing.TestableLooper.RunWithLooper
+import android.util.ArraySet
+import android.view.View
+import android.view.accessibility.AccessibilityManager
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.internal.statusbar.IStatusBarService
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.flags.andSceneContainer
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.people.widget.PeopleSpaceWidgetManager
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.power.domain.interactor.PowerInteractorFactory.create
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
+import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.settings.UserContextProvider
+import com.android.systemui.shade.ShadeController
+import com.android.systemui.statusbar.NotificationEntryHelper
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.NotificationPresenter
+import com.android.systemui.statusbar.notification.AssistantFeedbackController
+import com.android.systemui.statusbar.notification.NotificationActivityStarter
+import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
+import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.statusbar.policy.HeadsUpManager
+import com.android.systemui.testKosmos
+import com.android.systemui.util.kotlin.JavaAdapter
+import com.android.systemui.wmshell.BubblesManager
+import java.util.Optional
+import kotlin.test.assertNotNull
+import kotlin.test.fail
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.invocation.InvocationOnMock
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.doNothing
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+/** Tests for [NotificationGutsManager]. */
+@SmallTest
+@RunWith(ParameterizedAndroidJunit4::class)
+@RunWithLooper
+class NotificationGutsManagerTest(flags: FlagsParameterization) : SysuiTestCase() {
+ private val testNotificationChannel =
+ NotificationChannel(
+ TEST_CHANNEL_ID,
+ TEST_CHANNEL_ID,
+ NotificationManager.IMPORTANCE_DEFAULT,
+ )
+
+ private val kosmos = testKosmos()
+
+ private val testScope = kosmos.testScope
+ private val javaAdapter = JavaAdapter(testScope.backgroundScope)
+ private val executor = kosmos.fakeExecutor
+ private val handler = kosmos.fakeExecutorHandler
+ private lateinit var helper: NotificationTestHelper
+ private lateinit var gutsManager: NotificationGutsManager
+
+ @get:Rule val rule: MockitoRule = MockitoJUnit.rule()
+
+ @Mock private lateinit var metricsLogger: MetricsLogger
+ @Mock private lateinit var onUserInteractionCallback: OnUserInteractionCallback
+ @Mock private lateinit var presenter: NotificationPresenter
+ @Mock private lateinit var notificationActivityStarter: NotificationActivityStarter
+ @Mock private lateinit var notificationListContainer: NotificationListContainer
+ @Mock
+ private lateinit var onSettingsClickListener: NotificationGutsManager.OnSettingsClickListener
+ @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController
+ @Mock private lateinit var accessibilityManager: AccessibilityManager
+ @Mock private lateinit var highPriorityProvider: HighPriorityProvider
+ @Mock private lateinit var iNotificationManager: INotificationManager
+ @Mock private lateinit var barService: IStatusBarService
+ @Mock private lateinit var launcherApps: LauncherApps
+ @Mock private lateinit var shortcutManager: ShortcutManager
+ @Mock private lateinit var channelEditorDialogController: ChannelEditorDialogController
+ @Mock private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier
+ @Mock private lateinit var contextTracker: UserContextProvider
+ @Mock private lateinit var bubblesManager: BubblesManager
+ @Mock private lateinit var shadeController: ShadeController
+ @Mock private lateinit var peopleSpaceWidgetManager: PeopleSpaceWidgetManager
+ @Mock private lateinit var assistantFeedbackController: AssistantFeedbackController
+ @Mock private lateinit var notificationLockscreenUserManager: NotificationLockscreenUserManager
+ @Mock private lateinit var statusBarStateController: StatusBarStateController
+ @Mock private lateinit var headsUpManager: HeadsUpManager
+ @Mock private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var userManager: UserManager
+
+ private lateinit var windowRootViewVisibilityInteractor: WindowRootViewVisibilityInteractor
+
+ companion object {
+ private const val TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId"
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return FlagsParameterization.allCombinationsOf().andSceneContainer()
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
+ @Before
+ fun setUp() {
+ allowTestableLooperAsMainThread()
+ helper = NotificationTestHelper(mContext, mDependency)
+ whenever(accessibilityManager.isTouchExplorationEnabled).thenReturn(false)
+
+ windowRootViewVisibilityInteractor =
+ WindowRootViewVisibilityInteractor(
+ testScope.backgroundScope,
+ WindowRootViewVisibilityRepository(barService, executor),
+ FakeKeyguardRepository(),
+ headsUpManager,
+ create().powerInteractor,
+ kosmos.activeNotificationsInteractor,
+ ) {
+ kosmos.sceneInteractor
+ }
+
+ gutsManager =
+ NotificationGutsManager(
+ mContext,
+ handler,
+ handler,
+ javaAdapter,
+ accessibilityManager,
+ highPriorityProvider,
+ iNotificationManager,
+ userManager,
+ peopleSpaceWidgetManager,
+ launcherApps,
+ shortcutManager,
+ channelEditorDialogController,
+ contextTracker,
+ assistantFeedbackController,
+ Optional.of(bubblesManager),
+ UiEventLoggerFake(),
+ onUserInteractionCallback,
+ shadeController,
+ windowRootViewVisibilityInteractor,
+ notificationLockscreenUserManager,
+ statusBarStateController,
+ barService,
+ deviceProvisionedController,
+ metricsLogger,
+ headsUpManager,
+ activityStarter,
+ )
+ gutsManager.setUpWithPresenter(
+ presenter,
+ notificationListContainer,
+ onSettingsClickListener,
+ )
+ gutsManager.setNotificationActivityStarter(notificationActivityStarter)
+ gutsManager.start()
+ }
+
+ @Test
+ fun testOpenAndCloseGuts() {
+ val guts = spy(NotificationGuts(mContext))
+ whenever(guts.post(any())).thenAnswer { invocation: InvocationOnMock ->
+ handler.post(((invocation.arguments[0] as Runnable)))
+ null
+ }
+
+ // Test doesn't support animation since the guts view is not attached.
+ doNothing().whenever(guts).openControls(anyInt(), anyInt(), anyBoolean(), any())
+
+ val realRow = createTestNotificationRow()
+ val menuItem = createTestMenuItem(realRow)
+
+ val row = spy(realRow)
+ whenever(row.windowToken).thenReturn(Binder())
+ whenever(row.guts).thenReturn(guts)
+
+ assertTrue(gutsManager.openGutsInternal(row, 0, 0, menuItem))
+ assertEquals(View.INVISIBLE.toLong(), guts.visibility.toLong())
+ executor.runAllReady()
+ verify(guts).openControls(anyInt(), anyInt(), anyBoolean(), any<Runnable>())
+ verify(headsUpManager).setGutsShown(realRow.entry, true)
+
+ assertEquals(View.VISIBLE.toLong(), guts.visibility.toLong())
+ gutsManager.closeAndSaveGuts(false, false, true, 0, 0, false)
+
+ verify(guts).closeControls(anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyBoolean())
+ verify(row, times(1)).setGutsView(any<MenuItem>())
+ executor.runAllReady()
+ verify(headsUpManager).setGutsShown(realRow.entry, false)
+ }
+
+ @Test
+ fun testLockscreenShadeVisible_visible_gutsNotClosed() =
+ testScope.runTest {
+ // First, start out lockscreen or shade as not visible
+ windowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(false)
+ runCurrent()
+
+ val guts: NotificationGuts = mock()
+ gutsManager.exposedGuts = guts
+
+ // WHEN the lockscreen or shade becomes visible
+ windowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true)
+ runCurrent()
+
+ // THEN the guts are not closed
+ verify(guts, never()).removeCallbacks(any())
+ verify(guts, never())
+ .closeControls(anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyBoolean())
+ }
+
+ @Test
+ @DisableSceneContainer
+ fun testLockscreenShadeVisible_notVisible_gutsClosed() =
+ testScope.runTest {
+ // First, start out lockscreen or shade as visible
+ windowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true)
+ runCurrent()
+
+ val guts: NotificationGuts = mock()
+ gutsManager.exposedGuts = guts
+
+ // WHEN the lockscreen or shade is no longer visible
+ windowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(false)
+ runCurrent()
+
+ // THEN the guts are closed
+ verify(guts).removeCallbacks(null)
+ verify(guts)
+ .closeControls(
+ /* leavebehinds = */ eq(true),
+ /* controls = */ eq(true),
+ /* x = */ anyInt(),
+ /* y = */ anyInt(),
+ /* force = */ eq(true),
+ )
+ }
+
+ @Test
+ @EnableSceneContainer
+ fun testShadeVisible_notVisible_gutsClosed() =
+ testScope.runTest {
+ // First, start with shade as visible
+ kosmos.setSceneTransition(Idle(Scenes.Shade))
+ runCurrent()
+
+ val guts: NotificationGuts = mock()
+ gutsManager.exposedGuts = guts
+
+ // WHEN the shade is no longer visible
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
+ runCurrent()
+
+ // THEN the guts are closed
+ verify(guts).removeCallbacks(null)
+ verify(guts)
+ .closeControls(
+ /* leavebehinds = */ eq(true),
+ /* controls = */ eq(true),
+ /* x = */ anyInt(),
+ /* y = */ anyInt(),
+ /* force = */ eq(true),
+ )
+ }
+
+ @Test
+ @DisableSceneContainer
+ fun testLockscreenShadeVisible_notVisible_listContainerReset() =
+ testScope.runTest {
+ // First, start out lockscreen or shade as visible
+ windowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true)
+ runCurrent()
+ clearInvocations(notificationListContainer)
+
+ // WHEN the lockscreen or shade is no longer visible
+ windowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(false)
+ runCurrent()
+
+ // THEN the list container is reset
+ verify(notificationListContainer).resetExposedMenuView(anyBoolean(), anyBoolean())
+ }
+
+ @Test
+ @EnableSceneContainer
+ fun testShadeVisible_notVisible_listContainerReset() =
+ testScope.runTest {
+ // First, start with shade as visible
+ kosmos.setSceneTransition(Idle(Scenes.Shade))
+ runCurrent()
+ clearInvocations(notificationListContainer)
+
+ // WHEN the shade is no longer visible
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
+ runCurrent()
+
+ // THEN the list container is reset
+ verify(notificationListContainer).resetExposedMenuView(anyBoolean(), anyBoolean())
+ }
+
+ @Test
+ fun testChangeDensityOrFontScale() {
+ val guts = spy(NotificationGuts(mContext))
+ whenever(guts.post(any())).thenAnswer { invocation: InvocationOnMock ->
+ handler.post(((invocation.arguments[0] as Runnable)))
+ null
+ }
+
+ // Test doesn't support animation since the guts view is not attached.
+ doNothing().whenever(guts).openControls(anyInt(), anyInt(), anyBoolean(), any<Runnable>())
+
+ val realRow = createTestNotificationRow()
+ val menuItem = createTestMenuItem(realRow)
+
+ val row = spy(realRow)
+
+ whenever(row.windowToken).thenReturn(Binder())
+ whenever(row.guts).thenReturn(guts)
+ doNothing().whenever(row).ensureGutsInflated()
+
+ val realEntry = realRow.entry
+ val entry = spy(realEntry)
+
+ whenever(entry.row).thenReturn(row)
+ whenever(entry.guts).thenReturn(guts)
+
+ assertTrue(gutsManager.openGutsInternal(row, 0, 0, menuItem))
+ executor.runAllReady()
+ verify(guts).openControls(anyInt(), anyInt(), anyBoolean(), any<Runnable>())
+
+ // called once by mGutsManager.bindGuts() in mGutsManager.openGuts()
+ verify(row).setGutsView(any<MenuItem>())
+
+ row.onDensityOrFontScaleChanged()
+ gutsManager.onDensityOrFontScaleChanged(entry)
+
+ executor.runAllReady()
+
+ gutsManager.closeAndSaveGuts(false, false, false, 0, 0, false)
+
+ verify(guts).closeControls(anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyBoolean())
+
+ // called again by mGutsManager.bindGuts(), in mGutsManager.onDensityOrFontScaleChanged()
+ verify(row, times(2)).setGutsView(any<MenuItem>())
+ }
+
+ @Test
+ fun testAppOpsSettingsIntent_camera() {
+ val row = createTestNotificationRow()
+ val ops = ArraySet<Int>()
+ ops.add(AppOpsManager.OP_CAMERA)
+ gutsManager.startAppOpsSettingsActivity("", 0, ops, row)
+ val captor = argumentCaptor<Intent>()
+ verify(notificationActivityStarter, times(1))
+ .startNotificationGutsIntent(captor.capture(), anyInt(), eq(row))
+ assertEquals(Intent.ACTION_MANAGE_APP_PERMISSIONS, captor.lastValue.action)
+ }
+
+ @Test
+ fun testAppOpsSettingsIntent_mic() {
+ val row = createTestNotificationRow()
+ val ops = ArraySet<Int>()
+ ops.add(AppOpsManager.OP_RECORD_AUDIO)
+ gutsManager.startAppOpsSettingsActivity("", 0, ops, row)
+ val captor = argumentCaptor<Intent>()
+ verify(notificationActivityStarter, times(1))
+ .startNotificationGutsIntent(captor.capture(), anyInt(), eq(row))
+ assertEquals(Intent.ACTION_MANAGE_APP_PERMISSIONS, captor.lastValue.action)
+ }
+
+ @Test
+ fun testAppOpsSettingsIntent_camera_mic() {
+ val row = createTestNotificationRow()
+ val ops = ArraySet<Int>()
+ ops.add(AppOpsManager.OP_CAMERA)
+ ops.add(AppOpsManager.OP_RECORD_AUDIO)
+ gutsManager.startAppOpsSettingsActivity("", 0, ops, row)
+ val captor = argumentCaptor<Intent>()
+ verify(notificationActivityStarter, times(1))
+ .startNotificationGutsIntent(captor.capture(), anyInt(), eq(row))
+ assertEquals(Intent.ACTION_MANAGE_APP_PERMISSIONS, captor.lastValue.action)
+ }
+
+ @Test
+ fun testAppOpsSettingsIntent_overlay() {
+ val row = createTestNotificationRow()
+ val ops = ArraySet<Int>()
+ ops.add(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
+ gutsManager.startAppOpsSettingsActivity("", 0, ops, row)
+ val captor = argumentCaptor<Intent>()
+ verify(notificationActivityStarter, times(1))
+ .startNotificationGutsIntent(captor.capture(), anyInt(), eq(row))
+ assertEquals(Settings.ACTION_MANAGE_APP_OVERLAY_PERMISSION, captor.lastValue.action)
+ }
+
+ @Test
+ fun testAppOpsSettingsIntent_camera_mic_overlay() {
+ val row = createTestNotificationRow()
+ val ops = ArraySet<Int>()
+ ops.add(AppOpsManager.OP_CAMERA)
+ ops.add(AppOpsManager.OP_RECORD_AUDIO)
+ ops.add(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
+ gutsManager.startAppOpsSettingsActivity("", 0, ops, row)
+ val captor = argumentCaptor<Intent>()
+ verify(notificationActivityStarter, times(1))
+ .startNotificationGutsIntent(captor.capture(), anyInt(), eq(row))
+ assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.lastValue.action)
+ }
+
+ @Test
+ fun testAppOpsSettingsIntent_camera_overlay() {
+ val row = createTestNotificationRow()
+ val ops = ArraySet<Int>()
+ ops.add(AppOpsManager.OP_CAMERA)
+ ops.add(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
+ gutsManager.startAppOpsSettingsActivity("", 0, ops, row)
+ val captor = argumentCaptor<Intent>()
+ verify(notificationActivityStarter, times(1))
+ .startNotificationGutsIntent(captor.capture(), anyInt(), eq(row))
+ assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.lastValue.action)
+ }
+
+ @Test
+ fun testAppOpsSettingsIntent_mic_overlay() {
+ val row = createTestNotificationRow()
+ val ops = ArraySet<Int>()
+ ops.add(AppOpsManager.OP_RECORD_AUDIO)
+ ops.add(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
+ gutsManager.startAppOpsSettingsActivity("", 0, ops, row)
+ val captor = argumentCaptor<Intent>()
+ verify(notificationActivityStarter, times(1))
+ .startNotificationGutsIntent(captor.capture(), anyInt(), eq(row))
+ assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.lastValue.action)
+ }
+
+ @Test
+ @Throws(Exception::class)
+ fun testInitializeNotificationInfoView_highPriority() {
+ val notificationInfoView: NotificationInfo = mock()
+ val row = spy(helper.createRow())
+ val entry = row.entry
+ NotificationEntryHelper.modifyRanking(entry)
+ .setUserSentiment(NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE)
+ .setImportance(NotificationManager.IMPORTANCE_HIGH)
+ .build()
+
+ whenever(row.isNonblockable).thenReturn(false)
+ whenever(highPriorityProvider.isHighPriority(entry)).thenReturn(true)
+ val statusBarNotification = entry.sbn
+ gutsManager.initializeNotificationInfo(row, notificationInfoView)
+
+ verify(notificationInfoView)
+ .bindNotification(
+ any<PackageManager>(),
+ any<INotificationManager>(),
+ eq(onUserInteractionCallback),
+ eq(channelEditorDialogController),
+ eq(statusBarNotification.packageName),
+ any<NotificationChannel>(),
+ eq(entry),
+ any<NotificationInfo.OnSettingsClickListener>(),
+ any<NotificationInfo.OnAppSettingsClickListener>(),
+ any<UiEventLogger>(),
+ /* isDeviceProvisioned = */ eq(false),
+ /* isNonblockable = */ eq(false),
+ /* wasShownHighPriority = */ eq(true),
+ eq(assistantFeedbackController),
+ eq(metricsLogger),
+ )
+ }
+
+ @Test
+ @Throws(Exception::class)
+ fun testInitializeNotificationInfoView_PassesAlongProvisionedState() {
+ val notificationInfoView: NotificationInfo = mock()
+ val row = spy(helper.createRow())
+ NotificationEntryHelper.modifyRanking(row.entry)
+ .setUserSentiment(NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE)
+ .build()
+ whenever(row.isNonblockable).thenReturn(false)
+ val statusBarNotification = row.entry.sbn
+ val entry = row.entry
+
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+
+ gutsManager.initializeNotificationInfo(row, notificationInfoView)
+
+ verify(notificationInfoView)
+ .bindNotification(
+ any<PackageManager>(),
+ any<INotificationManager>(),
+ eq(onUserInteractionCallback),
+ eq(channelEditorDialogController),
+ eq(statusBarNotification.packageName),
+ any<NotificationChannel>(),
+ eq(entry),
+ any<NotificationInfo.OnSettingsClickListener>(),
+ any<NotificationInfo.OnAppSettingsClickListener>(),
+ any<UiEventLogger>(),
+ /* isDeviceProvisioned = */ eq(true),
+ /* isNonblockable = */ eq(false),
+ /* wasShownHighPriority = */ eq(false),
+ eq(assistantFeedbackController),
+ eq(metricsLogger),
+ )
+ }
+
+ @Test
+ @Throws(Exception::class)
+ fun testInitializeNotificationInfoView_withInitialAction() {
+ val notificationInfoView: NotificationInfo = mock()
+ val row = spy(helper.createRow())
+ NotificationEntryHelper.modifyRanking(row.entry)
+ .setUserSentiment(NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE)
+ .build()
+ whenever(row.isNonblockable).thenReturn(false)
+ val statusBarNotification = row.entry.sbn
+ val entry = row.entry
+
+ gutsManager.initializeNotificationInfo(row, notificationInfoView)
+
+ verify(notificationInfoView)
+ .bindNotification(
+ any<PackageManager>(),
+ any<INotificationManager>(),
+ eq(onUserInteractionCallback),
+ eq(channelEditorDialogController),
+ eq(statusBarNotification.packageName),
+ any<NotificationChannel>(),
+ eq(entry),
+ any<NotificationInfo.OnSettingsClickListener>(),
+ any<NotificationInfo.OnAppSettingsClickListener>(),
+ any<UiEventLogger>(),
+ /* isDeviceProvisioned = */ eq(false),
+ /* isNonblockable = */ eq(false),
+ /* wasShownHighPriority = */ eq(false),
+ eq(assistantFeedbackController),
+ eq(metricsLogger),
+ )
+ }
+
+ private fun createTestNotificationRow(): ExpandableNotificationRow {
+ val nb =
+ Notification.Builder(mContext, testNotificationChannel.id)
+ .setContentTitle("foo")
+ .setColorized(true)
+ .setColor(Color.RED)
+ .setFlag(Notification.FLAG_CAN_COLORIZE, true)
+ .setSmallIcon(R.drawable.sym_def_app_icon)
+
+ try {
+ val row = helper.createRow(nb.build())
+ NotificationEntryHelper.modifyRanking(row.entry)
+ .setChannel(testNotificationChannel)
+ .build()
+ return row
+ } catch (e: Exception) {
+ fail()
+ }
+ }
+
+ private fun createTestMenuItem(
+ row: ExpandableNotificationRow
+ ): NotificationMenuRowPlugin.MenuItem {
+ val menuRow: NotificationMenuRowPlugin =
+ NotificationMenuRow(mContext, peopleNotificationIdentifier)
+ menuRow.createMenu(row, row.entry.sbn)
+
+ val menuItem = menuRow.getLongpressMenuItem(mContext)
+ assertNotNull(menuItem)
+ return menuItem
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
index 327a07d6..4176d1c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
@@ -15,35 +15,55 @@
*
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.statusbar.notification.stack.domain.interactor
-import androidx.test.ext.junit.runners.AndroidJUnit4
+import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.andSceneContainer
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@SmallTest
-@RunWith(AndroidJUnit4::class)
-class SharedNotificationContainerInteractorTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class SharedNotificationContainerInteractorTest(flags: FlagsParameterization) : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val keyguardRepository = kosmos.fakeKeyguardRepository
private val configurationRepository = kosmos.fakeConfigurationRepository
private val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
- private val underTest = kosmos.sharedNotificationContainerInteractor
+ private val underTest by lazy { kosmos.sharedNotificationContainerInteractor }
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return FlagsParameterization.allCombinationsOf().andSceneContainer()
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
@Test
+ @DisableSceneContainer
fun validateConfigValues() =
testScope.runTest {
overrideResource(R.bool.config_use_split_notification_shade, true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
index 11dd587..cae9907 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt
@@ -31,10 +31,13 @@
import androidx.annotation.ColorInt
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.data.repository.statusBarConfigurationControllerStore
+import com.android.systemui.statusbar.data.repository.sysUiDarkIconDispatcherStore
import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange
import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -50,16 +53,18 @@
@SmallTest
class StatusOverlayHoverListenerTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
private val viewOverlay = mock<ViewGroupOverlay>()
private val overlayCaptor = argumentCaptor<Drawable>()
- private val darkDispatcher = mock<SysuiDarkIconDispatcher>()
private val darkChange: MutableStateFlow<DarkChange> = MutableStateFlow(DarkChange.EMPTY)
+ private val darkDispatcher = kosmos.sysUiDarkIconDispatcherStore.forDisplay(context.displayId)
private val factory =
StatusOverlayHoverListenerFactory(
context.resources,
FakeConfigurationController(),
- darkDispatcher
+ kosmos.sysUiDarkIconDispatcherStore,
+ kosmos.statusBarConfigurationControllerStore,
)
private val view = TestableStatusContainer(context, viewOverlay)
@@ -186,7 +191,7 @@
/* action= */ action,
/* x= */ 0f,
/* y= */ 0f,
- /* metaState= */ 0
+ /* metaState= */ 0,
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index 9dcbe1b..ff0321b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -99,6 +99,7 @@
whenever(mainLooper.isCurrentThread).thenReturn(true)
whenever(mainLooper.thread).thenReturn(thread)
whenever(thread.name).thenReturn("backgroundThread")
+ whenever(context.applicationContext).thenReturn(context)
whenever(context.resources).thenReturn(resources)
whenever(context.mainExecutor).thenReturn(mContext.mainExecutor)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
index b03c679..6b371d7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.user.data.repository
+import android.app.admin.devicePolicyManager
import android.content.pm.UserInfo
import android.os.UserHandle
import android.os.UserManager
@@ -24,6 +25,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
@@ -57,6 +59,8 @@
private val testDispatcher = kosmos.testDispatcher
private val testScope = kosmos.testScope
private val globalSettings = kosmos.fakeGlobalSettings
+ private val broadcastDispatcher = kosmos.broadcastDispatcher
+ private val devicePolicyManager = kosmos.devicePolicyManager
@Mock private lateinit var manager: UserManager
@@ -317,6 +321,8 @@
backgroundDispatcher = testDispatcher,
globalSettings = globalSettings,
tracker = tracker,
+ broadcastDispatcher = broadcastDispatcher,
+ devicePolicyManager = devicePolicyManager,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorTest.kt
new file mode 100644
index 0000000..26439df
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorTest.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.user.domain.interactor
+
+import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class UserLogoutInteractorTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+
+ private val userRepository = kosmos.fakeUserRepository
+ private val testScope = kosmos.testScope
+
+ private val underTest = kosmos.userLogoutInteractor
+
+ @Before
+ fun setUp() {
+ userRepository.setUserInfos(USER_INFOS)
+ runBlocking { userRepository.setSelectedUserInfo(USER_INFOS[1]) }
+ }
+
+ @Test
+ fun logOut_doesNothing_whenAdminDisabledSecondaryLogout() {
+ testScope.runTest {
+ val isLogoutEnabled by collectLastValue(underTest.isLogoutEnabled)
+ val lastLogoutCount = userRepository.logOutSecondaryUserCallCount
+ userRepository.setSecondaryUserLogoutEnabled(false)
+ assertThat(isLogoutEnabled).isFalse()
+ underTest.logOut()
+ assertThat(userRepository.logOutSecondaryUserCallCount).isEqualTo(lastLogoutCount)
+ }
+ }
+
+ @Test
+ fun logOut_logsOut_whenAdminEnabledSecondaryLogout() {
+ testScope.runTest {
+ val isLogoutEnabled by collectLastValue(underTest.isLogoutEnabled)
+ val lastLogoutCount = userRepository.logOutSecondaryUserCallCount
+ userRepository.setSecondaryUserLogoutEnabled(true)
+ assertThat(isLogoutEnabled).isTrue()
+ underTest.logOut()
+ assertThat(userRepository.logOutSecondaryUserCallCount).isEqualTo(lastLogoutCount + 1)
+ }
+ }
+
+ companion object {
+ private val USER_INFOS =
+ listOf(UserInfo(0, "System user", 0), UserInfo(10, "Regular user", 0))
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepositoryTest.kt
index e88dbd2..ad473c0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepositoryTest.kt
@@ -16,152 +16,16 @@
package com.android.systemui.util.settings.repository
-import android.content.pm.UserInfo
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.coroutines.collectValues
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.testKosmos
-import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.settings.data.repository.userAwareSecureSettingsRepository
-import com.android.systemui.util.settings.fakeSettings
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
import org.junit.runner.RunWith
-@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
-class UserAwareSecureSettingsRepositoryTest : SysuiTestCase() {
+class UserAwareSecureSettingsRepositoryTest : UserAwareSettingsRepositoryTestBase() {
- private val kosmos = testKosmos()
- private val testScope = kosmos.testScope
- private val secureSettings = kosmos.fakeSettings
- private val userRepository = kosmos.fakeUserRepository
- private lateinit var underTest: UserAwareSecureSettingsRepository
-
- @Before
- fun setup() {
- underTest = kosmos.userAwareSecureSettingsRepository
-
- userRepository.setUserInfos(USER_INFOS)
-
- secureSettings.putBoolForUser(BOOL_SETTING_NAME, true, USER_1.id)
- secureSettings.putBoolForUser(BOOL_SETTING_NAME, false, USER_2.id)
- secureSettings.putIntForUser(INT_SETTING_NAME, 1337, USER_1.id)
- secureSettings.putIntForUser(INT_SETTING_NAME, 818, USER_2.id)
- }
-
- @Test
- fun boolSetting_emitsInitialValue() {
- testScope.runTest {
- userRepository.setSelectedUserInfo(USER_1)
-
- val enabled by collectLastValue(underTest.boolSetting(BOOL_SETTING_NAME, false))
-
- assertThat(enabled).isTrue()
- }
- }
-
- @Test
- fun boolSetting_whenSettingChanges_emitsNewValue() {
- testScope.runTest {
- userRepository.setSelectedUserInfo(USER_1)
- val enabled by collectValues(underTest.boolSetting(BOOL_SETTING_NAME, false))
- runCurrent()
-
- secureSettings.putBoolForUser(BOOL_SETTING_NAME, false, USER_1.id)
-
- assertThat(enabled).containsExactly(true, false).inOrder()
- }
- }
-
- @Test
- fun boolSetting_whenWhenUserChanges_emitsNewValue() {
- testScope.runTest {
- userRepository.setSelectedUserInfo(USER_1)
- val enabled by collectLastValue(underTest.boolSetting(BOOL_SETTING_NAME, false))
- runCurrent()
-
- userRepository.setSelectedUserInfo(USER_2)
-
- assertThat(enabled).isFalse()
- }
- }
-
- @Test
- fun intSetting_emitsInitialValue() {
- testScope.runTest {
- userRepository.setSelectedUserInfo(USER_1)
-
- val number by collectLastValue(underTest.intSetting(INT_SETTING_NAME, 0))
-
- assertThat(number).isEqualTo(1337)
- }
- }
-
- @Test
- fun intSetting_whenSettingChanges_emitsNewValue() {
- testScope.runTest {
- userRepository.setSelectedUserInfo(USER_1)
- val number by collectValues(underTest.intSetting(INT_SETTING_NAME, 0))
- runCurrent()
-
- secureSettings.putIntForUser(INT_SETTING_NAME, 1338, USER_1.id)
-
- assertThat(number).containsExactly(1337, 1338).inOrder()
- }
- }
-
- @Test
- fun intSetting_whenWhenUserChanges_emitsNewValue() {
- testScope.runTest {
- userRepository.setSelectedUserInfo(USER_1)
- val number by collectLastValue(underTest.intSetting(INT_SETTING_NAME, 0))
- runCurrent()
-
- userRepository.setSelectedUserInfo(USER_2)
-
- assertThat(number).isEqualTo(818)
- }
- }
-
- @Test
- fun getInt_returnsInitialValue() =
- testScope.runTest {
- userRepository.setSelectedUserInfo(USER_1)
-
- assertThat(underTest.getInt(INT_SETTING_NAME, 0)).isEqualTo(1337)
- }
-
- @Test
- fun getInt_whenSettingChanges_returnsNewValue() =
- testScope.runTest {
- userRepository.setSelectedUserInfo(USER_1)
- secureSettings.putIntForUser(INT_SETTING_NAME, 999, USER_1.id)
-
- assertThat(underTest.getInt(INT_SETTING_NAME, 0)).isEqualTo(999)
- }
-
- @Test
- fun getInt_whenUserChanges_returnsThatUserValue() =
- testScope.runTest {
- userRepository.setSelectedUserInfo(USER_2)
-
- assertThat(underTest.getInt(INT_SETTING_NAME, 0)).isEqualTo(818)
- }
-
- private companion object {
- const val BOOL_SETTING_NAME = "BOOL_SETTING_NAME"
- const val INT_SETTING_NAME = "INT_SETTING_NAME"
- val USER_1 = UserInfo(/* id= */ 0, "user1", /* flags= */ 0)
- val USER_2 = UserInfo(/* id= */ 1, "user2", /* flags= */ 0)
- val USER_INFOS = listOf(USER_1, USER_2)
+ override fun getKosmosUserAwareSettingsRepository(): UserAwareSettingsRepository {
+ return kosmos.userAwareSecureSettingsRepository
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepositoryTestBase.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepositoryTestBase.kt
new file mode 100644
index 0000000..09db96f
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepositoryTestBase.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.settings.repository
+
+import android.content.pm.UserInfo
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.android.systemui.util.settings.fakeSettings
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+
+@OptIn(ExperimentalCoroutinesApi::class)
+abstract class UserAwareSettingsRepositoryTestBase : SysuiTestCase() {
+
+ protected val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ protected val secureSettings = kosmos.fakeSettings
+ protected val userRepository = kosmos.fakeUserRepository
+ private lateinit var underTest: UserAwareSettingsRepository
+
+ @Before
+ fun setup() {
+ underTest = getKosmosUserAwareSettingsRepository()
+
+ userRepository.setUserInfos(USER_INFOS)
+
+ secureSettings.putBoolForUser(BOOL_SETTING_NAME, true, USER_1.id)
+ secureSettings.putBoolForUser(BOOL_SETTING_NAME, false, USER_2.id)
+ secureSettings.putIntForUser(INT_SETTING_NAME, 1337, USER_1.id)
+ secureSettings.putIntForUser(INT_SETTING_NAME, 818, USER_2.id)
+ }
+
+ abstract fun getKosmosUserAwareSettingsRepository(): UserAwareSettingsRepository
+
+ @Test
+ fun boolSetting_emitsInitialValue() {
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(USER_1)
+
+ val enabled by collectLastValue(underTest.boolSetting(BOOL_SETTING_NAME, false))
+
+ assertThat(enabled).isTrue()
+ }
+ }
+
+ @Test
+ fun boolSetting_whenSettingChanges_emitsNewValue() {
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(USER_1)
+ val enabled by collectValues(underTest.boolSetting(BOOL_SETTING_NAME, false))
+ runCurrent()
+
+ secureSettings.putBoolForUser(BOOL_SETTING_NAME, false, USER_1.id)
+
+ assertThat(enabled).containsExactly(true, false).inOrder()
+ }
+ }
+
+ @Test
+ fun boolSetting_whenWhenUserChanges_emitsNewValue() {
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(USER_1)
+ val enabled by collectLastValue(underTest.boolSetting(BOOL_SETTING_NAME, false))
+ runCurrent()
+
+ userRepository.setSelectedUserInfo(USER_2)
+
+ assertThat(enabled).isFalse()
+ }
+ }
+
+ @Test
+ fun intSetting_emitsInitialValue() {
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(USER_1)
+
+ val number by collectLastValue(underTest.intSetting(INT_SETTING_NAME, 0))
+
+ assertThat(number).isEqualTo(1337)
+ }
+ }
+
+ @Test
+ fun intSetting_whenSettingChanges_emitsNewValue() {
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(USER_1)
+ val number by collectValues(underTest.intSetting(INT_SETTING_NAME, 0))
+ runCurrent()
+
+ secureSettings.putIntForUser(INT_SETTING_NAME, 1338, USER_1.id)
+
+ assertThat(number).containsExactly(1337, 1338).inOrder()
+ }
+ }
+
+ @Test
+ fun intSetting_whenWhenUserChanges_emitsNewValue() {
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(USER_1)
+ val number by collectLastValue(underTest.intSetting(INT_SETTING_NAME, 0))
+ runCurrent()
+
+ userRepository.setSelectedUserInfo(USER_2)
+
+ assertThat(number).isEqualTo(818)
+ }
+ }
+
+ @Test
+ fun getInt_returnsInitialValue() =
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(USER_1)
+
+ assertThat(underTest.getInt(INT_SETTING_NAME, 0)).isEqualTo(1337)
+ }
+
+ @Test
+ fun getInt_whenSettingChanges_returnsNewValue() =
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(USER_1)
+ secureSettings.putIntForUser(INT_SETTING_NAME, 999, USER_1.id)
+
+ assertThat(underTest.getInt(INT_SETTING_NAME, 0)).isEqualTo(999)
+ }
+
+ @Test
+ fun getInt_whenUserChanges_returnsThatUserValue() =
+ testScope.runTest {
+ userRepository.setSelectedUserInfo(USER_2)
+
+ assertThat(underTest.getInt(INT_SETTING_NAME, 0)).isEqualTo(818)
+ }
+
+ private companion object {
+ const val BOOL_SETTING_NAME = "BOOL_SETTING_NAME"
+ const val INT_SETTING_NAME = "INT_SETTING_NAME"
+ val USER_1 = UserInfo(/* id= */ 0, "user1", /* flags= */ 0)
+ val USER_2 = UserInfo(/* id= */ 1, "user2", /* flags= */ 0)
+ val USER_INFOS = listOf(USER_1, USER_2)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSystemSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSystemSettingsRepositoryTest.kt
new file mode 100644
index 0000000..586da8e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSystemSettingsRepositoryTest.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.settings.repository
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.util.settings.data.repository.userAwareSystemSettingsRepository
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class UserAwareSystemSettingsRepositoryTest : UserAwareSettingsRepositoryTestBase() {
+
+ override fun getKosmosUserAwareSettingsRepository(): UserAwareSettingsRepository {
+ return kosmos.userAwareSystemSettingsRepository
+ }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java
index 403c7c5..43185fd 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java
@@ -36,6 +36,9 @@
public interface DarkIconDispatcher {
int VERSION = 2;
+ /** Called when work should stop and resources should be cleaned up. */
+ default void stop() {}
+
/**
* Sets the dark area so {@link #applyDark} only affects the icons in the specified area.
*
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index bb3da3a..ef62996 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -49,7 +49,7 @@
<string name="disable_carrier_button_text" msgid="7153361131709275746">"eSIM ଅକ୍ଷମ କରନ୍ତୁ"</string>
<string name="error_disable_esim_title" msgid="3802652622784813119">"eSIMକୁ ଅକ୍ଷମ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="error_disable_esim_msg" msgid="2441188596467999327">"ଗୋଟିଏ ତ୍ରୁଟି କାରଣରୁ eSIMକୁ ଅକ୍ଷମ କରାଯାଇପାରିବ ନାହିଁ।"</string>
- <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"ଏଣ୍ଟର୍"</string>
+ <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"ଏଣ୍ଟର"</string>
<string name="kg_wrong_pattern" msgid="5907301342430102842">"ଭୁଲ ପାଟର୍ନ"</string>
<string name="kg_wrong_pattern_try_again" msgid="3603524940234151881">"ଭୁଲ ପାଟର୍ନ। ପୁଣିଚେଷ୍ଟା କର।"</string>
<string name="kg_wrong_password" msgid="4143127991071670512">"ଭୁଲ ପାସ୍ୱର୍ଡ"</string>
diff --git a/packages/SystemUI/res/drawable/ic_qs_notes.xml b/packages/SystemUI/res/drawable/ic_qs_notes.xml
new file mode 100644
index 0000000..6c1d2e4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_notes.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the Lice/packages/SystemUI/res/drawable/ic_qs_notes.xmlnse.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?attr/colorControlNormal">
+ <path android:fillColor="@android:color/white" android:pathData="M499,673L834,338Q834,338 834,338Q834,338 834,338L782,286Q782,286 782,286Q782,286 782,286L447,621L499,673ZM238,760Q138,755 89,718Q40,681 40,611Q40,546 93.5,505.5Q147,465 242,457Q281,454 300.5,444.5Q320,435 320,418Q320,392 290.5,379Q261,366 193,360L200,280Q303,288 351.5,321.5Q400,355 400,418Q400,471 361.5,501Q323,531 248,537Q184,542 152,560.5Q120,579 120,611Q120,646 148,661.5Q176,677 242,680L238,760ZM518,767L353,602L735,220Q755,200 782.5,200Q810,200 830,220L900,290Q920,310 920,337.5Q920,365 900,385L518,767ZM359,800Q342,804 329,791Q316,778 320,761L353,602L518,767L359,800Z"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index 65005f8..572f063 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -32,6 +32,34 @@
android:id="@+id/min_edge_guideline"
app:layout_constraintGuide_begin="@dimen/overlay_action_container_minimum_edge_spacing"
android:orientation="vertical"/>
+ <!-- This toast-like indication layout was forked from text_toast.xml and will have the same
+ appearance as system toast. -->
+ <FrameLayout
+ android:id="@+id/indication_container"
+ android:visibility="gone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:maxWidth="@*android:dimen/toast_width"
+ android:background="@android:drawable/toast_frame"
+ android:elevation="@*android:dimen/toast_elevation"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
+ android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
+ android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent">
+ <TextView
+ android:id="@+id/indication_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:maxLines="2"
+ android:paddingTop="12dp"
+ android:paddingBottom="12dp"
+ android:textAppearance="@*android:style/TextAppearance.Toast"/>
+ </FrameLayout>
<!-- Negative horizontal margin because this container background must render beyond the thing
it's constrained by (the actions themselves). -->
<FrameLayout
@@ -47,7 +75,7 @@
app:layout_constraintStart_toStartOf="@id/min_edge_guideline"
app:layout_constraintTop_toTopOf="@id/actions_container"
app:layout_constraintEnd_toEndOf="@id/actions_container"
- app:layout_constraintBottom_toBottomOf="parent"/>
+ app:layout_constraintBottom_toTopOf="@id/indication_container"/>
<HorizontalScrollView
android:id="@+id/actions_container"
android:layout_width="0dp"
@@ -144,7 +172,7 @@
android:visibility="gone"
android:elevation="7dp"
android:padding="8dp"
- app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/indication_container"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
diff --git a/packages/SystemUI/res/layout/screen_record_dialog.xml b/packages/SystemUI/res/layout/screen_record_dialog.xml
deleted file mode 100644
index dc560bf..0000000
--- a/packages/SystemUI/res/layout/screen_record_dialog.xml
+++ /dev/null
@@ -1,164 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <!-- Scrollview is necessary to fit everything in landscape layout -->
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="@dimen/dialog_side_padding"
- android:paddingEnd="@dimen/dialog_side_padding"
- android:paddingTop="@dimen/dialog_top_padding"
- android:paddingBottom="@dimen/dialog_bottom_padding"
- android:orientation="vertical">
-
- <!-- Header -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:gravity="center">
- <ImageView
- android:layout_width="@dimen/screenrecord_logo_size"
- android:layout_height="@dimen/screenrecord_logo_size"
- android:src="@drawable/ic_screenrecord"
- android:tint="@color/screenrecord_icon_color"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="@style/TextAppearance.Dialog.Title"
- android:fontFamily="@*android:string/config_headlineFontFamily"
- android:text="@string/screenrecord_permission_dialog_title"
- android:layout_marginTop="22dp"
- android:layout_marginBottom="15dp"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/screenrecord_permission_dialog_warning_entire_screen"
- android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
- android:gravity="center"
- android:layout_marginBottom="20dp"/>
-
- <!-- Options -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <ImageView
- android:layout_width="@dimen/screenrecord_option_icon_size"
- android:layout_height="@dimen/screenrecord_option_icon_size"
- android:src="@drawable/ic_mic_26dp"
- android:tint="?android:attr/textColorSecondary"
- android:layout_gravity="center"
- android:layout_weight="0"
- android:layout_marginEnd="@dimen/screenrecord_option_padding"/>
- <Spinner
- android:id="@+id/screen_recording_options"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:minHeight="48dp"
- android:layout_weight="1"
- android:popupBackground="@drawable/screenrecord_spinner_background"
- android:textColor="?androidprv:attr/materialColorOnSurface"
- android:dropDownWidth="274dp"
- android:prompt="@string/screenrecord_audio_label"/>
- <Switch
- android:layout_width="wrap_content"
- android:minWidth="48dp"
- android:layout_height="48dp"
- android:layout_weight="0"
- android:layout_gravity="end"
- android:contentDescription="@string/screenrecord_audio_label"
- android:id="@+id/screenrecord_audio_switch"
- style="@style/ScreenRecord.Switch"/>
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="@dimen/screenrecord_option_padding">
- <ImageView
- android:layout_width="@dimen/screenrecord_option_icon_size"
- android:layout_height="@dimen/screenrecord_option_icon_size"
- android:layout_weight="0"
- android:src="@drawable/ic_touch"
- android:tint="?android:attr/textColorSecondary"
- android:layout_gravity="center"
- android:layout_marginEnd="@dimen/screenrecord_option_padding"/>
- <TextView
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:minHeight="48dp"
- android:layout_weight="1"
- android:layout_gravity="fill_vertical"
- android:gravity="center_vertical"
- android:text="@string/screenrecord_taps_label"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:fontFamily="@*android:string/config_headlineFontFamily"
- android:textColor="?androidprv:attr/materialColorOnSurface"
- android:importantForAccessibility="no"/>
- <Switch
- android:layout_width="wrap_content"
- android:minWidth="48dp"
- android:layout_height="48dp"
- android:layout_weight="0"
- android:id="@+id/screenrecord_taps_switch"
- android:contentDescription="@string/screenrecord_taps_label"
- style="@style/ScreenRecord.Switch"/>
- </LinearLayout>
- </LinearLayout>
-
- <!-- Buttons -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="36dp">
- <TextView
- android:id="@+id/button_cancel"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:layout_gravity="start"
- android:text="@string/cancel"
- style="@style/Widget.Dialog.Button.BorderButton" />
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"/>
-
- <TextView
- android:id="@+id/button_start"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:layout_gravity="end"
- android:text="@string/screenrecord_continue"
- style="@style/Widget.Dialog.Button" />
- </LinearLayout>
- </LinearLayout>
- </ScrollView>
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_ringer_drawer.xml b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
index 9b3af52..7c266e6 100644
--- a/packages/SystemUI/res/layout/volume_ringer_drawer.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
@@ -65,7 +65,7 @@
android:background="@drawable/volume_drawer_selection_bg"
android:contentDescription="@string/volume_ringer_change"
android:gravity="center"
- android:padding="10dp"
+ android:padding="@dimen/volume_dialog_ringer_horizontal_padding"
android:src="@drawable/ic_volume_media"
android:tint="?androidprv:attr/materialColorOnPrimary" />
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index c091cbf..2f2981b 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Neem jou skerm op?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Neem een app op"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Neem hele skerm op"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Neem hele skerm op: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Wanneer jy jou hele skerm opneem, word enigiets wat op jou skerm wys, opgeneem. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Wanneer jy ’n app opneem, word enigiets wat in daardie app gewys of gespeel word, opgeneem. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Neem skerm op"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Jy neem tans <xliff:g id="APP_NAME">%1$s</xliff:g> op"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop opname"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deel tans skerm"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Inhoud word gedeel"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Hou op om skerm te deel?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Hou op deel?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Jy deel tans jou hele skerm met <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Jy deel tans jou hele skerm met ’n app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Jy deel tans <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Jy deel tans ’n app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Jy deel tans met ’n app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Hou op deel"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Skerm word tans uitgesaai"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Hou op uitsaai?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Sluitskermlegstukke"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Enigiemand kan legstukke op jou sluitskerm sien, selfs al is jou tablet gesluit."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ontkies legstuk"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Verminder hoogte"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Vermeerder hoogte"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Sluitskermlegstukke"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Om ’n app met ’n legstuk oop te maak, sal jy moet verifieer dat dit jy is. Hou ook in gedagte dat enigeen dit kan bekyk, selfs wanneer jou tablet gesluit is. Sommige legstukke is moontlik nie vir jou sluitskerm bedoel nie en dit kan onveilig wees om dit hier by te voeg."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Het dit"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Vee alles uit"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Bestuur"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Geskiedenis"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Kennisgewinginstellings"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Kennisgewinggeskiedenis"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nuut"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Stil"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Kennisgewings"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Geen kennisgewings nie"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Geen nuwe kennisgewings nie"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Kennisgewingdemping is aan"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Jou toestelvolume en -waarskuwings word outomaties vir tot 2 minute lank verminder wanneer jy te veel kennisgewings op een slag kry."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Skakel af"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ontsluit om ouer kennisgewings te sien"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Vasgestel"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Kopnasporing"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tik om luiermodus te verander"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"demp"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ontdemp"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibreer"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Huidige app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toeganklikheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortpadsleutels"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pasmaak kortpadsleutels"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Soekkortpaaie"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen soekresultate nie"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Vou ikoon in"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Pasmaak"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klaar"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Vou ikoon uit"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"of"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sleephandvatsel"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Verskaf deur apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Vertoon"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Onbekend"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Stel teëls terug"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Stel teëls terug na hul oorspronklike volgorde en groottes?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Stel alle teëls terug?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle Kitsinstellingsteëls sal na die toestel se oorspronklike instellings teruggestel word"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index af2971b..129c908 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ማያ ገፅዎን ይቀዳሉ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"አንድ መተግበሪያ ቅዳ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"መላው ማያ ገፅን ቅረጽ"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ሙሉ ማያ ገፅን ቅዳ፦ %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"መላው ማያ ገፅዎን በሚቀዱበት ጊዜ፣ በማያ ገፅዎ ላይ የሚታየው ማንኛውም ነገር ይቀዳል። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"መተግበሪያን ሲቀዱ በዚያ መተግበሪያ ውስጥ የሚታይ ወይም የሚጫወት ማንኛውም ነገር ይቀዳል። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ማያ ገፅን ቅረጽ"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"በአሁኑ ጊዜ <xliff:g id="APP_NAME">%1$s</xliff:g> በመቅዳት ላይ ነዎት"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"መቅረጽ አቁም"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ማያ ገፅን በማጋራት ላይ"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"ይዘት በማጋራት ላይ"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ማያ ገፅን ማጋራት ይቁም?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"ማጋራት ይቁም?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"በአሁኑ ጊዜ ሙሉ ማያ ገፅዎን ከ<xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ጋር በማጋራት ላይ ነዎት"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"በአሁኑ ጊዜ መሉ ማያ ገፅዎን ከመተግበሪያ ጋር በማጋራት ላይ ነዎት"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"በአሁኑ ጊዜ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> በማጋራት ላይ ነዎት"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"በአሁኑ ጊዜ መተግበሪያ በማጋራት ላይ ነዎት"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"በአሁኑ ጊዜ በመተግበሪያ በማጋራት ላይ ነዎት"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ማጋራት አቁም"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ማያ ገፅን cast በማድረግ ላይ"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"cast ማድረግ ይቁም?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"የማያ ገፅ ቁልፍ ምግብሮች"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"የእርስዎ ጡባዊ ቁልፍ ተቆልፎ ቢሆን እንኳን ማንኛውም ሰው በማያ ገፅ ቁልፍዎ ላይ ምግብሮችን ማየት ይችላል።"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ምግብር አትምረጥ"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ቁመት ቀንስ"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ቁመት ጨምር"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"የማያ ገፅ ቁልፍ ምግብሮች"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ምግብር በመጠቀም መተግበሪያ ለመክፈት እርስዎ መሆንዎን ማረጋገጥ አለብዎት። እንዲሁም የእርስዎ ጡባዊ በተቆለፈበት ጊዜ እንኳን ማንኛውም ሰው እነሱን ማየት እንደሚችል ከግምት ውስጥ ያስገቡ። አንዳንድ ምግብሮች ለማያ ገፅ ቁልፍዎ የታሰቡ ላይሆኑ ይችላሉ እና እዚህ ለማከል አስተማማኝ ላይሆኑ ይችላሉ።"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ገባኝ"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"ሁሉንም አጽዳ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ያቀናብሩ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ታሪክ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"የማሳወቂያ ቅንብሮች"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"የማሳወቂያ ታሪክ"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"አዲስ"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ጸጥ ያለ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ማሳወቂያዎች"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ምንም ማሳወቂያ የለም"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ምንም አዲስ ማሳወቂያዎች የሉም"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"የማሳወቂያ ረጋ ማለት በርቷል"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"በአንድ ጊዜ ብዙ ማሳወቂያዎችን ሲያገኙ የመሣሪያዎ ድምፅ እና ማንቂያዎች እስከ 2 ደቂቃዎች ድረስ በራስ-ሰር ይቀንሳሉ።"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"አጥፋ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"የቆዩ ማሳወቂያዎችን ለማየት ይክፈቱ"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ቋሚ"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"የጭንቅላት ክትትል"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"የደዋይ ሁነታን ለመቀየር መታ ያድርጉ"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ድምጸ-ከል አድርግ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ድምጸ-ከልን አንሳ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ንዘር"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"የአሁን መተግበሪያ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ተደራሽነት"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"የቁልፍ ሰሌዳ አቋራጮች"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"የቁልፍ ሰሌዳ አቋራጮችን ያብጁ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"የፍለጋ አቋራጮች"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ምንም የፍለጋ ውጤቶች የሉም"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"መሰብሰቢያ አዶ"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"አብጅ"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ተከናውኗል"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"መዘርጊያ አዶ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ወይም"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"መያዣ ይጎትቱ"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"በመተግበሪያዎች የቀረበ"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ማሳያ"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ያልታወቀ"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"ሰቆችን ዳግም ያስጀምሩ"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"ሰቆችን ወደ የመጀመሪያው ቅደም ተከተል እና መጠኖቻቸው ይመለሱ?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ሁሉም ሰቆች ዳግም ይጀምሩ?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ሁሉም የፈጣን ቅንብሮች ሰቆች ወደ የመሣሪያው የመጀመሪያ ቅንብሮች ዳግም ይጀምራሉ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 4ebac5a..48fc913 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"هل تريد تسجيل محتوى الشاشة؟"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"تسجيل محتوى تطبيق واحد"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"تسجيل محتوى الشاشة بالكامل"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"تسجيل محتوى الشاشة بالكامل: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"أثناء تسجيل محتوى الشاشة بالكامل، يتم تسجيل كل المحتوى المعروض على شاشتك. لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"أثناء تسجيل محتوى تطبيق، يتم تسجيل أي محتوى يتم عرضه أو تشغيله في ذلك التطبيق. لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"تسجيل محتوى الشاشة"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"يتم حاليًا تسجيل محتوى \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"إيقاف التسجيل"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"جارِ مشاركة محتوى الشاشة"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"مشاركة المحتوى"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"هل تريد إيقاف مشاركة الشاشة؟"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"هل تريد إيقاف المشاركة؟"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"تتم حاليًا مشاركة محتوى الشاشة بأكمله مع \"<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>\""</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"تتم حاليًا مشاركة محتوى الشاشة بأكمله مع تطبيق"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"تتم حاليًا مشاركة محتوى \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\""</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"تتم حاليًا مشاركة محتوى تطبيق"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"تتم حاليًا مشاركة المحتوى مع تطبيق"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"إيقاف المشاركة"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"جارٍ بث محتوى الشاشة"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"هل تريد إيقاف البث؟"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"التطبيقات المصغّرة المصمَّمة لشاشة القفل"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"يمكن للجميع رؤية التطبيقات المصغّرة على شاشة القفل، حتى في حال قفل الجهاز اللوحي."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"إلغاء اختيار التطبيق المصغّر"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"تقليل الارتفاع"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"زيادة الارتفاع"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"التطبيقات المصغّرة المصمَّمة لشاشة القفل"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"لفتح تطبيق باستخدام تطبيق مصغَّر، عليك إثبات هويتك. يُرجى ملاحظة أنّ أي شخص يمكنه الاطّلاع محتوى التطبيقات المصغَّرة، حتى وإن كان جهازك اللوحي مُقفلاً. بعض التطبيقات المصغّرة قد لا تكون مُصمَّمة لإضافتها إلى شاشة القفل، وقد يكون هذا الإجراء غير آمن."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"حسنًا"</string>
@@ -583,12 +577,10 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"محو الكل"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"إدارة"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"السجلّ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"إعدادات الإشعارات"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"سجلّ الإشعارات"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"الإشعارات الجديدة"</string>
- <string name="notification_section_header_gentle" msgid="6804099527336337197">"صامتة"</string>
+ <string name="notification_section_header_gentle" msgid="6804099527336337197">"إشعارات صامتة"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"الإشعارات"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"المحادثات"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"محو جميع الإشعارات الصامتة"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"البدء الآن"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ما مِن إشعارات"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ما مِن إشعارات جديدة"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"ميزة \"تخفيض الإشعارات الصوتية والاهتزاز\" مُفعَّلة"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"يتم تلقائيًا خفض مستوى صوت جهازك والتنبيهات لمدة تصل إلى دقيقتين عند تلقّي إشعارات كثيرة في آنٍ واحد."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"إيقاف"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"افتَح قفل الشاشة لعرض الإشعارات الأقدم."</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"تفعيل"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"تتبُّع حركة الرأس"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"انقر لتغيير وضع الرنين."</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"كتم الصوت"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"إعادة الصوت"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"اهتزاز"</string>
@@ -765,7 +760,7 @@
<string name="inline_done_button" msgid="6043094985588909584">"تمّ"</string>
<string name="inline_ok_button" msgid="603075490581280343">"تطبيق"</string>
<string name="inline_turn_off_notifications" msgid="8543989584403106071">"إيقاف الإشعارات"</string>
- <string name="notification_silence_title" msgid="8608090968400832335">"صامتة"</string>
+ <string name="notification_silence_title" msgid="8608090968400832335">"إشعارات صامتة"</string>
<string name="notification_alert_title" msgid="3656229781017543655">"تلقائية"</string>
<string name="notification_automatic_title" msgid="3745465364578762652">"تلقائي"</string>
<string name="notification_channel_summary_low" msgid="4860617986908931158">"بدون صوت أو اهتزاز"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"التطبيق الحالي"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"تسهيل الاستخدام"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"اختصارات لوحة المفاتيح"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"اختصارات طلبات البحث"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"تخصيص اختصارات لوحة المفاتيح"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"البحث في الاختصارات"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ما مِن نتائج بحث"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"رمز التصغير"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"تخصيص"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"تم"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"رمز التوسيع"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"أو"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"مقبض السحب"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"مقدَّمة من التطبيقات"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"العرض"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"غير معروفة"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"إعادة ضبط المربّعات"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"هل تريد إعادة ضبط المربّعات إلى ترتيبها وحجمها الأصليَّين؟"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"هل تريد إعادة ضبط كل المربّعات؟"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ستتم إعادة ضبط جميع مربّعات \"الإعدادات السريعة\" إلى الإعدادات الأصلية للجهاز"</string>
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 85517f3..96446c5 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"আপোনাৰ স্ক্ৰীনখন ৰেকৰ্ড কৰিবনে?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"এটা এপ্ ৰেকৰ্ড কৰক"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"গোটেই স্ক্ৰীনখন ৰেকৰ্ড কৰক"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"গোটেই স্ক্ৰীনখন ৰেকৰ্ড কৰক: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"আপুনি গোটেই স্ক্ৰীনখন ৰেকৰ্ডিং কৰিলে, আপোনাৰ স্ক্ৰীনখনত দেখুওৱা যিকোনো বস্তু ৰেকৰ্ড কৰা হয়। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"আপুনি কোনো এপ্ ৰেকৰ্ড কৰিলে, সেই এপত দেখুওৱা বা প্লে’ কৰা যিকোনো বস্তু ৰেকৰ্ড কৰা হয়। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"স্ক্ৰীনখন ৰেকৰ্ড কৰক"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"বৰ্তমান আপুনি <xliff:g id="APP_NAME">%1$s</xliff:g> ৰেকৰ্ড কৰি আছে"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ৰেকৰ্ডিং বন্ধ কৰক"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"স্ক্ৰীন শ্বেয়াৰ কৰি থকা হৈছে"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"সমল শ্বেয়াৰ কৰি থকা হৈছে"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"স্ক্ৰীন শ্বেয়াৰ কৰা বন্ধ কৰিবনে?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"শ্বেয়াৰ কৰাটো বন্ধ কৰিবনে?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"বৰ্তমান আপুনি আপোনাৰ গোটেই স্ক্ৰীনখন <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>ৰ সৈতে শ্বেয়াৰ কৰি আছে"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"বৰ্তমান আপুনি আপোনাৰ গোটেই স্ক্ৰীনখন এটা এপৰ সৈতে শ্বেয়াৰ কৰি আছে"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"বৰ্তমান আপুনি <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> শ্বেয়াৰ কৰি আছে"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"বৰ্তমান আপুনি এটা এপ্ শ্বেয়াৰ কৰি আছে"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"বৰ্তমান আপুনি এটা এপৰ সৈতে শ্বেয়াৰ কৰি আছে"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"শ্বেয়াৰ কৰা বন্ধ কৰক"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"স্ক্ৰীন কাষ্ট কৰি থকা হৈছে"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"কাষ্ট কৰা বন্ধ কৰিবনে?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"লক স্ক্ৰীনৰ ৱিজেট"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"আপোনাৰ টেবলেটটো লক কৰি ৰাখিলেও যিকোনো লোকে আপোনাৰ লক স্ক্ৰীনত ৱিজেট চাব পাৰে।"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ৱিজেট বাছনিৰ পৰা আঁতৰাওক"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"উচ্চতা হ্ৰাস কৰক"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"উচ্চতা বৃদ্ধি কৰক"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"লক স্ক্ৰীন ৱিজেট"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"এটা ৱিজেট ব্যৱহাৰ কৰি কোনো এপ্ খুলিবলৈ, এয়া আপুনিয়েই বুলি সত্যাপন পৰীক্ষা কৰিব লাগিব। লগতে, মনত ৰাখিব যে যিকোনো লোকেই সেইবোৰ চাব পাৰে, আনকি আপোনাৰ টেবলেটটো লক হৈ থাকিলেও। কিছুমান ৱিজেট হয়তো আপোনাৰ লক স্ক্ৰীনৰ বাবে কৰা হোৱা নাই আৰু ইয়াত যোগ কৰাটো অসুৰক্ষিত হ’ব পাৰে।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুজি পালোঁ"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"এতিয়াই আৰম্ভ কৰক"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"কোনো জাননী নাই"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"কোনো নতুন জাননী নাই"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"জাননী কুলডাউন কৰাটো অন আছে"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"আপুনি একেলগে বহুতো জাননী পালে আপোনাৰ ডিভাইচটোৰ ভলিউম আৰু সতৰ্কবাৰ্তা স্বয়ংক্ৰিয়ভাৱে ২ মিনিটলৈকে কমোৱা হয়।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"অফ কৰক"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুৰণি জাননী চবলৈ আনলক কৰক"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"নিৰ্ধাৰিত"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"হে’ড ট্ৰেকিং"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ৰিংগাৰ ম’ড সলনি কৰিবলৈ টিপক"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট কৰক"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট কৰক"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"কম্পন কৰক"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"বৰ্তমানৰ এপ্"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"সাধ্য সুবিধা"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীব’ৰ্ডৰ শ্বৰ্টকাট"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীব’ৰ্ডৰ শ্বৰ্টকাট কাষ্টমাইজ কৰক"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সন্ধানৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"সন্ধানৰ কোনো ফলাফল নাই"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"সংকোচন কৰাৰ চিহ্ন"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"কাষ্টমাইজ কৰক"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"হ’ল"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"বিস্তাৰ কৰাৰ চিহ্ন"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ড্ৰেগ হেণ্ডেল"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"এপে প্ৰদান কৰা"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ডিছপ্লে’"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"অজ্ঞাত"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"টাইল ৰিছেট কৰক"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"টাইলসমূহ সেইসমূহৰ মূল ক্ৰম আৰু আকাৰলৈ ৰিছেট কৰিবনে?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"আটাইবোৰ টাইল ৰিছেট কৰিবনে?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"আটাইবোৰ ক্ষিপ্ৰ ছেটিঙৰ টাইল ডিভাইচৰ মূল ছেটিংছলৈ ৰিছেট হ’ব"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index f08724a..2932b19 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekran qeydə alınsın?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bir tətbiqi qeydə alın"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Bütün ekranı qeydə alın"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Bütün ekranı qeydə alın: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Bütün ekranı qeydə alarkən ekranda göstərilən bütün kontent qeydə alınır. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Tətbiq qeydə aldıqda həmin tətbiqdə göstərilən və ya işə salınan bütün kontent qeydə alınır. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranı qeydə alın"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Hazırda <xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqini çəkirsiniz"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Qeydəalmanı dayandırın"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran paylaşılır"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Kontent paylaşmaq"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ekran paylaşımı dayandırılsın?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Paylaşım dayandırılsın?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Hazırda bütün ekranı <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ilə paylaşırsınız"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Hazırda bütün ekranı tətbiq ilə paylaşırsınız"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Hazırda <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> paylaşırsınız"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Hazırda tətbiq paylaşırsınız"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Hazırda tətbiqlə paylaşırsınız"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Paylaşımı dayandırın"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Ekran yayımlanır"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Yayım dayandırılsın?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Kilid ekranı vidcetləri"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Planşet kilidli olsa belə, hər kəs kilid ekranınızdakı vidcetlərə baxa bilər."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"vidcet seçimini silin"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Hündürlüyü azaldın"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Hündürlüyü artırın"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Kilid ekranı vidcetləri"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Vidcetdən istifadə edərək tətbiqi açmaq üçün kimliyi doğrulamalısınız. Planşet kilidli olsa da, hər kəs vidcetlərə baxa bilər. Bəzi vidcetlər kilid ekranı üçün nəzərdə tutulmayıb və bura əlavə etmək təhlükəli ola bilər."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hamısını silin"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"İdarə edin"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Tarixçə"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Bildiriş ayarları"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Bildiriş tarixçəsi"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Yeni"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Səssiz"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirişlər"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Heç bir bildiriş yoxdur"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildiriş yoxdur"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Bildiriş gözləmə müddəti yanılıdır"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Eyni anda çox bildiriş aldıqda cihazın səs və xəbərdarlıqları avtomatik 2 dəqiqəyə qədər azalır."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiv edin"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Köhnə bildirişləri görmək üçün kilidi açın"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Sabit"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Baş izləməsi"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Zəng rejimini dəyişmək üçün toxunun"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"susdurun"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"səssiz rejimdən çıxarın"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrasiya"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Cari tətbiq"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Xüsusi imkanlar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatura qısayolları"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatura qısayollarını fərdiləşdirin"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Axtarış qısayolları"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Axtarış nəticəsi yoxdur"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"İkonanı yığcamlaşdırın"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Fərdiləşdirin"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hazırdır"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"İkonanı genişləndirin"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"və ya"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dəstəyi çəkin"</string>
@@ -1435,14 +1427,14 @@
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Klaviatura və taçpeddən istifadə edərək hərəkət edin"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Taçped jestləri, klaviatura qısayolları və s. haqqında öyrənin"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Geri qayıdın"</string>
- <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Əsas səhifəyə qayıdın"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Əsas səhifəyə keçin"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Son tətbiqlərə baxın"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hazırdır"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Geri qayıdın"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Taçpeddə üç barmaqla sola və ya sağa sürüşdürün"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Əla!"</string>
<string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Geri getmə jestini tamamladınız."</string>
- <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Ana ekrana qayıdın"</string>
+ <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Əsas səhifəyə keçin"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Taçpeddə üç barmaqla yuxarı sürüşdürün"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Əla!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Əsas səhifəyə keçid jestini tamamladınız"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Tətbiqlər tərəfindən təmin edilir"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Displey"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Naməlum"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Mozaikləri sıfırlayın"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Mozaiklər orijinal sıra və ölçülərinə sıfırlansın?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Bütün mozaiklər sıfırlansın?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Bütün Sürətli Ayarlar mozaiki cihazın orijinal ayarlarına sıfırlanacaq"</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index f509691..7b571b9 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Želite da snimite ekran?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimi jednu aplikaciju"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimi ceo ekran"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snimite ceo ekran: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate ceo ekran, snima se sve što je na njemu. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, audio i video sadržaj."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snima se sav sadržaj koji se prikazuje ili pušta u njoj. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, audio i video sadržaj."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimi ekran"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Trenutno snimate: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zaustavi snimanje"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran se deli"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Deljenje sadržaja"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Želite da zaustavite deljenje ekrana?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Želite da zaustavite deljenje?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Trenutno delite ceo ekran sa: <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Trenutno delite ceo ekran sa aplikacijom"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Trenutno delite: <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Trenutno delite aplikaciju"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Trenutno delite sa aplikacijom"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Zaustavi deljenje"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Prebacuje se ekran"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Želite da zaustavite prebacivanje?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Vidžeti za zaključani ekran"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Svi mogu da vide vidžete na zaključanom ekranu, čak i kada je tablet zaključan."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"poništi izbor vidžeta"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Smanji visinu"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Povećaj visinu"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Vidžeti za zaključani ekran"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju koja koristi vidžet, treba da potvrdite da ste to vi. Imajte u vidu da svako može da ga vidi, čak i kada je tablet zaključan. Neki vidžeti možda nisu namenjeni za zaključani ekran i možda nije bezbedno da ih tamo dodate."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Važi"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obaveštenja"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obaveštenja"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Utišavanje obaveštenja je uključeno"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Zvuk i broj upozorenja na uređaju se automatski smanjuju na 2 minuta kada dobijete previše obaveštenja."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte za starija obaveštenja"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksno"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Praćenje glave"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promenili režim zvona"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibracija"</string>
@@ -814,7 +811,7 @@
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"Razmak"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
- <string name="keyboard_key_backspace" msgid="4095278312039628074">"Taster za brisanje unazad"</string>
+ <string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Taster za reprodukciju/pauziranje"</string>
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"Taster za zaustavljanje"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Taster Sledeća"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuelna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tasterske prečice"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečice pretrage"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite tasterske prečice"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pretražite prečice"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretrage"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za skupljanje"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za prevlačenje"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Obezbeđuju aplikacije"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekran"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Resetujte pločice"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Želite da resetujete pločice na prvobitni redosled i veličine?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Želite da resetujete sve pločice?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Sve pločice Brzih podešavanja će se resetovati na prvobitna podešavanja uređaja"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index bc0e2d1..2d2a010 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Запісаць экран?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Запісаць адну праграму"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Запісаць змесціва ўсяго экрана"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Запісваць экран цалкам: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Пры запісе ўсяго экрана запісваецца ўсё, што паказваецца на экране. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Пры запісе праграмы запісваецца ўсё, што паказваецца або прайграецца ў гэтай праграме. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Запісаць экран"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Зараз вы запісваеце змесціва праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Спыніць запіс"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экран абагульваецца"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Абагульваецца змесціва"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Спыніць абагульванне экрана?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Спыніць абагульванне?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Зараз вы абагульваеце змесціва ўсяго экрана з праграмай \"<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>\""</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Зараз вы абагульваеце змесціва ўсяго экрана з праграмай"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Зараз вы абагульваеце змесціва праграмы \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\""</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Зараз вы абагульваеце змесціва праграмы"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Зараз вы абагульваеце змесціва з праграмай"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Спыніць абагульванне"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Экран трансліруецца"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Спыніць трансляцыю?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Віджэты на экране блакіроўкі"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Віджэты на экране блакіроўкі будуць бачныя, нават калі планшэт заблакіраваны."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"скасаваць выбар віджэта"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Паменшыць вышыню"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Павялічыць вышыню"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Віджэты на экране блакіроўкі"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Каб адкрыць праграму з дапамогай віджэта, вам неабходна будзе пацвердзіць сваю асобу. Таксама памятайце, што такія віджэты могуць пабачыць іншыя людзі, нават калі экран планшэта заблакіраваны. Некаторыя віджэты могуць не падыходзіць для выкарыстання на экране блакіроўкі, і дадаваць іх сюды можа быць небяспечна."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Зразумела"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Ачысціць усё"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Кіраваць"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Гісторыя"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Налады апавяшчэнняў"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Гісторыя апавяшчэнняў"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Новае"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Без гуку"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Апавяшчэнні"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Пачаць зараз"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Апавяшчэнняў няма"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Няма новых апавяшчэнняў"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Зніжэнне гучнасці апавяшчэнняў уключана"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Калі адначасова прыходзіць шмат апавяшчэнняў, гук прылады і абвестак зніжаецца на час да 2 хвілін."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Выключыць"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблакіруйце, каб убачыць усе апавяшчэнні"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Замацавана"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Адсочваць рух галавы"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Націсніце, каб змяніць рэжым званка"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"выключыць гук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"уключыць гук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вібрыраваць"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Бягучая праграма"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Спецыяльныя магчымасці"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Спалучэнні клавіш"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Наладзіць спалучэнні клавіш"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пошук спалучэнняў клавіш"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма вынікаў пошуку"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Згарнуць\""</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Наладзіць"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Гатова"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Разгарнуць\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перацягвання"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Забяспечваюцца праграмамі"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Экран"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Невядома"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Скінуць пліткі"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Скінуць пліткі да зыходнага парадку і памеру?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Скінуць усе пліткі?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Усе пліткі хуткіх налад будуць скінуты да першапачатковых налад прылады"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 2ee1f5f..c2d5b9e 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Да се записва ли екранът?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записване на едно приложение"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записване на целия екран"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Записване на целия екран: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Когато записвате целия си екран, се записва всичко, което се показва на него. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Когато записвате приложение, се записва всичко, което се показва или възпроизвежда в него. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Записване на екрана"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"В момента записвате <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Спиране на записа"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Екранът се споделя"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Съдържанието се споделя"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Да се спре ли споделянето на екрана?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Да се спре ли споделянето?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"В момента споделяте целия си екран с(ъс) <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"В момента споделяте целия си екран с приложение"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"В момента споделяте <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"В момента споделяте приложение"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"В момента споделяте с приложение"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Спиране на споделянето"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Екранът се предава"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Да се спре ли предаването?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Приспособления за заключения екран"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Всеки ще вижда приспособленията на закл. екран дори ако таблетът ви е заключен."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"премахване на избора от приспособлението"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Намаляване на височината"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Увеличаване на височината"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Приспособления за заключения екран"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите дадено приложение посредством приспособление, ще трябва да потвърдите, че това сте вие. Също така имайте предвид, че всеки ще вижда приспособленията дори когато таблетът ви е заключен. Възможно е някои от тях да не са предназначени за заключения екран и добавянето им на него може да е опасно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Разбрах"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Изчистване на всички"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Управление"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"История"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Настройки за известията"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"История на известията"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Нови"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Беззвучни"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Известия"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Стартиране сега"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Няма известия"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Няма нови известия"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Изчакването за известията е включено"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Силата на звука и сигналите на у-вото се намаляват за до 2 минути, когато получавате твърде много известия наведнъж."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Изключване"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Отключете за достъп до по-стари известия"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Фиксирано"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Прослед. на движенията на главата"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Докоснете, за да промените режима на звънене"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"спиране"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"пускане"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибриране"</string>
@@ -867,7 +862,7 @@
<string name="group_system_access_google_assistant" msgid="7210074957915968110">"Отваряне на Асистент"</string>
<string name="group_system_lock_screen" msgid="7391191300363416543">"Заключване на екрана"</string>
<string name="group_system_quick_memo" msgid="3764560265935722903">"Създаване на бележка"</string>
- <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Изпълняване на няколко задачи едновременно"</string>
+ <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Няколко задачи едновременно"</string>
<string name="system_multitasking_rhs" msgid="8714224917276297810">"Използване на разделен екран с текущото приложение вдясно"</string>
<string name="system_multitasking_lhs" msgid="8402954791206308783">"Използване на разделен екран с текущото приложение вляво"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Превключване от разделен към цял екран"</string>
@@ -1407,7 +1402,7 @@
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Системни"</string>
<string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системни контроли"</string>
<string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системни приложения"</string>
- <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Изпълняване на няколко задачи едновременно"</string>
+ <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Няколко задачи едновременно"</string>
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Скорошни приложения"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Разделен екран"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Въвеждане"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Текущо приложение"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Клавишни комбинации"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Персонализиране на клавишните комбинации"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Търсете клавишни комбинации"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма резултати от търсенето"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за свиване"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Персонализиране"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за разгъване"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Манипулатор за преместване с плъзгане"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Предоставено от приложения"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Екран"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Неизвестно"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Нулиране на панелите"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Да се възстанови ли първоначалният ред и размери на панелите?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Да се нулират ли всички панели?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Всички панели с бързи настройки ще бъдат нулирани до първоначалните настройки на устройството"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index c593210..5f8ea8b 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"আপনার স্ক্রিন রেকর্ড করবেন?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"একটি অ্যাপ রেকর্ড করুন"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"সম্পূর্ণ স্ক্রিন রেকর্ড করুন"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"পুরো স্ক্রিন রেকর্ড করুন: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"আপনার সম্পূর্ণ স্ক্রিন রেকর্ড করার সময়, আপনার স্ক্রিনে দেখানো সব কিছু রেকর্ড করা হয়। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ের ক্ষেত্রে সতর্ক থাকুন।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"আপনি কোনও অ্যাপ রেকর্ড করার সময়, সেই অ্যাপে দেখানো বা চালানো সব কিছু রেকর্ড করা হয়। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ের ক্ষেত্রে সতর্ক থাকুন।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"স্ক্রিন রেকর্ড করুন"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"আপনি বর্তমানে <xliff:g id="APP_NAME">%1$s</xliff:g> রেকর্ড করছেন"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"রেকর্ড করা বন্ধ করুন"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"স্ক্রিন শেয়ার করা হচ্ছে"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"কন্টেন্ট শেয়ার করা হচ্ছে"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"স্ক্রিন শেয়ার করা বন্ধ করবেন?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"শেয়ার করা বন্ধ করতে চান?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"আপনি বর্তমানে <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> অ্যাপের সাথে আপনার সম্পূর্ণ স্ক্রিন শেয়ার করছেন"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"আপনি বর্তমানে কোনও একটি অ্যাপের সাথে আপনার সম্পূর্ণ স্ক্রিন শেয়ার করছেন"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"আপনি বর্তমানে <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> অ্যাপের সাথে শেয়ার করছেন"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"আপনি বর্তমানে কোনও একটি অ্যাপের সাথে শেয়ার করছেন"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"আপনি বর্তমানে কোনও একটি অ্যাপের সাথে শেয়ার করছেন"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"শেয়ার করা বন্ধ করুন"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"স্ক্রিন কাস্ট করা হচ্ছে"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"কাস্ট করা বন্ধ করবেন?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"লক স্ক্রিন উইজেট"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"আপনার ট্যাবলেট লক থাকলেও যেকোনও ব্যক্তি লক স্ক্রিনে উইজেট দেখতে পাবেন।"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"উইজেট বাদ দিন"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"উচ্চতা কমান"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"উচ্চতা বাড়ান"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"লক স্ক্রিন উইজেট"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"উইজেট ব্যবহার করে কোনও অ্যাপ খুলতে, আপনাকে নিজের পরিচয় যাচাই করতে হবে। এছাড়াও, মনে রাখবেন, আপনার ট্যাবলেট লক থাকলেও যেকেউ তা দেখতে পারবেন। কিছু উইজেট আপনার লক স্ক্রিনের উদ্দেশ্যে তৈরি করা হয়নি এবং এখানে যোগ করা নিরাপদ নাও হতে পারে।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুঝেছি"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"এখন শুরু করুন"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"কোনও বিজ্ঞপ্তি নেই"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"নতুন কোনও বিজ্ঞপ্তি নেই"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"নোটিফিকেশন কুলডাউন চালু আছে"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"আপনি একসঙ্গে খুব বেশি বিজ্ঞপ্তি পেলে আপনার ডিভাইসের ভলিউম এবং সতর্কবার্তা সর্বাধিক ২ মিনিটের জন্য অটোমেটিক কমে যায়।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"বন্ধ করুন"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুরনো বিজ্ঞপ্তি দেখতে আনলক করুন"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"চালু আছে"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"হেড ট্র্যাকিং"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"রিঙ্গার মোড পরিবর্তন করতে ট্যাপ করুন"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট করুন"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট করুন"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ভাইব্রেট করান"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"বর্তমান অ্যাপ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"অ্যাক্সেসিবিলিটি"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীবোর্ড শর্টকাট"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সার্চ শর্টকাট"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীবোর্ড শর্টকাট কাস্টমাইজ করুন"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"শর্টকাট সার্চ করুন"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"কোনও সার্চ ফলাফল নেই"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"আইকন আড়াল করুন"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"কাস্টমাইজ করুন"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"হয়ে গেছে"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"আইকন বড় করুন"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"টেনে আনার হ্যান্ডেল"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"অ্যাপের তরফ থেকে দেওয়া"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ডিসপ্লে"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"অজানা"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"টাইল রিসেট করুন"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"টাইলগুলিকে অরিজিনাল অর্ডার ও সাইজ অনুযায়ী রিসেট করবেন?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"সব টাইল রিসেট করবেন?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"সব কুইক সেটিংস টাইল, ডিভাইসের আসল সেটিংসে রিসেট হয়ে যাবে"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 38f4265..32f6be3 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Snimati ekran?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimaj jednu aplikaciju"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimaj cijeli ekran"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snimi cijeli ekran: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate cijeli ekran, snimat će se sve što se prikazuje na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snimat će se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimaj ekran"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Trenutno snimate aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zaustavi snimanje"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Dijeljenje ekrana"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Dijeljenje sadržaja"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Zaustaviti dijeljenje ekrana?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Zaustaviti dijeljenje?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Trenutno dijelite cijeli ekran s aplikacijom <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Trenutno dijelite cijeli ekran s aplikacijom"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Trenutno dijelite aplikaciju <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Trenutno dijelite aplikaciju"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Trenutno dijelite s aplikacijom"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Zaustavi dijeljenje"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Emitiranje ekrana"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Zaustaviti emitiranje?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Vidžeti na zaključanom ekranu"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Svi mogu pregledati vidžete na zaključanom ekranu, čak i ako je tablet zaključan."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"poništavanje odabira vidžeta"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Smanjenje visine"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Povećanje visine"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Vidžeti na zaključanom ekranu"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da otvorite aplikaciju pomoću vidžeta, morat ćete potvrditi identitet. Također imajte na umu da ih svako može pregledati, čak i ako je tablet zaključan. Neki vidžeti možda nisu namijenjeni za vaš zaključani ekran i njihovo dodavanje ovdje možda nije sigurno."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumijem"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obavještenja"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obavještenja"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Stišavanje obavještenja je uključeno"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Jačina zvuka uređaja i obavještenja se automatski stišavaju do 2 minute kada odjednom dobijete previše obavještenja."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte da vidite starija obavještenja"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksno"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Praćenje položaja glave"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da promijenite način rada zvuka zvona"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string>
@@ -813,7 +810,7 @@
<string name="keyboard_key_back" msgid="4185420465469481999">"Nazad"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"Tipka za razmak"</string>
- <string name="keyboard_key_enter" msgid="8633362970109751646">"Tipka za novi red"</string>
+ <string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Tipka za brisanje"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Pokreni/pauziraj"</string>
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"Zaustavi"</string>
@@ -869,7 +866,7 @@
<string name="system_multitasking_rhs" msgid="8714224917276297810">"Korištenje podijeljenog ekrana s trenutnom aplikacijom na desnoj strani"</string>
<string name="system_multitasking_lhs" msgid="8402954791206308783">"Korištenje podijeljenog ekrana s trenutnom aplikacijom na lijevoj strani"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Prebacivanje s podijeljenog ekrana na prikaz preko cijelog ekrana"</string>
- <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pređite u aplikaciju desno ili ispod dok koristite podijeljeni ekran"</string>
+ <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prelazak u aplikaciju desno ili ispod uz podijeljeni ekran"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju lijevo ili iznad dok koristite podijeljeni ekran"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Za vrijeme podijeljenog ekrana: zamjena jedne aplikacije drugom"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
@@ -1011,7 +1008,7 @@
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Način rada Ne ometaj uključila je aplikacija <xliff:g id="ID_1">%s</xliff:g>."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Način rada Ne ometaj uključilo je automatsko pravilo ili aplikacija."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije koje rade u pozadini"</string>
- <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
+ <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o potrošnji baterije i prenosa podataka"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Isključiti prijenos podataka na mobilnoj mreži?"</string>
<string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ni internetu putem mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo putem WiFi-ja."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"vaš operater"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Prečice tastature"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite prečice na tastaturi"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečica pretraživanja"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sužavanja"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagođavanje"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona proširivanja"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ručica za prevlačenje"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Pružaju aplikacije"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Prikaz"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Vratite kartice na zadano"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Vratiti kartice na zadani redoslijed i veličine?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vratiti sve kartice na zadano?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Sve kartice Brze postavke će se vratiti na originalne postavke uređaja"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index bcaca5a..8a700dd 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vols gravar la pantalla?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grava una aplicació"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grava tota la pantalla"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grava tota la pantalla: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quan graves tota la pantalla, es grava tot el que es mostra en pantalla. Per aquest motiu, ves amb compte amb elements com les contrasenyes, les dades de pagament, els missatges, les fotos, i l\'àudio i el vídeo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quan graves una aplicació, es grava tot el que es mostra o es reprodueix en aquesta aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos, i l\'àudio i el vídeo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grava la pantalla"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Ara mateix estàs gravant <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Atura la gravació"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"S\'està compartint la pantalla"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"S\'està compartint contingut"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vols deixar de compartir la pantalla?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Vols deixar de compartir-lo?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Ara mateix estàs compartint tota la pantalla amb <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Ara mateix estàs compartint tota la pantalla amb una aplicació"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Ara mateix estàs compartint <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Ara mateix estàs compartint una aplicació"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Ara mateix estàs compartint contingut amb una aplicació"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Deixa de compartir"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"S\'està emetent la pantalla"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vols aturar l\'emissió?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets de la pantalla de bloqueig"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Tothom pot veure els widgets de la teva pantalla de bloqueig, fins i tot quan la tauleta està bloquejada."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desselecciona el widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Redueix l\'alçada"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Augmenta l\'alçada"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets de la pantalla de bloqueig"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per obrir una aplicació utilitzant un widget, necessitaràs verificar la teva identitat. També has de tenir en compte que qualsevol persona pot veure els widgets, fins i tot quan la tauleta està bloquejada. És possible que alguns widgets no estiguin pensats per a la pantalla de bloqueig i que no sigui segur afegir-los-hi."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entesos"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Esborra-ho tot"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestiona"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Configuració de notificacions"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historial de notificacions"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Novetats"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silenciat"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacions"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hi ha cap notificació"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hi ha cap notificació nova"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"La moderació de notificacions està activada"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"El volum i les alertes del dispositiu es redueixen automàticament durant 2 minuts com a màxim quan reps massa notificacions alhora."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactiva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueja per veure notif. anteriors"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fix"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seguiment del cap"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toca per canviar el mode de timbre"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"deixar de silenciar"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicació actual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilitat"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tecles de drecera"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalitza les tecles de drecera"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Dreceres de cerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hi ha cap resultat de la cerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Replega la icona"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalitza"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Fet"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Desplega la icona"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ansa per arrossegar"</string>
@@ -1460,7 +1452,7 @@
<string name="home_controls_dream_description" msgid="4644150952104035789">"Utilitza controls de la llar com a estalvi de pantalla"</string>
<string name="volume_undo_action" msgid="5815519725211877114">"Desfés"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"Per tornar enrere, llisca tres dits cap a l\'esquerra o cap a la dreta al ratolí tàctil"</string>
- <string name="home_edu_toast_content" msgid="3381071147871955415">"Per anar a la pantalla d\'inici, llisca tres dits cap amunt al ratolí tàctil"</string>
+ <string name="home_edu_toast_content" msgid="3381071147871955415">"Per anar a la pantalla d\'inici, fes lliscar tres dits cap amunt al ratolí tàctil"</string>
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Per veure les aplicacions recents, llisca cap amunt amb tres dits i mantén premut al ratolí tàctil"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Per veure totes les aplicacions, prem la tecla d\'acció al teclat"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Emmascarat"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Proporcionat per aplicacions"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Pantalla"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconegut"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Restableix les icones"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Vols restablir l\'ordre i les mides originals de les icones?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vols restablir totes les icones?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Totes les icones de configuració ràpida es restabliran a les opcions originals del dispositiu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 76ae86d..bc52bb8 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Pořídit nahrávku obrazovky?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Nahrát jednu aplikaci"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Nahrát celou obrazovku"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Nahrát celou obrazovku: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Při nahrávání celé obrazovky se zaznamenává veškerý obsah na obrazovce. Buďte proto opatrní, když jde o hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Při nahrávání aplikace se zaznamenává všechno, co se v dané obrazovce zobrazuje nebo přehrává. Buďte proto opatrní, když jde o hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Nahrát obrazovku"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Momentálně nahráváte aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Ukončit nahrávání"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sdílení obrazovky"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Sdílení obsahu"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ukončit sdílení obrazovky?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Ukončit sdílení?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Momentálně sdílíte celou obrazovku s aplikací <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Momentálně sdílíte celou obrazovku s aplikací"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Momentálně sdílíte aplikaci <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Momentálně sdílíte aplikaci"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Momentálně sdílíte obsah s aplikací"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Ukončit sdílení"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Odesílání obsahu obrazovky"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Ukončit odesílání?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgety na obrazovce uzamčení"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Widgety na obrazovce uzamčení může zobrazit kdokoli, i když je tablet uzamčen."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"zrušit výběr widgetu"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Snížit výšku"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Zvýšit výšku"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgety na obrazovce uzamčení"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"K otevření aplikace pomocí widgetu budete muset ověřit svou totožnost. Také mějte na paměti, že widgety uvidí kdokoli, i když tablet bude uzamčen. Některé widgety nemusí být pro obrazovku uzamčení určeny a nemusí být bezpečné je na ni přidat."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Rozumím"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Smazat vše"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Spravovat"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historie"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Nastavení oznámení"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historie oznámení"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nové"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Tichý režim"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Oznámení"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Žádná oznámení"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Žádná nová oznámení"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Oznámení jsou zeslabená"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Když máte moc oznámení najednou, až na dvě minuty se sníží hlasitost zařízení a oznámení se omezí."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnout"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Starší oznámení se zobrazí po odemknutí"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixovaný"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sledování hlavy"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Klepnutím změníte režim vyzvánění"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnout zvuk"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnout zvuk"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrovat"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuální aplikace"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Přístupnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové zkratky"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Přizpůsobení klávesových zkratek"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Vyhledat zkratky"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žádné výsledky hledání"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sbalení"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Přizpůsobit"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalení"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"nebo"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Úchyt pro přetažení"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Poskytováno aplikacemi"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Displej"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznámé"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Resetování dlaždic"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Resetovat dlaždice na původní pořadí a velikosti?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Resetovat všechny dlaždice?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Všechny dlaždice Rychlého nastavení se resetují do původní konfigurace zařízení"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index abcd4b8..0da56bd 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vil du optage din skærm?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Optag én app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Optag hele skærmen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Optag hele skærmen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Når du optager hele skærmen, bliver alt det, der vises på skærmen, optaget. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Når du optager en app, optages alt det, der vises eller afspilles i den pågældende app. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Optag skærm"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Du optager i øjeblikket <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop optagelse"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Skærmen deles"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Indhold deles"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vil du stoppe skærmdelingen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Vil du stoppe med at dele?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Du deler i øjeblikket hele skærmen med <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Du deler i øjeblikket hele skærmen med en app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Du deler i øjeblikket <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Du deler i øjeblikket en app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Du deler i øjeblikket med en app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop deling"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Skærmen castes"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vil du stoppe din cast?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets på låseskærmen"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Alle kan se widgets på din låseskærm, også selvom din tablet er låst."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"fjern markering af widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reducer højden"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Forøg højden"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets på låseskærmen"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Hvis du vil åbne en app ved hjælp af en widget, skal du verificere din identitet. Husk også, at alle kan se dem, også når din tablet er låst. Nogle widgets er muligvis ikke beregnet til låseskærmen, og det kan være usikkert at tilføje dem her."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen notifikationer"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye notifikationer"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Dæmpning af notifikationer er aktiveret"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Enheden skruer automatisk ned for lydstyrken og minimerer underretninger på skærmen i op til 2 minutter, når du får for mange notifikationer på én gang."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås op for at se ældre notifikationer"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fast"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Register. af hovedbevægelser"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tryk for at ændre ringetilstand"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"slå lyden fra"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå lyden til"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrer"</string>
@@ -885,7 +882,7 @@
<string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"Sms"</string>
<string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"Musik"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
- <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Lommeregner"</string>
+ <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Lommeregner"</string>
<string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
<string name="volume_and_do_not_disturb" msgid="502044092739382832">"Forstyr ikke"</string>
<string name="volume_dnd_silent" msgid="4154597281458298093">"Genvej til lydstyrkeknapper"</string>
@@ -992,7 +989,7 @@
<string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
<string name="notification_channel_setup" msgid="7660580986090760350">"Konfiguration"</string>
<string name="notification_channel_storage" msgid="2720725707628094977">"Lagerplads"</string>
- <string name="notification_channel_hints" msgid="7703783206000346876">"Tips"</string>
+ <string name="notification_channel_hints" msgid="7703783206000346876">"Tip"</string>
<string name="notification_channel_accessibility" msgid="8956203986976245820">"Hjælpefunktioner"</string>
<string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
<string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> kører"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuel app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hjælpefunktioner"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastaturgenveje"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpas tastaturgenveje"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Genveje til søgning"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Der er ingen søgeresultater"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon for Skjul"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tilpas"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Udfør"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon for Udvid"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtag"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fra apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Skærm"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ukendt"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Nulstil felter"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Vil du nulstille felterne til deres oprindelige rækkefølge og størrelser?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vil du nulstille alle handlingsfelter?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle handlingsfelter i kvikmenuen nulstilles til enhedens oprindelige indstillinger"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 9799a932..f9b844d 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Bildschirm aufnehmen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Einzelne App aufnehmen"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gesamten Bildschirm aufnehmen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gesamten Bildschirm aufnehmen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Wenn du den gesamten Bildschirm aufnimmst, ist in der Aufnahme alles zu sehen, was auf dem Bildschirm angezeigt wird. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Wenn du eine App aufnimmst, ist in der Aufnahme alles zu sehen, was in dieser App angezeigt oder abgespielt wird. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Bildschirm aufnehmen"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Du zeichnest momentan Inhalte der App <xliff:g id="APP_NAME">%1$s</xliff:g> auf"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Aufzeichnung beenden"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Bildschirm wird geteilt"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Inhalte teilen"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Bildschirmfreigabe beenden?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Teilen beenden?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Du teilst momentan deinen gesamten Bildschirm mit der App <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Du teilst momentan deinen gesamten Bildschirm mit einer App"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Du teilst momentan die App <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Du teilst momentan Inhalte einer App"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Du teilst momentan Inhalte mit einer App"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Freigabe beenden"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Bildschirm wird übertragen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Streaming beenden?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Sperrbildschirm-Widgets"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Jeder kann Widgets auf deinem Sperrbildschirm sehen, auch bei gesperrtem Tablet."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"Auswahl für Widget aufheben"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Höhe verringern"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Höhe vergrößern"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Sperrbildschirm-Widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Wenn du eine App mit einem Widget öffnen möchtest, musst du deine Identität bestätigen. Beachte auch, dass jeder die Widgets sehen kann, auch wenn dein Tablet gesperrt ist. Einige Widgets sind möglicherweise nicht für den Sperrbildschirm vorgesehen, sodass es unsicher sein kann, sie hier hinzuzufügen."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Alle löschen"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Verwalten"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Verlauf"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Benachrichtigungseinstellungen"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Benachrichtigungsverlauf"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Neu"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Lautlos"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Benachrichtigungen"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Keine Benachrichtigungen"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Keine neuen Benachrichtigungen"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"„Benachrichtigungen reduzieren” ist aktiviert"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Wenn du zu viele Benachrichtigungen auf einmal erhältst, wird die Lautstärke automatisch bis zu 2 min lang verringert und Benachrichtigungen werden minimiert."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktivieren"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Für ältere Benachrichtigungen entsperren"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Statisch"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Erfassung von Kopfbewegungen"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Zum Ändern des Klingeltonmodus tippen"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Stummschalten"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"Aufheben der Stummschaltung"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"Vibrieren lassen"</string>
@@ -854,9 +849,9 @@
<string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Tastenkombinationen für die Eingabe werden angezeigt"</string>
<string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Tastenkombinationen zum Öffnen von Apps werden angezeigt"</string>
<string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Tastenkombinationen für die aktuelle App werden angezeigt"</string>
- <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Benachrichtigungen ansehen"</string>
+ <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Benachrichtigungen ansehen"</string>
<string name="group_system_full_screenshot" msgid="5742204844232667785">"Screenshot erstellen"</string>
- <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Tastenkombinationen anzeigen"</string>
+ <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Tastenkürzel anzeigen"</string>
<string name="group_system_go_back" msgid="2730322046244918816">"Zurück"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"Zum Startbildschirm wechseln"</string>
<string name="group_system_overview_open_apps" msgid="5659958952937994104">"Letzte Apps aufrufen"</string>
@@ -877,8 +872,8 @@
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Eingabe"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Zur nächsten Sprache wechseln"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Zur vorherigen Sprache wechseln"</string>
- <string name="input_access_emoji" msgid="8105642858900406351">"Auf Emojis zugreifen"</string>
- <string name="input_access_voice_typing" msgid="7291201476395326141">"Auf Spracheingabe zugreifen"</string>
+ <string name="input_access_emoji" msgid="8105642858900406351">"Emojis aufrufen"</string>
+ <string name="input_access_voice_typing" msgid="7291201476395326141">"Spracheingabe aufrufen"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Apps"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Browser"</string>
@@ -1408,22 +1403,19 @@
<string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemsteuerelemente"</string>
<string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System-Apps"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
- <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Zuletzt aktive Apps"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Zuletzt verwendete Apps"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Splitscreen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Eingabe"</string>
- <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-Verknüpfungen"</string>
+ <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-Verknüpfungen"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuelle App"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Bedienungshilfen"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastenkürzel"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tastenkombinationen anpassen"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tastenkürzel suchen"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Keine Suchergebnisse"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Symbol „Minimieren“"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Anpassen"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Fertig"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Symbol „Maximieren“"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oder"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ziehpunkt"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Von Apps bereitgestellt"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unbekannt"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Kacheln zurücksetzen"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Kacheln auf die ursprüngliche Reihenfolge und Größe zurücksetzen?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Alle Kacheln zurücksetzen?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle Schnelleinstellungen-Kacheln werden auf die Standardeinstellungen des Geräts zurückgesetzt"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 7200a91..74019de 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Να γίνει εγγραφή της οθόνης σας;"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Εγγραφή μίας εφαρμογής"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Εγγραφή ολόκληρης της οθόνης"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Εγγραφή ολόκληρης της οθόνης: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Όταν κάνετε εγγραφή ολόκληρης της οθόνη σας, καταγράφεται οτιδήποτε εμφανίζεται σε αυτήν. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Όταν κάνετε εγγραφή μιας εφαρμογής, καταγράφεται οτιδήποτε εμφανίζεται ή αναπαράγεται στη συγκεκριμένη εφαρμογή. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Εγγραφή οθόνης"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Αυτή τη στιγμή εγγράφετε το <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Διακοπή εγγραφής"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Γίνεται κοινοποίηση οθόνης"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Κοινή χρήση περιεχομένου"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Διακοπή κοινής χρήσης οθόνης;"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Να διακοπεί η κοινή χρήση;"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Αυτή τη στιγμή μοιράζεστε ολόκληρη την οθόνη σας με το <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Αυτή τη στιγμή μοιράζεστε ολόκληρη την οθόνη σας με μια εφαρμογή"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Αυτή τη στιγμή μοιράζεστε το <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Αυτή τη στιγμή μοιράζεστε μια εφαρμογή"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Αυτή τη στιγμή, μοιράζεστε περιεχόμενο με μια εφαρμογή"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Διακοπή κοινής χρήσης"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Μετάδοση οθόνης"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Τερματισμός μετάδοσης;"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Γραφικά στοιχεία οθόνης κλειδώματος"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Όλοι μπορούν να δουν γραφικά στοιχεία στην οθόνη κλειδώματος, ακόμα και αν το tablet είναι κλειδωμένο."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"αποεπιλογή γραφικού στοιχείου"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Μείωση του ύψους"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Αύξηση του ύψους"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Γραφικά στοιχεία οθόνης κλειδώματος"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Για να ανοίξετε μια εφαρμογή χρησιμοποιώντας ένα γραφικό στοιχείο, θα πρέπει να επαληθεύσετε την ταυτότητά σας. Επίσης, λάβετε υπόψη ότι η προβολή τους είναι δυνατή από οποιονδήποτε, ακόμα και όταν το tablet σας είναι κλειδωμένο. Ορισμένα γραφικά στοιχεία μπορεί να μην προορίζονται για την οθόνη κλειδώματος και η προσθήκη τους εδώ ενδέχεται να μην είναι ασφαλής."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Το κατάλαβα"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Διαγραφή όλων"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Διαχείριση"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Ιστορικό"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Ρυθμίσεις ειδοποιήσεων"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Ιστορικό ειδοποιήσεων"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Νέα"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Σίγαση"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ειδοποιήσεις"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Έναρξη τώρα"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Δεν υπάρχουν ειδοποιήσεις"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Δεν υπάρχουν νέες ειδοποιήσεις"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Η ρύθμιση cooldown ειδοποιήσεων είναι ενεργή"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Αυτόματη μείωση έντασης ήχου συσκευής και ειδοποιήσεων για έως 2 λεπτά όταν λαμβάνετε πολλές ειδοποιήσεις ταυτόχρονα."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Απενεργοποίηση"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ξεκλειδώστε για εμφάνιση παλαιότ. ειδοπ."</string>
@@ -705,6 +698,7 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Σταθερός"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Παρακ. κίνησ. κεφαλής"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Πατήστε για να αλλάξετε τη λειτουργία ειδοποίησης ήχου"</string>
+ <string name="volume_ringer_mode" msgid="6867838048430807128">"λειτουργία ειδοποίησης ήχου"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"σίγαση"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"κατάργηση σίγασης"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"δόνηση"</string>
@@ -1415,15 +1409,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Τρέχουσα εφαρμογή"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Προσβασιμότητα"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Συντομεύσεις πληκτρολογίου"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Προσαρμογή συντομεύσεων πληκτρολογίου"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Συντομεύσεις αναζήτησης"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Κανένα αποτέλεσμα αναζήτησης"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Εικονίδιο σύμπτυξης"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Προσαρμογή"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Τέλος"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Εικονίδιο ανάπτυξης"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ή"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Λαβή μεταφοράς"</string>
@@ -1485,6 +1476,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Παρέχεται από εφαρμογές"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Προβολή"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Άγνωστο"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Επαναφορά πλακιδίων"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Επαναφορά των πλακιδίων στην αρχική τους σειρά και μεγέθη;"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Επαναφορά σε όλα τα πλακάκια;"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Σε όλα τα πλακάκια Γρήγορων ρυθμίσεων θα γίνει επαναφορά στις αρχικές ρυθμίσεις της συσκευής"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 1ecf4f1..d56abeb 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"You\'re currently recording <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Sharing content"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Stop sharing?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"You\'re currently sharing your entire screen with <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"You\'re currently sharing your entire screen with an app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"You\'re currently sharing <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"You\'re currently sharing an app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"You\'re currently sharing with an app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Casting screen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stop casting?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Lock screen widgets"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Anyone can view widgets on your lock screen, even if your tablet\'s locked."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"unselect widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Decrease height"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Increase height"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Clear all"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Manage"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"History"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Notification settings"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Notification history"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"New"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silent"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Notification cooldown is on"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Your device volume and alerts are reduced automatically for up to 2 minutes when you get too many notifications at once."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixed"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customise"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provided by apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Reset tiles"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Reset tiles to their original order and sizes?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device\'s original settings"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index f775513..bee2393 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you’re recording your entire screen, anything shown on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you’re recording an app, anything shown or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -590,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Notification cooldown is on"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Your device volume and alerts are reduced automatically for up to 2 minutes when you get too many notifications at once."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
@@ -698,6 +698,7 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixed"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head Tracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
+ <string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1408,15 +1409,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current App"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customize keyboard shortcuts"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customize"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
@@ -1478,6 +1476,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provided by apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Reset tiles"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Reset tiles to their original order and sizes?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device’s original settings"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 1ecf4f1..d56abeb 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"You\'re currently recording <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Sharing content"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Stop sharing?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"You\'re currently sharing your entire screen with <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"You\'re currently sharing your entire screen with an app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"You\'re currently sharing <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"You\'re currently sharing an app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"You\'re currently sharing with an app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Casting screen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stop casting?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Lock screen widgets"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Anyone can view widgets on your lock screen, even if your tablet\'s locked."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"unselect widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Decrease height"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Increase height"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Clear all"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Manage"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"History"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Notification settings"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Notification history"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"New"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silent"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Notification cooldown is on"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Your device volume and alerts are reduced automatically for up to 2 minutes when you get too many notifications at once."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixed"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customise"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provided by apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Reset tiles"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Reset tiles to their original order and sizes?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device\'s original settings"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 1ecf4f1..d56abeb 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"You\'re currently recording <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Sharing content"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Stop sharing?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"You\'re currently sharing your entire screen with <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"You\'re currently sharing your entire screen with an app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"You\'re currently sharing <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"You\'re currently sharing an app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"You\'re currently sharing with an app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Casting screen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stop casting?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Lock screen widgets"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Anyone can view widgets on your lock screen, even if your tablet\'s locked."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"unselect widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Decrease height"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Increase height"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear in mind that anyone can view them, even when your tablet\'s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Clear all"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Manage"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"History"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Notification settings"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Notification history"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"New"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silent"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Notification cooldown is on"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Your device volume and alerts are reduced automatically for up to 2 minutes when you get too many notifications at once."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixed"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customise"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provided by apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Unknown"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Reset tiles"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Reset tiles to their original order and sizes?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset all tiles?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"All Quick Settings tiles will reset to the device\'s original settings"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 77c2a63..6f04e8e 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"¿Quieres grabar la pantalla?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabar una app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabar toda la pantalla"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grabar toda la pantalla: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabes toda la pantalla, se grabará todo lo que se muestre en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabes una app, se registrará todo lo que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabar pantalla"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Actualmente, estás grabando <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Detener grabación"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartiendo pantalla"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Compartiendo contenido"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"¿Quieres dejar de compartir la pantalla?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"¿Quieres dejar de compartir?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Actualmente, estás compartiendo toda la pantalla con <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Actualmente, estás compartiendo toda la pantalla con una app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Actualmente, estás compartiendo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Actualmente, estás compartiendo una app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Actualmente, estás compartiendo con una app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Dejar de compartir"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Transmitiendo pantalla"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"¿Detener la transmisión?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets en la pantalla de bloqueo"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Los widgets de la pantalla de bloqueo podrán verse incluso si bloqueas la tablet."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"anular la selección del widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reducir la altura"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar la altura"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets en la pantalla de bloqueo"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una app usando un widget, debes verificar tu identidad. Además, ten en cuenta que cualquier persona podrá verlo, incluso cuando la tablet esté bloqueada. Es posible que algunos widgets no se hayan diseñados para la pantalla de bloqueo y podría ser peligroso agregarlos allí."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Comenzar ahora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Reducción de sonido de notificaciones activada"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"El volumen y las alertas se reducen por hasta 2 minutos si recibes muchas notificaciones a la vez."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fijar"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Monitoreo de cabeza"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Presiona para cambiar el modo de timbre"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App actual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personaliza las combinaciones de teclas"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Buscar combinaciones de teclas"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"La búsqueda no arrojó resultados"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícono de contraer"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Listo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícono de expandir"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Proporcionado por apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Pantalla"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconocido"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Restablecer tarjetas"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"¿Quieres restablecer las tarjetas al orden y el tamaño originales?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"¿Quieres restablecer todas las tarjetas?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Se restablecerán todas las tarjeta de Configuración rápida a la configuración original del dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 81b1562..10f3754c 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"¿Grabar la pantalla?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabar una aplicación"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabar toda la pantalla"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grabar toda la pantalla: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabas toda la pantalla, se graba todo lo que se muestre en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabas una aplicación, se graba todo lo que se muestre o reproduzca en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabar pantalla"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Estás grabando <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Detener grabación"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartiendo pantalla"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Compartiendo contenido"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"¿Dejar de compartir pantalla?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"¿Dejar de compartir?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Estás compartiendo toda tu pantalla con <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Estás compartiendo toda tu pantalla con una aplicación"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Estás compartiendo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Estás compartiendo una aplicación"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Estás compartiendo una aplicación"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Dejar de compartir"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Enviando pantalla"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"¿Dejar de enviar?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets para la pantalla de bloqueo"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Cualquiera puede ver los widgets de tu pantalla de bloqueo, aunque tu tablet esté bloqueada."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"deseleccionar widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reducir altura"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar altura"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets para la pantalla de bloqueo"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una aplicación usando un widget, deberás verificar que eres tú. Además, ten en cuenta que cualquier persona podrá verlos, incluso aunque tu tablet esté bloqueada. Es posible que algunos widgets no estén pensados para la pantalla de bloqueo y no sea seguro añadirlos aquí."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestionar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Ajustes de notificaciones"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historial de notificaciones"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nuevas"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silenciadas"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Bajar el volumen de notificaciones está activado"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"El volumen y las alertas de tu dispositivo se reducen durante hasta 2 minutos si recibes muchas notificaciones a la vez."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fijo"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seguimiento de cabeza"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar el modo de timbre"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -814,7 +809,7 @@
<string name="keyboard_key_home" msgid="3734400625170020657">"Inicio"</string>
<string name="keyboard_key_back" msgid="4185420465469481999">"Atrás"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
- <string name="keyboard_key_space" msgid="6980847564173394012">"Espacio"</string>
+ <string name="keyboard_key_space" msgid="6980847564173394012">"Espa-cio"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Intro"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Tecla de retroceso"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Reproducir/Pausa"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicación en uso"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar las combinaciones de teclas"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atajos de búsqueda"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hay resultados de búsqueda"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icono de contraer"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hecho"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icono de desplegar"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
@@ -1447,7 +1439,7 @@
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"¡Bien hecho!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Has completado el gesto para ir a la pantalla de inicio"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver aplicaciones recientes"</string>
- <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Desliza hacia arriba y mantén pulsado con tres dedos en el panel táctil"</string>
+ <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Desliza hacia arriba con tres dedos y mantén pulsado en el panel táctil"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"¡Bien hecho!"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Has completado el gesto para ver las aplicaciones recientes."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todas las aplicaciones"</string>
@@ -1471,7 +1463,7 @@
<string name="home_edu_notification_title" msgid="6097902076909654045">"Usa el panel táctil para ir a la pantalla de inicio"</string>
<string name="home_edu_notification_content" msgid="6631697734535766588">"Desliza hacia arriba con tres dedos. Toca para aprender a usar más gestos."</string>
<string name="overview_edu_notification_title" msgid="1265824157319562406">"Usa el panel táctil para ver las aplicaciones recientes"</string>
- <string name="overview_edu_notification_content" msgid="3578204677648432500">"Desliza hacia arriba y mantén pulsado con tres dedos. Toca para aprender a usar más gestos."</string>
+ <string name="overview_edu_notification_content" msgid="3578204677648432500">"Desliza hacia arriba con tres dedos y mantén pulsado. Toca para aprender a usar más gestos."</string>
<string name="all_apps_edu_notification_title" msgid="372262997265569063">"Usa el teclado para ver todas las aplicaciones"</string>
<string name="all_apps_edu_notification_content" msgid="3255070575694025585">"Pulsa la tecla de acción en cualquier momento. Toca para aprender a usar más gestos."</string>
<string name="accessibility_deprecate_extra_dim_dialog_title" msgid="910988771011857460">"La atenuación extra ahora forma parte del control deslizante de brillo"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Proporcionado por aplicaciones"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Pantalla"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconocido"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Restablecer recuadros"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"¿Restablecer recuadros a su orden y tamaño originales?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"¿Borrar todos los recuadros?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos los recuadros de ajustes rápidos se restablecerán a los ajustes originales del dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 56039da5..e73a7dd 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Kas salvestada ekraanikuvast video?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ühe rakenduse salvestamine"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Kogu ekraanikuva salvestamine"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Kogu ekraanikuva salvestamine: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kui salvestate kogu ekraani, salvestatakse kõik ekraanil kuvatud andmed. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kui salvestate rakendust, salvestatakse kõik, mida selles rakenduses näidatakse või esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekraanikuva jäädvustamine"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Salvestate praegu rakendust <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Peata salvestamine"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekraani jagamine"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Sisu jagamine"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Kas lõpetada ekraanikuva jagamine?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Kas lõpetada jagamine?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Jagate praegu kogu oma ekraanikuva rakendusega <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Jagate praegu kogu oma ekraanikuva rakendusega"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Jagate praegu rakenduse <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> kuva"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Jagate praegu rakenduse kuva"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Jagate praegu rakendusega"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Lõpeta jagamine"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Ekraanikuva ülekandmine"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Kas peatada ülekandmine?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Lukustuskuva vidinad"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Igaüks saab vaadata luk.kuval olevaid vidinaid, isegi kui tahvelarvuti on lukus."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"tühistage vidina valimine"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Vähenda kõrgust"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Suurenda kõrgust"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lukustuskuva vidinad"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Rakenduse avamiseks vidina abil peate kinnitama, et see olete teie. Samuti pidage meeles, et kõik saavad vidinaid vaadata, isegi kui teie tahvelarvuti on lukus. Mõni vidin ei pruugi olla ette nähtud teie lukustuskuva jaoks ja seda pole turvaline siia lisada."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selge"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tühjenda kõik"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Haldamine"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Ajalugu"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Märguandeseaded"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Märguannete ajalugu"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Uued"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Hääletu"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Märguanded"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Märguandeid pole"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Uusi märguandeid ei ole"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Märguannete summutamine on sees"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Kui saate korraga liiga palju märguandeid, vähendab seade automaatselt helitugevust ja minimeerib märguanded kuni kaheks minutiks."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Lülita välja"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vanemate märguannete nägemiseks avage"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fikseeritud"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pea jälgimine"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Puudutage telefonihelina režiimi muutmiseks"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vaigistamine"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vaigistuse tühistamine"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibreerimine"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Praegune rakendus"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Juurdepääsetavus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatuuri otseteed"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Otsingu otseteed"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatuuri otseteede kohandamine"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Otsige otseteid"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Otsingutulemused puuduvad"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ahendamisikoon"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Kohandamine"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Valmis"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laiendamisikoon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"või"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Lohistamispide"</string>
@@ -1435,14 +1427,14 @@
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Navigeerige klaviatuuri ja puuteplaadi abil"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Õppige puuteplaadi liigutusi, klaviatuuri otseteid ja palju muud"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Mine tagasi"</string>
- <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Avalehele"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Avakuvale"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Hiljutiste rakenduste vaatamine"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Valmis"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Tagasi"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Pühkige puuteplaadil kolme sõrmega vasakule või paremale"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Tubli töö!"</string>
<string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Tegite tagasiliikumise liigutuse."</string>
- <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Avalehele"</string>
+ <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Avakuvale"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Pühkige puuteplaadil kolme sõrmega üles"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Väga hea!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Tegite avakuvale minemise liigutuse"</string>
@@ -1460,8 +1452,8 @@
<string name="home_controls_dream_description" msgid="4644150952104035789">"Juurdepääs kodu juhtelementidele ekraanisäästjalt"</string>
<string name="volume_undo_action" msgid="5815519725211877114">"Võta tagasi"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"Tagasiliikumiseks pühkige puuteplaadil kolme sõrmega vasakule või paremale"</string>
- <string name="home_edu_toast_content" msgid="3381071147871955415">"Avakuvale liikumiseks pühkige puuteplaadil kolme sõrmega üles"</string>
- <string name="overview_edu_toast_content" msgid="5797030644017804518">"Hiljutiste rakenduste kuvamiseks pühkige puuteplaadil kolme sõrmega üles ja hoidke sõrmi puuteplaadil"</string>
+ <string name="home_edu_toast_content" msgid="3381071147871955415">"Avakuvale liikumiseks pühkige puuteplaadil kolme sõrmega üles."</string>
+ <string name="overview_edu_toast_content" msgid="5797030644017804518">"Hiljutiste rakenduste kuvamiseks pühkige puuteplaadil kolme sõrmega üles ja hoidke sõrmi puuteplaadil."</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Kõigi oma rakenduste kuvamiseks vajutage klaviatuuril toiminguklahvi"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Peidetud"</string>
<string name="redacted_notification_single_line_text" msgid="8684166405005242945">"Vaatamiseks avage"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Rakendustelt"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Kuva"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Teadmata"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Paanide lähtestamine"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Kas soovite paanid lähtestada nende algsesse järjekorda ja suurusesse?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Kas lähtestada kõik paanid?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Kõik kiirseadete paanid lähtestatakse seadme algseadetele"</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 426d1d7..71bc77f 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Pantaila grabatu nahi duzu?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabatu aplikazio bat"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabatu pantaila osoa"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grabatu pantaila osoa: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pantaila osoa grabatzen ari zarenean, pantailan agertzen den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Aplikazio bat grabatzen ari zarenean, aplikazio horretan agertzen den edo bertan erreproduzitzen ari den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabatu pantaila"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"<xliff:g id="APP_NAME">%1$s</xliff:g> grabatzen ari zara"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Utzi grabatzeari"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Pantaila partekatzen"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Edukia partekatzen"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Pantaila partekatzeari utzi nahi diozu?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Partekatzeari utzi nahi diozu?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Pantaila osoa <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> aplikazioarekin partekatzen ari zara"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Pantaila osoa aplikazio batekin partekatzen ari zara"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> partekatzen ari zara"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Aplikazio bat partekatzen ari zara"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Aplikazio batekin edukia partekatzen ari zara"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Utzi partekatzeari"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Pantaila igortzen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Igortzeari utzi nahi diozu?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Pantaila blokeatuko widgetak"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Edonork ikus ditzake pantaila blokeatuko widgetak, tableta blokeatuta badago ere."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desautatu widgeta"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Txikitu altuera"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Handitu altuera"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Pantaila blokeatuko widgetak"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aplikazio bat widget baten bidez irekitzeko, zeu zarela egiaztatu beharko duzu. Gainera, kontuan izan edonork ikusi ahalko dituela halako widgetak, tableta blokeatuta badago ere. Baliteke widget batzuk pantaila blokeaturako egokiak ez izatea, eta agian ez da segurua haiek bertan gehitzea."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ados"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Garbitu guztiak"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Kudeatu"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Jakinarazpen-ezarpenak"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Jakinarazpenen historia"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Berria"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Isila"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Jakinarazpenak"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ez dago jakinarazpenik"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ez dago jakinarazpen berririk"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Jakinarazpenak arintzeko ezarpena aktibatuta dago"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Aldi berean jakinarazpen gehiegi jasotzen badituzu, gailuaren bolumena eta alertak automatikoki murriztuko dira 2 minutuz (gehienez)."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desaktibatu"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Jakinarazpen zaharragoak ikusteko, desblokeatu"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Finkoa"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Buruaren jarraipena"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Sakatu tonu-jotzailearen modua aldatzeko"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desaktibatu audioa"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktibatu audioa"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"dardara"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Oraingo aplikazioa"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erabilerraztasuna"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Lasterbideak"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pertsonalizatu lasterbideak"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Bilatu lasterbideak"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ez dago bilaketa-emaitzarik"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tolesteko ikonoa"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Pertsonalizatu"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Eginda"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Zabaltzeko ikonoa"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"edo"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Arrastatzeko kontrol-puntua"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Aplikazioenak"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Pantaila"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ezezagunak"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Berrezarri lauzak"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Lauzen jatorrizko ordena eta tamainak berrezarri nahi dituzu?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Lauza guztiak berrezarri nahi dituzu?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Gailuaren jatorrizko ezarpenak berrezarriko dira ezarpen bizkorren lauza guztietan"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b0d23aa..d82edf9 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"صفحهنمایش ضبط شود؟"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ضبط یک برنامه"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ضبط کل صفحهنمایش"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ضبط کردن کل صفحهنمایش: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"وقتی کل صفحهنمایش را ضبط میکنید، هر چیزی که در صفحهنمایش نشان داده شود ضبط خواهد شد. درنتیجه مراقب چیزهایی مثل گذرواژهها، جزئیات پرداخت، پیامها، عکسها، و صدا و تصویر باشید."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"وقتی برنامهای را ضبط میکنید، هر چیزی که در آن برنامه نشان داده شود یا پخش شود ضبط خواهد شد. درنتیجه مراقب چیزهایی مثل گذرواژهها، جزئیات پرداخت، پیامها، عکسها، و صدا و تصویر باشید."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ضبط صفحهنمایش"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"اکنون درحال ضبط <xliff:g id="APP_NAME">%1$s</xliff:g> هستید"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"توقف ضبط"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"درحال همرسانی صفحه"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"همرسانی محتوا"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"همرسانی صفحه متوقف شود؟"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"همرسانی متوقف شود؟"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"اکنون درحال همرسانی کل صفحهنمایشتان با <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> هستید"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"اکنون درحال همرسانی کل صفحهنمایشتان با یک برنامه هستید"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"اکنون درحال همرسانی <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> هستید"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"اکنون درحال همرسانی با یک برنامه هستید"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"درحال همرسانی با یک برنامه هستید"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"توقف همرسانی"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"درحال پخش محتوای صفحهنمایش"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"پخش محتوا متوقف شود؟"</string>
@@ -417,7 +413,7 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"برای جفت کردن دستگاه جدید، کلیک کنید"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"پیشتنظیم بهروزرسانی نشد"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"پیشتنظیم"</string>
- <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"زیرنویس ناشنوایان زنده"</string>
+ <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"زیرنویس زنده ناشنوایان"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"میکروفون دستگاه لغو انسداد شود؟"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"دوربین دستگاه لغو انسداد شود؟"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"دوربین و میکروفون دستگاه لغو انسداد شود؟"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ابزارههای صفحه قفل"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"همه میتوانند ابزارهها را در صفحه قفل شما ببینند، حتی اگر رایانه لوحی قفل باشد."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"لغو انتخاب ابزاره"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"کاهش ارتفاع"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"افزایش ارتفاع"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ابزارههای صفحه قفل"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"برای باز کردن برنامه بااستفاده از ابزاره، باید هویت خودتان را بهتأیید برسانید. همچنین، بهخاطر داشته باشید که همه میتوانند آنها را مشاهده کنند، حتی وقتی رایانه لوحیتان قفل است. برخیاز ابزارهها ممکن است برای صفحه قفل درنظر گرفته نشده باشند و ممکن است اضافه کردن آنها در اینجا ناامن باشد."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"متوجهام"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"اکنون شروع کنید"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"اعلانی موجود نیست"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"اعلان جدیدی وجود ندارد"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"«استراحت اعلانها» روشن است"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"وقتی بهطور همزمان تعداد بسیار زیادی اعلان دریافت کنید، میزان صدای دستگاه و هشدارها بهطور خودکار تا ۲ دقیقه کاهش مییابد."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"خاموش کردن"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"برای دیدن اعلانهای قبلی قفل را باز کنید"</string>
@@ -653,7 +648,7 @@
<string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"غیرفعال کردن"</string>
<string name="sound_settings" msgid="8874581353127418308">"صدا و لرزش"</string>
<string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"تنظیمات"</string>
- <string name="volume_panel_captioning_title" msgid="5984936949147684357">"زیرنویس ناشنوایان زنده"</string>
+ <string name="volume_panel_captioning_title" msgid="5984936949147684357">"زیرنویس زنده ناشنوایان"</string>
<string name="csd_lowered_title" product="default" msgid="2464112924151691129">"صدا به سطح ایمنتر کاهش یافت"</string>
<string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"صدای هدفون برای مدتی طولانیتر از حد توصیهشده بلند بوده است"</string>
<string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"صدای هدفون از حد ایمن برای این هفته فراتر رفته است"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ثابت"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ردیابی سر"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"برای تغییر حالت زنگ، تکضرب بزنید"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"صامت کردن"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"باصدا کردن"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"لرزش"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"برنامه فعلی"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترسپذیری"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"میانبرهای صفحهکلید"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"سفارشیسازی کردن میانبرهای صفحهکلید"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"جستجوی میانبرها"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"نتیجهای برای جستجو پیدا نشد"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"نماد جمع کردن"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"سفارشیسازی کردن"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"تمام"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"نماد ازهم بازکردن"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"دستگیره کشاندن"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ارائهشده از برنامهها"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"نمایشگر"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"نامشخص"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"بازنشانی کردن کاشیها"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"اندازه و ترتیب کاشیها به حالت اولیهشان بازنشانی شود؟"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"همه کاشیها بازنشانی شود؟"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"همه کاشیهای «تنظیمات فوری» به تنظیمات اصلی دستگاه بازنشانی خواهد شد"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 690228f..e3d27a5 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Tallennetaanko näytön toimintaa?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Tallenna yhdestä sovelluksesta"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tallenna koko näyttö"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Tallenna koko näyttö: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kun tallennat koko näyttöä, kaikki näytöllä näkyvä sisältö tallennetaan. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kun tallennat sovellusta, kaikki sovelluksessa näkyvä tai toistettu sisältö tallennetaan. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Tallenna näyttö"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Laite, jonka sisältöä tallennat: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Lopeta tallennus"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Näyttöä jaetaan"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Jaetaan sisältöä"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Lopetetaanko näytön jakaminen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Lopetetaanko jakaminen?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Jaat tällä hetkellä koko näyttöä: <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Jaat tällä hetkellä koko näyttöä sovellukselle"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Jaat tällä hetkellä tätä: <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Jaat tällä hetkellä sovellusta"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Jaat tällä hetkellä sovellukseen"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Lopeta jakaminen"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Näyttöä striimataan"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Lopetetaanko striimaus?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Lukitusnäytön widgetit"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Kaikki voivat nähdä widgetit lukitusnäytöllä, vaikka tabletti olisi lukittuna."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"poista widgetin valinta"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Vähennä korkeutta"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Lisää korkeutta"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lukitusnäytön widgetit"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Jos haluat avata sovelluksen käyttämällä widgetiä, sinun täytyy vahvistaa henkilöllisyytesi. Muista myös, että widgetit näkyvät kaikille, vaikka tabletti olisi lukittuna. Jotkin widgetit on ehkä tarkoitettu lukitusnäytölle, ja niiden lisääminen tänne ei välttämättä ole turvallista."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selvä"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tyhjennä kaikki"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Muuta asetuksia"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Ilmoitusasetukset"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Ilmoitushistoria"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Uudet"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Äänetön"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ilmoitukset"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ei ilmoituksia"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ei uusia ilmoituksia"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Ilmoitusten vaimennus on päällä"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Äänenvoimakkuus ja ilmoitukset vaimennetaan enintään 2 minuutiksi, kun saat paljon ilmoituksia."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Laita pois päältä"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Avaa lukitus niin näet ilmoituksia"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Kiinteä"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pään seuranta"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Vaihda soittoäänen tilaa napauttamalla"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mykistä"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"poista mykistys"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"värinä"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Nykyinen sovellus"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Saavutettavuus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pikanäppäimet"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pikanäppäimien muokkaaminen"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pikahaut"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ei hakutuloksia"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tiivistyskuvake"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Muokkaa"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Valmis"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laajennuskuvake"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"tai"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vetokahva"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Sovellusten tarjoama"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Näyttö"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tuntematon"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Palauta laatat"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Palautetaanko laatat alkuperäiseen järjestykseen ja kokoon?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Nollataanko kaikki laatat?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Kaikki pika-asetuslaatat palautetaan laitteen alkuperäisiin asetuksiin"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5ea58ce..d01acd3 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Enregistrer votre écran?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Enregistrer une appli"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Enregistrer l\'écran entier"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Enregistrer tout l\'écran : %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'affiche sur votre écran est enregistré. Par conséquent, soyez prudent avec les mots de passe, les détails du mode de paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Lorsque vous enregistrez une appli, tout ce qui est affiché ou lu dans cette appli est enregistré. Par conséquent, soyez prudent avec les mots de passe, les détails du mode de paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Enregistrer l\'écran"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Vous êtes en train d\'enregistrer <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Arrêter l\'enregistrement"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Partage d\'écran en cours…"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Partage de contenu en cours…"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Arrêter le partage d\'écran?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Arrêter le partage?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Vous partagez actuellement l\'intégralité de votre écran avec <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Vous partagez actuellement l\'intégralité de votre écran avec une appli"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Vous partagez actuellement <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Vous partagez actuellement une appli"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Vous partagez actuellement un élément avec une appli"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Arrêter le partage"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Diffusion de l\'écran en cours…"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Arrêter la diffusion?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets de l\'écran de verrouillage"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"N\'importe qui peut voir les widgets sur votre écran de verrouillage, même si votre tablette est verrouillée."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"désélectionner le widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuer la hauteur"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Augmenter la hauteur"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets de l\'écran de verrouillage"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pour ouvrir une appli à l\'aide d\'un widget, vous devrez confirmer votre identité. En outre, gardez à l\'esprit que tout le monde peut voir les widgets, même lorsque votre tablette est verrouillée. Certains widgets n\'ont peut-être pas été conçus pour votre écran de verrouillage, et il pourrait être dangereux de les ajouter ici."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historique"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Paramètres de notification"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historique des notifications"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nouvelles"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Mode silencieux"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"L\'atténuation des notifications est activée"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Les alertes et le volume de l\'appareil sont réduits automatiquement pendant 2 minutes maximum quand vous recevez trop de notifications à la fois."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverr. pour voir les anciennes notif."</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Activé"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Suivi de la tête"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Touchez pour modifier le mode de sonnerie"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"désactiver le son"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibration"</string>
@@ -843,7 +838,7 @@
<string name="keyboard_shortcut_join" msgid="3578314570034512676">"ou"</string>
<string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Effacez la requête de recherche"</string>
<string name="keyboard_shortcut_search_list_title" msgid="4271769465397671138">"Raccourcis-clavier"</string>
- <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Recherchez des raccourcis"</string>
+ <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Rechercher des raccourcis"</string>
<string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Aucun raccourci trouvé"</string>
<string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"Système"</string>
<string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrée"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Appli actuelle"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis-clavier"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Recherchez des raccourcis"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis-clavier"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Rechercher des raccourcis"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personnaliser"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Terminé"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fournies par des applis"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Affichage"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Inconnu"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Réinitialiser les tuiles"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Réinitialiser les tuiles à leur ordre et à leur taille par défaut?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Réinitialiser toutes les tuiles?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Toutes les tuiles des paramètres rapides seront réinitialisées aux paramètres par défaut de l\'appareil."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 2be31b1..2da6399 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Enregistrer l\'écran ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Enregistrer une appli"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Enregistrer tout l\'écran"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Enregistrer tout l\'écran : %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'y affiche est enregistré. Faites donc attention aux éléments tels que les mots de passe, les détails du mode de paiement, les messages, les photos, et les contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Lorsque vous enregistrez une appli, tout ce qui est affiché ou lu dans celle-ci est enregistré. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Enregistrer l\'écran"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Vous enregistrez actuellement <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Arrêter l\'enregistrement"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Partage de l\'écran…"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Partage de contenu"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Arrêter le partage d\'écran ?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Arrêter le partage ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Vous partagez actuellement l\'intégralité de votre écran avec <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Vous partagez actuellement l\'intégralité de votre écran avec une appli"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Vous partagez actuellement <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Vous partagez actuellement une appli"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Vous partagez actuellement du contenu avec une appli"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Arrêter le partage"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Cast de l\'écran"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Arrêter de caster ?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets sur l\'écran de verrouillage"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"N\'importe qui peut consulter les widgets sur votre écran de verrouillage, même si votre tablette est verrouillée."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"désélectionner le widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuer la hauteur"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Augmenter la hauteur"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets pour l\'écran de verrouillage"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pour ouvrir une appli à l\'aide d\'un widget, vous devez confirmer qu\'il s\'agit bien de vous. N\'oubliez pas non plus que tout le monde peut voir vos widgets, même lorsque votre tablette est verrouillée. Certains d\'entre eux n\'ont pas été conçus pour l\'écran de verrouillage et les ajouter à cet endroit peut s\'avérer dangereux."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historique"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Paramètres de notification"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historique des notifications"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nouvelles notifications"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silencieux"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"La limitation des notifications est activée"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Les alertes et le volume de l\'appareil sont réduits automatiquement pendant 2 minutes maximum quand vous recevez trop de notifications à la fois."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverrouiller pour voir anciennes notifications"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Activé"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Suivi de la tête"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Appuyez pour changer le mode de la sonnerie"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"couper le son"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"activer le vibreur"</string>
@@ -860,8 +855,8 @@
<string name="group_system_go_back" msgid="2730322046244918816">"Retour"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"Accéder à l\'écran d\'accueil"</string>
<string name="group_system_overview_open_apps" msgid="5659958952937994104">"Afficher les applis récentes"</string>
- <string name="group_system_cycle_forward" msgid="5478663965957647805">"Avancer dans les applications récentes"</string>
- <string name="group_system_cycle_back" msgid="8194102916946802902">"Revenir sur les applications récentes"</string>
+ <string name="group_system_cycle_forward" msgid="5478663965957647805">"Faire défiler les applications récentes"</string>
+ <string name="group_system_cycle_back" msgid="8194102916946802902">"Faire défiler les applications récentes à l\'envers"</string>
<string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ouvrir la liste d\'applications"</string>
<string name="group_system_access_system_settings" msgid="8731721963449070017">"Ouvrir les paramètres"</string>
<string name="group_system_access_google_assistant" msgid="7210074957915968110">"Ouvrir l\'Assistant"</string>
@@ -871,7 +866,7 @@
<string name="system_multitasking_rhs" msgid="8714224917276297810">"Utiliser l\'écran partagé avec l\'appli actuelle sur la droite"</string>
<string name="system_multitasking_lhs" msgid="8402954791206308783">"Utiliser l\'écran partagé avec l\'appli actuelle sur la gauche"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Passer de l\'écran partagé au plein écran"</string>
- <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passez à l\'appli à droite ou en dessous avec l\'écran partagé"</string>
+ <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'écran partagé"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passez à l\'appli à gauche ou au-dessus avec l\'écran partagé"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"En mode écran partagé : Remplacer une appli par une autre"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Saisie"</string>
@@ -1415,21 +1410,18 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Appli actuelle"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis clavier"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Raccourcis de recherche"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis clavier"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Rechercher des raccourcis"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personnaliser"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"OK"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Paramètres du clavier"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide du clavier"</string>
- <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Découvrir les raccourcis clavier"</string>
+ <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Apprenez à utiliser les raccourcis clavier"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviguer à l\'aide de votre pavé tactile"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Découvrir les gestes au pavé tactile"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Naviguer à l\'aide de votre clavier et de votre pavé tactile"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fournis par des applis"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Écran"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Inconnu"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Réinitialiser les blocs"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Rétablir l\'ordre et la taille d\'origine des blocs ?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Réinitialiser tous les blocs ?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Tous les blocs \"Réglages rapides\" seront réinitialisés aux paramètres d\'origine de l\'appareil"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 2bd0b30..e012725 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Queres gravar a túa pantalla?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar unha aplicación"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar pantalla completa"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gravar pantalla completa: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cando gravas a pantalla completa, recóllese todo o que se mostra nela. Recomendámosche que teñas coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como co contido de audio e de vídeo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cando gravas unha aplicación, recóllese todo o que se mostra ou reproduce nela. Recomendámosche que teñas coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como co contido de audio e de vídeo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar pantalla"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Estás gravando <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Deter gravación"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartindo pantalla"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Compartindo contido"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Queres deixar de compartir a pantalla?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Queres deixar de compartir o contido?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Estás compartindo toda a pantalla con <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Estás compartindo toda a pantalla cunha aplicación"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Estás compartindo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Estás compartindo unha aplicación"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Estás compartindo contido cunha aplicación"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Deixar de compartir"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Emitindo pantalla"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Queres deter a emisión?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets da pantalla de bloqueo"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Calquera pode ver os widgets na pantalla de bloqueo, mesmo coa tableta bloqueada"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"anular a selección do widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reducir a altura"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar a altura"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da pantalla de bloqueo"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir unha aplicación mediante un widget, tes que verificar a túa identidade. Ten en conta que pode velos calquera persoa, mesmo coa tableta bloqueada. Pode ser que algúns widgets non estean pensados para a túa pantalla de bloqueo, polo que talvez non sexa seguro engadilos aquí."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Eliminar todo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Xestionar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Configuración de notificacións"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historial de notificacións"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Notificacións novas"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silenciadas"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacións"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Non hai notificacións"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Non hai notificacións novas"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"A opción Amainar notificacións está activada"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Ao recibir moitas notificacións, o volume e as alertas redúcense automaticamente ata dous minutos."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver máis notificacións"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixado"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seguimento da cabeza"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar o modo de timbre"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activar o son"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -826,7 +821,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Re Páx"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Av Páx"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Supr"</string>
- <string name="keyboard_key_esc" msgid="6230365950511411322">"Escape"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Inicio"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Fin"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Inserir"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicación actual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atallos de teclado"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atallos de busca"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar os atallos de teclado"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Busca atallos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Non hai resultados de busca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona de contraer"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Feito"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icona de despregar"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Provenientes de aplicacións"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Visualización"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Categoría descoñecida"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Restablecer as tarxetas"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Queres restablecer as tarxetas ao seu tamaño e orde orixinais?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Queres restablecer todos os atallos?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Restablecerase a configuración orixinal do dispositivo para todos os atallos de Configuración rápida"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index becca8f..898ca38 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"તમારી સ્ક્રીન રેકોર્ડ કરીએ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"એક ઍપ રેકોર્ડ કરો"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"પૂર્ણ સ્ક્રીન રેકોર્ડ કરો"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"પૂરી સ્ક્રીન રેકોર્ડ કરો: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"જ્યારે તમે તમારી પૂર્ણ સ્ક્રીન રેકોર્ડ કરી રહ્યાં હો, ત્યારે તમારી સ્ક્રીન પર બતાવવામાં આવતી હોય તેવી બધી વસ્તુ રેકોર્ડ કરવામાં આવે છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"જ્યારે તમે કોઈ ઍપને રેકોર્ડ કરી રહ્યાં હો, ત્યારે એ ઍપમાં બતાવવામાં કે ચલાવવામાં આવતી હોય તેવી બધી વસ્તુ રેકોર્ડ કરવામાં આવે છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"સ્ક્રીન રેકોર્ડ કરો"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"તમે હાલમાં <xliff:g id="APP_NAME">%1$s</xliff:g> રેકોર્ડ કરી રહ્યાં છો"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"રેકોર્ડિંગ રોકો"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"સ્ક્રીન શેર કરી રહ્યાં છીએ"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"કન્ટેન્ટ શેર કરી રહ્યાં છીએ"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"સ્ક્રીન શેર કરવાનું રોકીએ?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"શેર કરવાનું રોકીએ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"તમે હાલમાં <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> વડે તમારી પૂર્ણ સ્ક્રીન શેર કરી રહ્યાં છો"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"તમે હાલમાં ઍપ વડે તમારી પૂર્ણ સ્ક્રીન શેર કરી રહ્યાં છો"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"તમે હાલમાં <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> શેર કરી રહ્યાં છો"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"તમે હાલમાં ઍપ શેર કરી રહ્યાં છો"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"તમે હાલમાં ઍપ સાથે શેર કરી રહ્યાં છો"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"શેર કરવાનું રોકો"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"સ્ક્રીન કાસ્ટ કરી રહ્યાં છીએ"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"કાસ્ટ કરવાનું રોકીએ?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"લૉક સ્ક્રીન વિજેટ"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"તમારું ટૅબ્લેટ લૉક કરેલું હોય તો પણ કોઈપણ તમારી લૉક સ્ક્રીન પર વિજેટ જોઈ શકે છે."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"વિજેટ નાપસંદ કરો"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ઊંચાઈ ઘટાડો"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ઊંચાઈ વધારો"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"લૉક સ્ક્રીન વિજેટ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"વિજેટનો ઉપયોગ કરીને ઍપ ખોલવા માટે, તમારે એ ચકાસણી કરવાની જરૂર રહેશે કે આ તમે જ છો. તે ઉપરાંત, ધ્યાનમાં રાખો કે તમારું ટૅબ્લેટ લૉક કરેલું હોય તો પણ કોઈપણ વ્યક્તિ તેમને જોઈ શકે છે. અમુક વિજેટ કદાચ તમારી લૉક સ્ક્રીન માટે બનાવવામાં આવ્યા ન હોઈ શકે છે અને તેમને અહીં ઉમેરવાનું અસલામત હોઈ શકે છે."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"સમજાઈ ગયું"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"હવે શરૂ કરો"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"કોઈ નોટિફિકેશન નથી"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"કોઈ નવું નોટિફિકેશન નથી"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"નોટિફિકેશન કૂલડાઉન ચાલુ છે"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"જ્યારે તમને એકસાથે ઘણા બધા નોટિફિકેશન મળે ત્યારે તમારા ડિવાઇસનું વૉલ્યૂમ અને અલર્ટ ઑટોમૅટિક રીતે 2 મિનિટ જેટલા સમય માટે ઘટાડવામાં આવે છે."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"બંધ કરો"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"જૂના નોટિફિકેશન જોવા માટે અનલૉક કરો"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ફિક્સ્ડ"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"હૅડ ટ્રૅકિંગ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"રિંગર મોડ બદલવા માટે ટૅપ કરો"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"મ્યૂટ કરો"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"અનમ્યૂટ કરો"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"વાઇબ્રેટ"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"હાલની ઍપ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ઍક્સેસિબિલિટી"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"કીબોર્ડ શૉર્ટકટ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"કીબોર્ડ શૉર્ટકટને કસ્ટમાઇઝ કરો"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"શૉર્ટકટ શોધો"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"કોઈ શોધ પરિણામો નથી"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\'નાનું કરો\'નું આઇકન"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"કસ્ટમાઇઝ કરો"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"થઈ ગયું"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\'મોટું કરો\'નું આઇકન"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"અથવા"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ઑબ્જેક્ટ ખેંચવાનું હૅન્ડલ"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ઍપ દ્વારા પ્રદાન કરવામાં આવેલી"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ડિસ્પ્લે"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"અજાણ"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"ટાઇલને રીસેટ કરો"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"ટાઇલને તેમના મૂળ ક્રમ અને કદમાં રીસેટ કરીએ?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"તમામ ટાઇલ રીસેટ કરીએ?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"તમામ ઝડપી સેટિંગ ટાઇલને ડિવાઇસના ઑરિજિનલ સેટિંગ પર રીસેટ કરવામાં આવશે"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index a6fc05e..380d394b 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"क्या आपको स्क्रीन रिकॉर्ड करनी है?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक ऐप्लिकेशन की रिकॉर्डिंग करें"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूरी स्क्रीन रिकॉर्ड करें"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"पूरी स्क्रीन रिकॉर्ड करें: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"पूरी स्क्रीन रिकॉर्ड करते समय, स्क्रीन पर दिखने वाली हर चीज़ रिकॉर्ड की जाती है. इसलिए पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, डिवाइस पर चल रहे ऑडियो और वीडियो, और फ़ोटो जैसी चीज़ों को लेकर सावधानी बरतें."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"किसी ऐप्लिकेशन को रिकॉर्ड करने के दौरान, उस पर दिख रहा कॉन्टेंट या चल रहा मीडिया दूसरी स्क्रीन पर भी रिकॉर्ड होता है. इसलिए, रिकॉर्ड करते समय पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, ऑडियो, और वीडियो को लेकर सावधानी बरतें."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रिकॉर्ड करें"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"फ़िलहाल, <xliff:g id="APP_NAME">%1$s</xliff:g> की रिकॉर्डिंग की जा रही है"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"रिकॉर्ड करना बंद करें"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रीन शेयर की जा रही है"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"कॉन्टेंट शेयर करें"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"स्क्रीन शेयर करना बंद करना है?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"क्या आपको शेयर करने की प्रोसेस बंद करनी है?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"फ़िलहाल, <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> पर पूरी स्क्रीन शेयर की जा रही है"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"फ़िलहाल, किसी ऐप्लिकेशन पर पूरी स्क्रीन शेयर की जा रही है"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"फ़िलहाल, <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> शेयर किया जा रहा है"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"फ़िलहाल, कोई ऐप्लिकेशन शेयर किया जा रहा है"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"फ़िलहाल, ऐप्लिकेशन के साथ कुछ शेयर किया जा रहा है"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"शेयर करना बंद करें"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"स्क्रीन कास्ट की जा रही है"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"कास्ट करना बंद करना है?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"लॉक स्क्रीन विजेट"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"टैबलेट लॉक होने के बावजूद, कोई भी व्यक्ति इसकी लॉक स्क्रीन पर विजेट देख सकता है."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"विजेट से चुने हुए का निशान हटाएं"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ऊंचाई घटाएं"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ऊंचाई बढ़ाएं"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लॉक स्क्रीन विजेट"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"किसी विजेट से कोई ऐप्लिकेशन खोलने के लिए, आपको अपनी पहचान की पुष्टि करनी होगी. ध्यान रखें कि आपके टैबलेट के लॉक होने पर भी, कोई व्यक्ति विजेट देख सकता है. ऐसा हो सकता है कि कुछ विजेट, लॉक स्क्रीन पर दिखाने के लिए न बने हों. इन्हें लॉक स्क्रीन पर जोड़ना असुरक्षित हो सकता है."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ठीक है"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"सभी हटाएं"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"मैनेज करें"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"सूचना सेटिंग"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"सूचनाओं का इतिहास"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"नई सूचनाएं"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"साइलेंट मोड में मिली सूचनाएं"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाएं"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"अभी शुरू करें"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"कोई सूचना नहीं है"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"कोई नई सूचना नहीं है"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"लगातार सूचनाएं आने पर आवाज़ कम करने की सेटिंग चालू है"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"एक साथ कई सूचनाएं मिलने पर, डिवाइस में सूचनाओं से होने वाली आवाज़ और सूचनाएं, दो मिनट के लिए अपने-आप कम हो जाएंगी."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"बंद करें"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"पुरानी सूचाएं देखने के लिए अनलॉक करें"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"चालू है"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्रैकिंग चालू है"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलने के लिए टैप करें"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करें"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्यूट करें"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"वाइब्रेशन की सुविधा चालू करें"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"मौजूदा ऐप्लिकेशन"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"सर्च शॉर्टकट"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट को पसंद के मुताबिक बनाएं"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शॉर्टकट खोजें"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"खोज का कोई नतीजा नहीं मिला"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"छोटा करने का आइकॉन"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"पसंद के मुताबिक बनाएं"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"हो गया"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"बड़ा करने का आइकॉन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"या"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"खींचकर छोड़ने वाला हैंडल"</string>
@@ -1469,9 +1461,9 @@
<string name="back_edu_notification_title" msgid="5624780717751357278">"वापस जाने के लिए, अपने डिवाइस के टचपैड का इस्तेमाल करें"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"तीन उंगलियों से बाईं या दाईं ओर स्वाइप करें. ज़्यादा जेस्चर के बारे में जानने के लिए टैप करें."</string>
<string name="home_edu_notification_title" msgid="6097902076909654045">"होम पर जाने के लिए, अपने डिवाइस के टचपैड का इस्तेमाल करें"</string>
- <string name="home_edu_notification_content" msgid="6631697734535766588">"तीन उंगलियों से ऊपर की ओर स्वाइप करें. जेस्चर के बारे में ज़्यादा जानने के लिए टैप करें."</string>
+ <string name="home_edu_notification_content" msgid="6631697734535766588">"तीन उंगलियों से ऊपर की ओर स्वाइप करें. ज़्यादा जेस्चर के बारे में जानने के लिए टैप करें."</string>
<string name="overview_edu_notification_title" msgid="1265824157319562406">"हाल ही में इस्तेमाल हुए ऐप्लिकेशन देखने के लिए, अपने डिवाइस के टचपैड का इस्तेमाल करें"</string>
- <string name="overview_edu_notification_content" msgid="3578204677648432500">"तीन उंगलियों से ऊपर की ओर स्वाइप करें और दबाकर रखें. जेस्चर की ज़्यादा जानकारी पाने के लिए टैप करें."</string>
+ <string name="overview_edu_notification_content" msgid="3578204677648432500">"तीन उंगलियों से ऊपर की ओर स्वाइप करके दबाकर रखें. ज़्यादा जेस्चर के बारे में जानने के लिए टैप करें."</string>
<string name="all_apps_edu_notification_title" msgid="372262997265569063">"सभी ऐप्लिकेशन देखने के लिए, कीबोर्ड का इस्तेमाल करें"</string>
<string name="all_apps_edu_notification_content" msgid="3255070575694025585">"किसी भी समय ऐक्शन बटन दबाएं. हाथ के जेस्चर के बारे में ज़्यादा जानने के लिए टैप करें."</string>
<string name="accessibility_deprecate_extra_dim_dialog_title" msgid="910988771011857460">"स्क्रीन की रोशनी को सामान्य लेवल से और कम करने की सुविधा, अब ब्राइटनेस स्लाइडर का हिस्सा है"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ऐप्लिकेशन से मिली जानकारी"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"डिसप्ले"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"कोई जानकारी नहीं है"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"टाइल रीसेट करें"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"क्या आपको टाइल, उनके ओरिजनल क्रम और साइज़ पर रीसेट करने हैं?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"क्या सभी टाइल रीसेट करनी हैं?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"क्विक सेटिंग टाइल, डिवाइस की ओरिजनल सेटिंग पर रीसेट हो जाएंगी"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index cb7a193..0a7d82b 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Želite li snimati zaslon?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimanje jedne aplikacije"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimanje cijelog zaslona"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snimanje cijelog zaslona: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kad snimate cijeli zaslon, snima se sve što se prikazuje na zaslonu. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kad snimate aplikaciju, snima se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimanje zaslona"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Trenutačno snimate aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zaustavi snimanje"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Dijeljenje zaslona"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Dijeljenje sadržaja"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Želite li zaustaviti dijeljenje zaslona?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Želite li zaustaviti dijeljenje?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Trenutačno dijelite cijeli zaslon s aplikacijom <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Trenutačno dijelite cijeli zaslon s aplikacijom"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Trenutačno dijelite aplikaciju <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Trenutačno dijelite aplikaciju"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Trenutačno dijelite sadržaj s aplikacijom"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Zaustavi dijeljenje"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Emitiranje zaslona"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Želite li prestati emitirati?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgeti zaključanog zaslona"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Svi vide widgete na vašem zaključanom zaslonu, čak i ako je tablet zaključan."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"poništavanje odabira widgeta"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Smanjenje visine"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Povećanje visine"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgeti na zaključanom zaslonu"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju pomoću widgeta, trebate potvrditi da ste to vi. Također napominjemo da ih svatko može vidjeti, čak i ako je vaš tablet zaključan. Neki widgeti možda nisu namijenjeni za zaključani zaslon, pa ih možda nije sigurno dodati ovdje."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Shvaćam"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Izbriši sve"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Povijest"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Postavke obavijesti"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Povijest obavijesti"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Novo"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Bešumno"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavijesti"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Pokreni"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obavijesti"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obavijesti"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Stišavanje obavijesti je uključeno"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Glasnoća/upozorenja uređaja automatski se stišavaju do 2 min kad primite previše obavijesti odjednom"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte za starije obavijesti"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksno"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Praćenje glave"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promijenili način softvera zvona"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključivanje zvuka"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključivanje zvuka"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutačna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tipkovni prečaci"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodba tipkovnih prečaca"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečaci za pretraživanje"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za sažimanje"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za povlačenje"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Pružaju aplikacije"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Prikaz"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nepoznato"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Vraćanje kartica na zadano"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Želite li vratiti kartice na zadani redoslijed i veličine?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Želite li poništiti sve pločice?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Sve pločice Brze postavke vratit će se na izvorne postavke uređaja"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b09947f..7be9656 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rögzíti a képernyőt?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Egyetlen alkalmazás rögzítése"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Teljes képernyő rögzítése"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Teljes képernyő rögzítése: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"A teljes képernyő rögzítése esetén a képernyőn megjelenő minden tartalom rögzítésre kerül. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Alkalmazás rögzítésekor az adott alkalmazásban megjelenített vagy lejátszott minden tartalom rögzítésre kerül. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Képernyő rögzítése"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Jelenleg a következőről készít felvételt: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Felvétel leállítása"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Képernyő megosztása…"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Tartalom megosztása…"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Leállítja a képernyőmegosztást?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Leállítja a megosztást?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Jelenleg megosztja a teljes képernyőt a következővel: <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Jelenleg megosztja a teljes képernyőt egy alkalmazással"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Jelenleg megosztja a következőt: <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Jelenleg megoszt egy alkalmazást"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Jelenleg megoszt valamit egy alkalmazással"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Megosztás leállítása"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Képernyőtartalom átküldése…"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Leállítja az átküldést?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"A lezárási képernyő moduljai"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Bárki megtekintheti a modulokat a lezárási képernyőjén, még ha a táblagépe zárolva is van."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"modul kijelölésének megszüntetése"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Magasság csökkentése"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Magasság növelése"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"A lezárási képernyő moduljai"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ha modul használatával szeretne megnyitni egy alkalmazást, igazolnia kell a személyazonosságát. Ne felejtse továbbá, hogy bárki megtekintheti a modulokat, még akkor is, amikor zárolva van a táblagép. Előfordulhat, hogy bizonyos modulokat nem a lezárási képernyőn való használatra terveztek, ezért nem biztonságos a hozzáadásuk."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Értem"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Az összes törlése"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Kezelés"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Előzmények"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Értesítési beállítások"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Értesítéselőzmények"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Új"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Néma"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Értesítések"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nincs értesítés"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nincsenek új értesítések"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Értesítések befagyasztása bekapcsolva"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Az eszköz hangerejét és értesítéseit a rendszer automatikusan legfeljebb két percig csökkenti, ha egyszerre túl sok értesítést kap."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Igen"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"A régebbiek feloldás után láthatók"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Rögzített"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Fejkövetés"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Koppintson a csengés módjának módosításához"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"némítás"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"némítás feloldása"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"rezgés"</string>
@@ -1411,19 +1406,16 @@
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Legutóbbi alkalmazások"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Osztott képernyő"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Bevitel"</string>
- <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Alkalmazás-parancsikonok"</string>
+ <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Alkalmazásikonok"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Jelenlegi alkalmazás"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kisegítő lehetőségek"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Billentyűparancsok"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"A billentyűparancsok személyre szabása"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Billentyűparancsok keresése"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nincsenek keresési találatok"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Összecsukás ikon"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Személyre szabás"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Kész"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kibontás ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vagy"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Fogópont"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Alkalmazás által biztosított"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Kijelző"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ismeretlen"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Mozaikok visszaállítása"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Visszaállítja a mozaikok eredeti sorrendjét és méretét?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Visszaállítja az összes mozaikot?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Az összes Gyorsbeállítások mozaik visszaáll az eszköz eredeti beállításaira"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 174b526..c7a8a0e 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Տեսագրե՞լ ձեր էկրանը"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Տեսագրել մեկ հավելված"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Տեսագրել ամբողջ էկրանը"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Տեսագրել ամբողջ էկրանը՝ %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Երբ դուք տեսագրում եք ամբողջ էկրանը, էկրանին ցուցադրվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Երբ դուք որևէ հավելված եք տեսագրում, հավելվածում ցուցադրվող կամ նվագարկվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Տեսագրել էկրանը"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Դուք ներկայումս տեսագրում եք <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Կանգնեցնել տեսագրումը"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Միացված է էկրանի ցուցադրումը"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Բովանդակության փոխանցում"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Դադարեցնե՞լ էկրանի ցուցադրումը"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Չեղարկե՞լ փոխանցումը"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Դուք ներկայումս կիսվում եք ձեր էկրանով <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> հավելվածի հետ"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Դուք ներկայումս կիսվում եք ձեր էկրանով հավելվածի հետ"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Դուք ներկայումս կիսվում եք <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> հավելվածով"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Դուք ներկայումս կիսվում եք հավելվածով"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Դուք ներկայումս բովանդակություն եք փոխանցում այս հավելվածին"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Դադարեցնել էկրանի ցուցադրումը"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Էկրանի հեռարձակում"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Կանգնեցնե՞լ հեռարձակումը"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Կողպէկրանի վիջեթներ"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Բոլորը կարող են դիտել ձեր կողպէկրանի վիջեթները, նույնիսկ եթե պլանշետը կողպված է"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"չեղարկել վիջեթի ընտրությունը"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Նվազեցնել բարձրությունը"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Ավելացնել բարձրությունը"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Կողպէկրանի վիջեթներ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Վիջեթի միջոցով հավելված բացելու համար դուք պետք է հաստատեք ձեր ինքնությունը։ Նաև նկատի ունեցեք, որ ցանկացած ոք կարող է դիտել վիջեթները, նույնիսկ երբ ձեր պլանշետը կողպված է։ Որոշ վիջեթներ կարող են նախատեսված չլինել ձեր կողպէկրանի համար, և այստեղ դրանց ավելացնելը կարող է վտանգավոր լինել։"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Եղավ"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Մաքրել բոլորը"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Կառավարել"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Պատմություն"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Ծանուցումների կարգավորումներ"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Ծանուցումների պատմություն"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Նոր"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Անձայն"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ծանուցումներ"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Սկսել հիմա"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ծանուցումներ չկան"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Նոր ծանուցումներ չկան"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Ծանուցումների ձայնի իջեցումը միացված է"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Սարքի և ծանուցումների ձայնն ավտոմատ իջեցվում է մինչև 2 րոպեով, երբ շատ ծանուցումներ եք ստանում։"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Անջատել"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ապակողպեք՝ տեսնելու հին ծանուցումները"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Ֆիքսված"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Գլխի շարժումների հետագծում"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Հպեք՝ զանգակի ռեժիմը փոխելու համար"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"անջատել ձայնը"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"միացնել ձայնը"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"միացնել թրթռոցը"</string>
@@ -815,7 +810,7 @@
<string name="keyboard_key_back" msgid="4185420465469481999">"Հետ"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"Բացատ"</string>
- <string name="keyboard_key_enter" msgid="8633362970109751646">"Մուտք"</string>
+ <string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Նվագարկում/դադար"</string>
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"Կանգնեցնել"</string>
@@ -860,14 +855,14 @@
<string name="group_system_go_back" msgid="2730322046244918816">"Հետ գնալ"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"Անցնել հիմնական էկրան"</string>
<string name="group_system_overview_open_apps" msgid="5659958952937994104">"Դիտել վերջին հավելվածները"</string>
- <string name="group_system_cycle_forward" msgid="5478663965957647805">"Առաջ անցնել վերջին հավելվածների միջով"</string>
- <string name="group_system_cycle_back" msgid="8194102916946802902">"Հետ անցնել վերջին հավելվածների միջով"</string>
+ <string name="group_system_cycle_forward" msgid="5478663965957647805">"Առաջ անցնել վերջին հավելվածներով"</string>
+ <string name="group_system_cycle_back" msgid="8194102916946802902">"Հետ անցնել վերջին հավելվածներով"</string>
<string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Բացել հավելվածների ցանկը"</string>
<string name="group_system_access_system_settings" msgid="8731721963449070017">"Բացել կարգավորումները"</string>
<string name="group_system_access_google_assistant" msgid="7210074957915968110">"Բացել Օգնականը"</string>
<string name="group_system_lock_screen" msgid="7391191300363416543">"Կողպէկրան"</string>
<string name="group_system_quick_memo" msgid="3764560265935722903">"Ստեղծել նշում"</string>
- <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Բազմախնդրություն"</string>
+ <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Բազմախնդրություն"</string>
<string name="system_multitasking_rhs" msgid="8714224917276297810">"Տրոհել էկրանը և տեղավորել այս հավելվածը աջում"</string>
<string name="system_multitasking_lhs" msgid="8402954791206308783">"Տրոհել էկրանը և տեղավորել այս հավելվածը ձախում"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Տրոհված էկրանից անցնել լիաէկրան ռեժիմ"</string>
@@ -1407,7 +1402,7 @@
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Համակարգ"</string>
<string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Համակարգի կառավարման տարրեր"</string>
<string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Համակարգային հավելվածներ"</string>
- <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Բազմախնդրություն"</string>
+ <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Բազմախնդրություն"</string>
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Վերջին օգտագործած հավելվածները"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Տրոհված էկրան"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ներածում"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Այս հավելվածը"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Հատուկ գործառույթներ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ստեղնային դյուրանցումներ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Կարգավորեք ստեղնային դյուրանցումներ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Դյուրանցումների որոնում"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Որոնման արդյունքներ չկան"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ծալել պատկերակը"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Կարգավորել"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Պատրաստ է"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ծավալել պատկերակը"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"կամ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Տեղափոխման նշիչ"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Տրամադրվել են հավելվածների կողմից"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Էկրան"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Անհայտ"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Սալիկների վերակայում"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Վերականգնե՞լ սալիկների սկզբնական դասավորությունն ու չափսերը"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Զրոյացնե՞լ բոլոր սալիկները"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Արագ կարգավորումների բոլոր սալիկները կզրոյացվեն սարքի սկզբնական կարգավորումների համաձայն։"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index e706b27..a8a6443 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rekam layar Anda?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rekam satu aplikasi"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rekam seluruh layar"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Rekam seluruh layar: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Saat Anda merekam seluruh layar, semua hal yang ditampilkan di layar akan direkam. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Jika Anda merekam aplikasi, semua hal yang ditampilkan atau diputar di aplikasi tersebut akan direkam. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rekam layar"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Anda sedang merekam <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Berhenti merekam"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Membagikan layar"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Membagikan konten"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Hentikan berbagi layar?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Berhenti berbagi?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Anda sedang berbagi seluruh layar dengan <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Anda sedang berbagi seluruh layar dengan aplikasi"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Anda sedang berbagi <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Anda sedang berbagi aplikasi"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Anda sedang berbagi dengan aplikasi"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Berhenti berbagi"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Mentransmisikan layar"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Hentikan transmisi?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widget layar kunci"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Siapa saja dapat melihat widget di layar kunci Anda, meskipun tablet terkunci."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"batalkan pilihan widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Kurangi tinggi"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Tambah tinggi"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget layar kunci"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka aplikasi menggunakan widget, Anda perlu memverifikasi diri Anda. Selain itu, harap ingat bahwa siapa saja dapat melihatnya, bahkan saat tablet Anda terkunci. Beberapa widget mungkin tidak dirancang untuk layar kunci Anda dan mungkin tidak aman untuk ditambahkan di sini."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Oke"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hapus semua"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Kelola"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histori"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Setelan notifikasi"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Histori notifikasi"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Baru"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Senyap"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikasi"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Tidak ada notifikasi"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Tidak ada notifikasi baru"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Pengurangan suara dan getaran notifikasi aktif"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Saat Anda menerima terlalu banyak notifikasi sekaligus, volume dan getaran perangkat akan otomatis dikurangi hingga selama 2 menit."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Nonaktifkan"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Buka kunci untuk melihat notifikasi lama"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Tetap"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pelacakan Gerak Kepala"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Ketuk untuk mengubah mode pendering"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Tanpa suara"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktifkan"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"getar"</string>
@@ -814,7 +809,7 @@
<string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
<string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
- <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
+ <string name="keyboard_key_space" msgid="6980847564173394012">"Spasi"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
@@ -1368,7 +1363,7 @@
<string name="call_from_work_profile_text" msgid="2856337395968118274">"Organisasi Anda hanya mengizinkan menelepon dari aplikasi kerja"</string>
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Beralih ke profil kerja"</string>
<string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instal aplikasi telepon kerja"</string>
- <string name="call_from_work_profile_close" msgid="5830072964434474143">"Batalkan"</string>
+ <string name="call_from_work_profile_close" msgid="5830072964434474143">"Batal"</string>
<string name="lock_screen_settings" msgid="6152703934761402399">"Sesuaikan layar kunci"</string>
<string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Buka kunci untuk menyesuaikan layar kunci"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi tidak tersedia"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplikasi Saat Ini"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aksesibilitas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan keyboard"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan penelusuran"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Menyesuaikan pintasan keyboard"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Telusuri pintasan"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tidak ada hasil penelusuran"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon ciutkan"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sesuaikan"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Selesai"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon luaskan"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handel geser"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Disediakan oleh aplikasi"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Tampilan"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tidak diketahui"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Reset kartu"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Reset kartu ke urutan dan ukuran default?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reset semua kartu?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Semua kartu Setelan Cepat akan direset ke setelan asli perangkat"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 26729106..66b156a 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Viltu taka upp skjáinn?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Taka upp eitt forrit"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Taka upp allan skjáinn"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Taka upp allan skjáinn: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Þegar þú tekur upp allan skjáinn verður allt sem er sýnilegt á skjánum tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Þegar þú tekur upp forrit verður allt sem er sýnilegt eða spilað í forritinu tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Taka upp skjá"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Þú ert að taka upp <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stöðva upptöku"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deilir skjá"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Deilir efni"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Hætta að deila skjá?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Hætta að deila?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Þú ert að deila öllum skjánum með <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Þú ert að deila öllum skjánum með forriti"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Þú ert að deila <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Þú ert að deila forriti"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Þú ert að deila með forriti"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Hætta að deila"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Varpar skjá"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Hætta að varpa?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Græjur á lásskjá"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Hver sem er getur séð græjur á lásskjánum þínum, jafnvel þótt spjaldtölvan sé læst."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"afturkalla val á græju"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Lækka"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Hækka"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Græjur fyrir lásskjá"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Þú þarft að staðfesta að þetta sért þú til að geta opnað forrit með græju. Hafðu einnig í huga að hver sem er getur skoðað þær, jafnvel þótt spjaldtölvan sé læst. Sumar græjur eru hugsanlega ekki ætlaðar fyrir lásskjá og því gæti verið óöruggt að bæta þeim við hér."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ég skil"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Byrja núna"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Engar tilkynningar"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Engar nýjar tilkynningar"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Kveikt er á tilkynningadempun"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Lækkað er sjálfkrafa í hljóðstyrk og áminningum tækisins í allt að tvær mínútur þegar þú færð of margar tilkynningar í einu."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slökkva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Taktu úr lás til að sjá eldri tilkynningar"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fast"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rakning höfuðhreyfinga"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Ýta til að skipta um hringjarastillingu"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"þagga"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"hætta að þagga"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"titringur"</string>
@@ -1408,20 +1405,17 @@
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Fjölvinnsla"</string>
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nýleg forrit"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Skjáskipting"</string>
- <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Inntak"</string>
+ <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Innsláttur"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Flýtileiðir forrita"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Núverandi forrit"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aðgengi"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Flýtilyklar"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Leitarflýtileiðir"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sérsníddu flýtilykla"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Leita að flýtileiðum"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Engar leitarniðurstöður"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Minnka tákn"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sérsníða"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Lokið"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Stækka tákn"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eða"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dragkló"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Frá forritum"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Skjár"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Óþekkt"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Endurstilla flísar"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Endurstilla flísar í upphaflega röð og stærð?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Endurstilla alla reiti?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Allir flýtistillingareitir munu endurstillast á upprunalegar stillingar tækisins"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index fd56c5b..36d564b 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Registrare lo schermo?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Registra un\'app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Registra l\'intero schermo"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Registra l\'intero schermo: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando registri l\'intero schermo, tutto ciò che viene mostrato sullo schermo viene registrato. Presta quindi attenzione a password, dati di pagamento, messaggi, foto, audio e video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando registri un\'app, tutto ciò che viene mostrato o riprodotto al suo interno viene registrato. Presta quindi attenzione a password, dati di pagamento, messaggi, foto, audio e video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Registra lo schermo"</string>
@@ -578,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Cancella tutto"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestisci"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Cronologia"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Impostazioni di notifica"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Cronologia delle notifiche"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nuove"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Notifiche silenziose"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifiche"</string>
@@ -592,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nessuna notifica"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nessuna nuova notifica"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Attenuazione delle notifiche attivata"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volume e avvisi vengono ridotti automaticamente per un massimo di 2 minuti quando ricevi troppe notifiche contemporaneamente."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Disattiva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Sblocca per vedere le notifiche meno recenti"</string>
@@ -700,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fisso"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rilev. movim. testa"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tocca per cambiare la modalità della suoneria"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenzia"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"riattiva l\'audio"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrazione"</string>
@@ -1410,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App corrente"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilità"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Scorciatoie da tastiera"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizza scorciatoie da tastiera"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Scorciatoie per la ricerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nessun risultato di ricerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona Comprimi"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizza"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Fine"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icona Espandi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oppure"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Punto di trascinamento"</string>
@@ -1480,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Forniti dalle app"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Sconosciuti"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Reimposta riquadri"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Ripristinare l\'ordine e le dimensioni originali dei riquadri?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Reimpostare tutti i riquadri?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Tutti i riquadri Impostazioni rapide verranno reimpostati sulle impostazioni originali del dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 384c680..6cf84e4 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"להקליט את המסך?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"הקלטה של אפליקציה אחת"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"הקלטה של כל המסך"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"הקלטת התוכן של כל המסך: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"כשמקליטים את כל המסך, כל מה שמופיע במסך מוקלט. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"כשמקליטים אפליקציה, כל מה שרואים או מפעילים בה מוקלט. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"הקלטת המסך"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"מתבצעת כרגע הקלטה של <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"הפסקת ההקלטה"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"שיתוף המסך מתבצע"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"התוכן משותף"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"להפסיק את שיתוף המסך?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"להפסיק את השיתוף?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"מתבצע כרגע שיתוף של כל המסך שלך עם <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"מתבצע כרגע שיתוף של כל המסך שלך עם אפליקציה"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"מתבצע כרגע שיתוף של <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"מתבצע כרגע שיתוף של אפליקציה"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"מתבצע כרגע שיתוף עם אפליקציה"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"הפסקת השיתוף"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"הפעלת Cast של המסך מתבצעת"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"להפסיק את פעולת ה-Cast?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ווידג\'טים במסך הנעילה"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"כולם יכולים לראות את הווידג\'טים במסך הנעילה שלך, גם אם הטאבלט נעול."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ביטול הבחירה בווידג\'ט"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"הקטנת הגובה"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"הגדלת הגובה"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ווידג\'טים במסך הנעילה"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"כדי לפתוח אפליקציה באמצעות ווידג\'ט, עליך לאמת את זהותך. בנוסף, כדאי לזכור שכל אחד יכול לראות את הווידג\'טים גם כשהטאבלט שלך נעול. יכול להיות שחלק מהווידג\'טים לא נועדו למסך הנעילה ושלא בטוח להוסיף אותם לכאן."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"הבנתי"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"אין התראות"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"אין התראות חדשות"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"הפוגת התראות מופעלת"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"עוצמת הקול וההתראות במכשיר מופחתות אוטומטית למשך עד 2 דקות כשמתקבלות יותר מדי התראות בבת אחת."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"השבתה"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"יש לבטל את הנעילה כדי לראות התראות ישנות"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"מצב סטטי"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"מעקב אחר תנועות הראש"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"יש להקיש כדי לשנות את מצב תוכנת הצלצול"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"השתקה"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ביטול ההשתקה"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"רטט"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"האפליקציה הנוכחית"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"נגישות"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"מקשי קיצור"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"התאמה אישית של מקשי הקיצור"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"קיצורי דרך לחיפוש"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"אין תוצאות חיפוש"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"סמל הכיווץ"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"התאמה אישית"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"סיום"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"סמל ההרחבה"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"או"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"נקודת האחיזה לגרירה"</string>
@@ -1459,7 +1453,7 @@
<string name="volume_undo_action" msgid="5815519725211877114">"ביטול"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"כדי לחזור אחורה, מחליקים שמאלה או ימינה עם שלוש אצבעות על לוח המגע."</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"כדי לעבור למסך הבית, מחליקים למעלה עם שלוש אצבעות על לוח המגע"</string>
- <string name="overview_edu_toast_content" msgid="5797030644017804518">"כדי לראות את האפליקציות האחרונות, מחליקים למעלה עם שלוש אצבעות על לוח המגע ולוחצים לחיצה ארוכה"</string>
+ <string name="overview_edu_toast_content" msgid="5797030644017804518">"כדי לראות את האפליקציות האחרונות, מחליקים למעלה לוחצים לחיצה ארוכה עם שלוש אצבעות על לוח המגע"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"כדי לראות את כל האפליקציות, מקישים על מקש הפעולה במקלדת"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"מצונזר"</string>
<string name="redacted_notification_single_line_text" msgid="8684166405005242945">"צריך לבטל את הנעילה כדי לראות"</string>
@@ -1467,9 +1461,9 @@
<string name="back_edu_notification_title" msgid="5624780717751357278">"אפשר להשתמש בלוח המגע כדי לחזור אחורה"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"מחליקים ימינה או שמאלה עם שלוש אצבעות. ניתן להקיש כדי לקבל מידע נוסף על התנועות."</string>
<string name="home_edu_notification_title" msgid="6097902076909654045">"איך להשתמש בלוח המגע כדי לעבור למסך הבית"</string>
- <string name="home_edu_notification_content" msgid="6631697734535766588">"מחליקים למעלה עם שלוש אצבעות. ניתן להקיש כדי לקבל מידע נוסף על התנועות."</string>
+ <string name="home_edu_notification_content" msgid="6631697734535766588">"מחליקים למעלה עם שלוש אצבעות. אפשר להקיש כדי לקבל מידע נוסף על התנועות."</string>
<string name="overview_edu_notification_title" msgid="1265824157319562406">"איך להשתמש בלוח המגע כדי לראות את האפליקציות האחרונות"</string>
- <string name="overview_edu_notification_content" msgid="3578204677648432500">"מחליקים למעלה ולוחצים לחיצה ארוכה עם שלוש אצבעות. ניתן להקיש כדי לקבל מידע נוסף על התנועות."</string>
+ <string name="overview_edu_notification_content" msgid="3578204677648432500">"מחליקים למעלה ולוחצים לחיצה ארוכה עם שלוש אצבעות. אפשר להקיש כדי לקבל מידע נוסף על התנועות."</string>
<string name="all_apps_edu_notification_title" msgid="372262997265569063">"איך להשתמש במקלדת כדי לראות את כל האפליקציות"</string>
<string name="all_apps_edu_notification_content" msgid="3255070575694025585">"בכל שלב אפשר ללחוץ על מקש הפעולה. ניתן להקיש כדי לקבל מידע נוסף על התנועות."</string>
<string name="accessibility_deprecate_extra_dim_dialog_title" msgid="910988771011857460">"התכונה \'מעומעם במיוחד\' נוספה לפס ההזזה לבהירות"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"מסופקים על ידי אפליקציות"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"מסך"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"לא ידוע"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"איפוס המשבצות"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"לאפס את המשבצות לסדר ולגודל המקורי שלהן?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"לאפס את כל הלחצנים?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"כל הלחצנים ב\'הגדרות מהירות\' יאופסו להגדרות המקוריות של המכשיר"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index a0a3b2b..0793da9 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"画面を録画しますか?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"1 つのアプリを録画"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"画面全体を録画"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"画面全体を録画: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"画面全体を録画すると、画面に表示されるものがすべて録画されます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"アプリを録画すると、そのアプリで表示または再生される内容がすべて録画されます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"画面を録画"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"現在、<xliff:g id="APP_NAME">%1$s</xliff:g>を録画しています"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"録画を停止"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"画面を共有しています"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"コンテンツの共有"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"画面の共有を停止しますか?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"共有を停止しますか?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"現在、画面全体を<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>と共有しています"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"現在、画面全体をアプリと共有しています"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"現在、<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>を共有しています"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"現在、アプリを共有しています"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"現在、アプリと共有しています"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"共有を停止"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"画面をキャストしています"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"キャストを停止しますか?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ロック画面ウィジェット"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"タブレットがロックされていても、ロック画面のウィジェットは誰でも確認できます。"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ウィジェットの選択を解除する"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"高さを低くする"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"高さを高くする"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ロック画面ウィジェット"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ウィジェットを使用してアプリを起動するには、本人確認が必要です。タブレットがロックされた状態でも他のユーザーにウィジェットが表示されますので、注意してください。一部のウィジェットについてはロック画面での使用を想定していないため、ロック画面への追加は危険な場合があります。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"今すぐ開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"通知はありません"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"新しい通知はありません"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"通知のクールダウンが ON になっています"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"一度に多くの通知が届いた場合に、最長 2 分間自動的にデバイスの音量が小さくなりアラートも減ります。"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"OFF にする"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ロック解除して以前の通知を表示"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"固定"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ヘッド トラッキング"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"タップすると、着信音のモードを変更できます"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ミュート"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ミュートを解除"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"バイブレーション"</string>
@@ -812,7 +809,7 @@
<string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
<string name="keyboard_key_back" msgid="4185420465469481999">"戻る"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
- <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
+ <string name="keyboard_key_space" msgid="6980847564173394012">"スペース"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"再生 / 一時停止"</string>
@@ -875,7 +872,7 @@
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"入力"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"次の言語に切り替える"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"前の言語に切り替える"</string>
- <string name="input_access_emoji" msgid="8105642858900406351">"絵文字にアクセス"</string>
+ <string name="input_access_emoji" msgid="8105642858900406351">"絵文字にアクセスする"</string>
<string name="input_access_voice_typing" msgid="7291201476395326141">"音声入力にアクセス"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"アプリ"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"アシスタント"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"現在のアプリ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ユーザー補助"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"キーボード ショートカット"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"キーボード ショートカットをカスタマイズする"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"検索ショートカット"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"検索結果がありません"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"閉じるアイコン"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"カスタマイズ"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完了"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"開くアイコン"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"または"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ドラッグ ハンドル"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"アプリから提供"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ディスプレイ"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"タイルのリセット"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"タイルを元の順序とサイズにリセットしますか?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"すべてのタイルをリセットしますか?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"すべてのクイック設定タイルがデバイスの元の設定にリセットされます"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 471957e..8b513ff 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"გსურთ თქვენი ეკრანის ჩაწერა?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ერთი აპის ჩაწერა"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"მთლიანი ეკრანის ჩაწერა"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"მთლიანი ეკრანის ჩაწერა: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"მთლიანი ეკრანის ჩაწერისას ჩაიწერება ყველაფერი, რაც თქვენს ეკრანზე გამოჩნდება. ამიტომ სიფრთხილე გამოიჩინეთ ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"აპის ჩაწერისას ჩაიწერება ყველაფერი, რაც ამ აპში გამოჩნდება ან დაიკვრება. ამიტომ სიფრთხილე გამოიჩინეთ ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ეკრანის ჩაწერა"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"თქვენ ამჟამად იწერთ <xliff:g id="APP_NAME">%1$s</xliff:g>-ს"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ჩაწერის შეწყვეტა"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"მიმდინარეობს ეკრანის გაზიარება"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"კონტენტის გაზიარება"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"გსურთ ეკრანის გაზიარების შეწყვეტა?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"შეწყდეს გაზიარება?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"თქვენ ამჟამად უზიარებთ თქვენს მთლიან ეკრანს <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>-ს"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"თქვენ ამჟამად უზიარებთ თქვენს მთლიან ეკრანს აპს"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"თქვენ ამჟამად აზიარებთ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>-ს"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"თქვენ ამჟამად აზიარებთ აპს"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"თქვენ ამჟამად აზიარებთ აპთან"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"გაზიარების შეწყვეტა"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"მიმდინარეობს ეკრანის ტრანსლირება"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"გსურთ ტრანსლირების შეწყვეტა?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ჩაკეტილი ეკრანის ვიჯეტები"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"ნებისმიერს შეუძლია თქვენს ჩაკეტილ ეკრანზე ვიჯეტების ნახვა, თუნდაც ტაბლეტი ჩაკეტილი იყოს."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ვიჯეტის არჩევის გაუქმება"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"სიმაღლის შემცირება"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"სიმაღლის გაზრდა"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"დაბლოკილი ეკრანის ვიჯეტები"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"უნდა დაადასტუროთ თქვენი ვინაობა, რათა გახსნათ აპი ვიჯეტის გამოყენებით. გაითვალისწინეთ, რომ ნებისმიერს შეუძლია მათი ნახვა, მაშინაც კი, როცა ტაბლეტი დაბლოკილია. ზოგი ვიჯეტი შეიძლება არ იყოს გათვლილი თქვენი დაბლოკილი ეკრანისთვის და მათი აქ დამატება შეიძლება სახიფათო იყოს."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"გასაგებია"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"ყველას გასუფთავება"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"მართვა"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ისტორია"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"შეტყობინების პარამეტრები"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"შეტყობინების ისტორია"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"ახალი"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ჩუმი"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"შეტყობინებები"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"დაწყება ახლავე"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"შეტყობინებები არ არის."</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ახალი შეტყობინებები არ არის"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"შეტყობინების განტვირთვის პერიოდი ჩართულია"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"მოწყობილობის ხმა და გაფრთხილებები მცირდება 2 წუთის განმავლობაში, როდესაც ბევრ შეტყობინებას მიიღებთ ერთდროულად."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"გამორთვა"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"განბლოკეთ ძველი შეტყობინებების სანახავად"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ფიქსირებული"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ხმის მიდევნებით"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"შეეხეთ მრეკავის რეჟიმის შესაცვლელად"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"დადუმება"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"დადუმების მოხსნა"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ვიბრაცია"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"მიმდინარე აპი"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"მისაწვდომობა"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"კლავიატურის მალსახმობები"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"კლავიატურის მალსახმობების მორგება"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ძიების მალსახმობები"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ძიების შედეგები არ არის"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ხატულის ჩაკეცვა"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"მორგება"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"მზადაა"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ხატულის გაფართოება"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ან"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"სახელური ჩავლებისთვის"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"მოწოდებულია აპების მიერ"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ეკრანი"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"უცნობი"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"მოზაიკის ფილების გადაყენება"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"გსურთ მოზაიკის ფილების გადაყენება მათ ორიგინალ წყობაზე და ზომებზე?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"გსურთ ყველა ფილის გადაყენება?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"სწრაფი პარამეტრების ყველა ფილა გადაყენდება მოწყობილობის ორიგინალ პარამეტრებზე"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 3dbfd86..4ff87a3 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Қолданба экранын жазасыз ба?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Бір қолданба экранын жазу"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүкіл экранды жазу"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Бүкіл экранды жазу: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Бүкіл экранды жазған кезде, онда көрінетін барлық нәрсе жазылады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Қолданбаны жазған кезде, онда көрінетін не ойнатылатын барлық нәрсе жазылады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Экранды жазу"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Қазір қолданбадағы (<xliff:g id="APP_NAME">%1$s</xliff:g>) контентті жазып жатырсыз."</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Жазуды тоқтату"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экранды бөлісіп жатыр."</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Контент бөлісіліп жатыр"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Экранды бөлісуді тоқтатасыз ба?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Бөлісу тоқтатылсын ба?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Қазір бүкіл экранды қолданбамен (<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>) бөлісіп жатырсыз."</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Қазір бүкіл экранды қолданбамен бөлісіп жатырсыз."</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Қазір қолданбадағы (<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>) контентті бөлісіп жатырсыз."</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Қазір қолданбаны бөлісіп жатырсыз."</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Қазір қолданбамен бөлісіп жатырсыз."</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Бөлісуді тоқтату"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Экранды трансляциялап жатырсыз."</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Трансляциялау тоқтасын ба?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Құлып экранының виджеттері"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Планшет құлыпталып тұрса да, құлып экранындағы виджеттерді кез келген адам көре алады."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"виджетті таңдаудан алу"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Биіктігін төмендету"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Биіктігін арттыру"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Құлып экранының виджеттері"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Қолданбаны виджет көмегімен ашу үшін жеке басыңызды растауыңыз керек. Сондай-ақ басқалар оларды планшетіңіз құлыптаулы кезде де көре алатынын ескеріңіз. Кейбір виджеттер құлып экранына арналмаған болады, сондықтан оларды мұнда қосу қауіпсіз болмауы мүмкін."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түсінікті"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Барлығын тазарту"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Басқару"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Тарих"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Хабарландыру параметрлері"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Хабарландыру тарихы"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Жаңа"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Үнсіз"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Хабарландырулар"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Хабарландырулар жоқ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңа хабарландырулар жоқ"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Хабарландыру дыбысын азайту параметрі қосулы"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Бір уақытта тым көп хабарландыру келсе, дыбыс деңгейі автоматты түрде азайтылып, хабарландырулар 2 минутқа кідіртіледі."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өшіру"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ескі хабарландырулар үшін құлыпты ашыңыз"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Бекітілген"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Бас қимылын қадағалау"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Қоңырау режимін өзгерту үшін түртіңіз."</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дыбысын өшіру"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дыбысын қосу"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"дірілдету"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Қолданыстағы қолданба"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Пернелер тіркесімін бейімдеу"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Іздеу жылдам пәрмендері"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Іздеу нәтижелері жоқ."</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жию белгішесі"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Бейімдеу"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Дайын"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жаю белгішесі"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"немесе"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Сүйрейтін тетік"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Қолданбалар ұсынған"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Дисплей"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Белгісіз"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Бөлшектерді бастапқы күйге қайтару"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Бөлшектерді бастапқы реті мен өлшеміне қайтару керек пе?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Барлық бөлшекті бастапқы күйге қайтару керек пе?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Барлық \"Жылдам параметрлер\" бөлшегі құрылғының бастапқы параметрлеріне қайтарылады."</string>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index b2c8977..24524df 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ថតអេក្រង់របស់អ្នកឬ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ថតកម្មវិធីទោល"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ថតអេក្រង់ទាំងមូល"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ថតអេក្រង់ទាំងមូល៖ %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"នៅពេលអ្នកកំពុងថតអេក្រង់ទាំងមូលរបស់អ្នក អ្វីគ្រប់យ៉ាងដែលបង្ហាញនៅលើអេក្រង់របស់អ្នកត្រូវបានថត។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"នៅពេលអ្នកកំពុងថតកម្មវិធីណាមួយ អ្វីគ្រប់យ៉ាងដែលបង្ហាញ ឬចាក់នៅក្នុងកម្មវិធីនោះត្រូវបានថត។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ថតអេក្រង់"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"បច្ចុប្បន្ន អ្នកកំពុងថត <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ឈប់ថត"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"កំពុងបង្ហាញអេក្រង់"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"កំពុងចែករំលែកខ្លឹមសារ"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ឈប់បង្ហាញអេក្រង់ឬ?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"ឈប់ចែករំលែកឬ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"បច្ចុប្បន្ន អ្នកកំពុងបង្ហាញអេក្រង់ទាំងមូលរបស់អ្នកតាមរយៈ <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"បច្ចុប្បន្ន អ្នកកំពុងបង្ហាញអេក្រង់ទាំងមូលរបស់អ្នកតាមរយៈកម្មវិធីមួយ"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"បច្ចុប្បន្ន អ្នកកំពុងបង្ហាញ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"បច្ចុប្បន្ន អ្នកកំពុងបង្ហាញកម្មវិធីមួយ"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"បច្ចុប្បន្ន អ្នកកំពុងចែករំលែកជាមួយកម្មវិធីមួយ"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ឈប់បង្ហាញ"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"កំពុងបញ្ជូនអេក្រង់"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ឈប់បញ្ជូនឬ?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ធាតុក្រាហ្វិកអេក្រង់ចាក់សោ"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"អ្នកគ្រប់គ្នាអាចមើលធាតុក្រាហ្វិកលើអេក្រង់ចាក់សោរបស់អ្នក ទោះបីជាថេប្លេតរបស់អ្នកត្រូវបានចាក់សោក៏ដោយ។"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ដកការជ្រើសរើសធាតុក្រាហ្វិក"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"បន្ថយកម្ពស់"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"បង្កើនកម្ពស់"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ធាតុក្រាហ្វិកលើអេក្រង់ចាក់សោ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ដើម្បីបើកកម្មវិធីដោយប្រើធាតុក្រាហ្វិក អ្នកនឹងត្រូវផ្ទៀងផ្ទាត់ថាជាអ្នក។ ទន្ទឹមនឹងនេះ សូមចងចាំថា នរណាក៏អាចមើលធាតុក្រាហ្វិកបាន សូម្បីពេលថេប្លេតរបស់អ្នកជាប់សោក៏ដោយ។ ធាតុក្រាហ្វិកមួយចំនួនប្រហែលមិនត្រូវបានរចនាឡើងសម្រាប់អេក្រង់ចាក់សោរបស់អ្នកទេ និងមិនមានសុវត្ថិភាពឡើយ បើបញ្ចូលទៅទីនេះ។"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"យល់ហើយ"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"សម្អាតទាំងអស់"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"គ្រប់គ្រង"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ប្រវត្តិ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"ការកំណត់ការជូនដំណឹង"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"ប្រវត្តិនៃការជូនដំណឹង"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"ថ្មី"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ស្ងាត់"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ការជូនដំណឹង"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ចាប់ផ្ដើមឥឡូវ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"គ្មានការជូនដំណឹង"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"គ្មានការជូនដំណឹងថ្មីៗទេ"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"ការបន្ថយសំឡេងការជូនដំណឹងត្រូវបានបើក"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"កម្រិតសំឡេង និងការជូនដំណឹងនៅលើឧបករណ៍របស់អ្នកត្រូវបានកាត់បន្ថយដោយស្វ័យប្រវត្តិរហូតដល់ 2 នាទី នៅពេលអ្នកទទួលបានការជូនដំណឹងច្រើនពេកក្នុងពេលតែមួយ។"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"បិទ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ដោះសោដើម្បីមើលការជូនដំណឹងចាស់ៗ"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ថេរ"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"រេតាមក្បាល"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ចុចដើម្បីប្ដូរមុខងាររោទ៍"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"បិទសំឡេង"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"បើកសំឡេង"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ញ័រ"</string>
@@ -814,7 +809,7 @@
<string name="keyboard_key_home" msgid="3734400625170020657">"Home"</string>
<string name="keyboard_key_back" msgid="4185420465469481999">"Back"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
- <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
+ <string name="keyboard_key_space" msgid="6980847564173394012">"ដកឃ្លា"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"កម្មវិធីបច្ចុប្បន្ន"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ភាពងាយស្រួល"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ផ្លូវកាត់ក្ដារចុច"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ផ្លូវកាត់ការស្វែងរក"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ប្ដូរផ្លូវកាត់ក្ដារចុចតាមបំណង"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ស្វែងរកផ្លូវកាត់"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"គ្មានលទ្ធផលស្វែងរកទេ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"រូបតំណាង \"បង្រួម\""</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ប្ដូរតាមបំណង"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"រួចរាល់"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"រូបតំណាង \"ពង្រីក\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ឬ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ដងអូស"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ផ្ដល់ជូនដោយកម្មវិធី"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ផ្ទាំងបង្ហាញ"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"មិនស្គាល់"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"កំណត់ប្រអប់ឡើងវិញ"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"កំណត់ប្រអប់ឡើងវិញទៅទំហំ និងលំដាប់ដើមរបស់ប្រអប់ទាំងនោះឬ?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"កំណត់ប្រអប់ទាំងអស់ឡើងវិញឬ?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ប្រអប់ការកំណត់រហ័សទាំងអស់នឹងកំណត់ឡើងវិញទៅការកំណត់ដើមរបស់ឧបករណ៍"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 20c3676..bfaa4391 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಬೇಕೇ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ಒಂದು ಆ್ಯಪ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ನೀವು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತಿರುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಗೋಚರಿಸುವ ಎಲ್ಲವನ್ನೂ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಮತ್ತು ಆಡಿಯೋ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಬಗ್ಗೆ ಜಾಗರೂಕರಾಗಿರಿ."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುವಾಗ, ಆ ಆ್ಯಪ್ನಲ್ಲಿ ತೋರಿಸಿರುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡಿದ ಎಲ್ಲವನ್ನೂ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಮತ್ತು ಆಡಿಯೋ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಬಗ್ಗೆ ಜಾಗರೂಕರಾಗಿರಿ."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"ನೀವು ಪ್ರಸ್ತುತ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತಿದ್ದೀರಿ"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಿ"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ಪರದೆಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"ಕಂಟೆಂಟ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ಸ್ಕ್ರೀನ್ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ನಿಲ್ಲಿಸಬೇಕೆ?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"ಹಂಚಿಕೊಳ್ಳುವುದನ್ನು ನಿಲ್ಲಿಸಬೇಕೇ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"ನೀವು ಪ್ರಸ್ತುತ ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ನೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೀರಿ"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"ನೀವು ಪ್ರಸ್ತುತ ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆ್ಯಪ್ನೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೀರಿ"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"ನೀವು ಪ್ರಸ್ತುತ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೀರಿ"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"ನೀವು ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೀರಿ"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"ನೀವು ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳುತ್ತಿದ್ದೀರಿ"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ನಿಲ್ಲಿಸಿ"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಬೇಕೆ?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ವಿಜೆಟ್ಗಳು"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಲಾಕ್ ಆಗಿದ್ದರೂ ಸಹ ಯಾರಾದರೂ ನಿಮ್ಮ ಲಾಕ್ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ವಿಜೆಟ್ಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ವಿಜೆಟ್ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಬೇಡಿ"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ಎತ್ತರವನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ಎತ್ತರವನ್ನು ಹೆಚ್ಚಿಸಿ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ವಿಜೆಟ್ಗಳು"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ವಿಜೆಟ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಆ್ಯಪ್ ತೆರೆಯಲು, ಇದು ನೀವೇ ಎಂದು ನೀವು ದೃಢೀಕರಿಸಬೇಕಾಗುತ್ತದೆ. ಅಲ್ಲದೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಲಾಕ್ ಆಗಿದ್ದರೂ ಸಹ ಯಾರಾದರೂ ಅವುಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಎಂಬುದನ್ನು ನೆನಪಿನಲ್ಲಿಡಿ. ಕೆಲವು ವಿಜೆಟ್ಗಳು ನಿಮ್ಮ ಲಾಕ್ ಸ್ಕ್ರೀನ್ಗಾಗಿ ಉದ್ದೇಶಿಸದೇ ಇರಬಹುದು ಮತ್ತು ಇಲ್ಲಿ ಸೇರಿಸುವುದು ಸುರಕ್ಷಿತವಲ್ಲದಿರಬಹುದು."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ಅರ್ಥವಾಯಿತು"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ಈಗ ಪ್ರಾರಂಭಿಸಿ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ಯಾವುದೇ ಹೊಸ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"ನೋಟಿಫಿಕೇಶನ್ ಕೂಲ್ಡೌನ್ ಆನ್ ಆಗಿದೆ"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ನೀವು ಏಕಕಾಲದಲ್ಲಿ ತೀರಾ ಹೆಚ್ಚು ನೋಟಿಫಿಕೇಶನ್ಗಳನ್ನು ಪಡೆದಾಗ 2 ನಿಮಿಷಗಳವರೆಗೆ ನಿಮ್ಮ ಸಾಧನದ ವಾಲ್ಯೂಮ್ ಮತ್ತು ಅಲರ್ಟ್ಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಕಡಿಮೆ ಮಾಡಲಾಗುತ್ತದೆ."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ಆಫ್ ಮಾಡಿ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ಹಳೆಯ ಅಧಿಸೂಚನೆಗಳನ್ನು ನೋಡಲು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ಫಿಕ್ಸಡ್"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ಹೆಡ್ ಟ್ರ್ಯಾಕಿಂಗ್"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ರಿಂಗರ್ ಮೋಡ್ ಬದಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ವೈಬ್ರೇಟ್"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ಪ್ರಸ್ತುತ ಆ್ಯಪ್"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳು"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ಹುಡುಕಾಟದ ಶಾರ್ಟ್ಕಟ್ಗಳು"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ಯಾವುದೇ ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳಿಲ್ಲ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ಕುಗ್ಗಿಸುವ ಐಕಾನ್"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ಮುಗಿದಿದೆ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ವಿಸ್ತೃತಗೊಳಿಸುವ ಐಕಾನ್"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ಅಥವಾ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ಡ್ರ್ಯಾಗ್ ಹ್ಯಾಂಡಲ್"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ಆ್ಯಪ್ಗಳಿಂದ ಒದಗಿಸಲಾಗಿದೆ"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ಡಿಸ್ಪ್ಲೇ"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ಅಪರಿಚಿತ"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"ಟೈಲ್ಗಳನ್ನು ರೀಸೆಟ್ ಮಾಡಿ"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"ಟೈಲ್ಗಳನ್ನು ಅವುಗಳ ಮೂಲ ಆರ್ಡರ್ ಮತ್ತು ಗಾತ್ರಗಳಿಗೆ ರೀಸೆಟ್ ಮಾಡಬೇಕೇ?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ಎಲ್ಲಾ ಟೈಲ್ಗಳನ್ನು ರೀಸೆಟ್ ಮಾಡಬೇಕೆ?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ಎಲ್ಲಾ ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳ ಟೈಲ್ಗಳನ್ನು ಸಾಧನದ ಮೂಲ ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತದೆ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 35dc245..fee96f9 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"화면을 녹화하시겠습니까?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"단일 앱 녹화"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"전체 화면 녹화"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"전체 화면 녹화: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"전체 화면을 녹화하면 화면에 표시되는 모든 항목이 녹화됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"앱을 녹화하면 앱에 표시되거나 앱에서 재생되는 모든 항목이 녹화됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"화면 녹화"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"현재 <xliff:g id="APP_NAME">%1$s</xliff:g>의 콘텐츠를 녹화 중입니다."</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"녹화 중지"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"화면 공유 중"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"콘텐츠 공유"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"화면 공유를 중지하시겠습니까?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"공유를 중단하시겠습니까?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"현재 전체 화면을 <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> 앱과 공유 중입니다."</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"현재 전체 화면을 앱과 공유 중입니다"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"현재 <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>의 콘텐츠를 공유 중입니다."</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"현재 앱을 공유 중입니다"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"현재 앱과 공유 중입니다"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"공유 중지"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"화면 전송 중"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"전송을 중지할까요?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"잠금 화면 위젯"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"태블릿이 잠겨 있어도 누구나 잠금 화면에서 위젯을 볼 수 있습니다."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"위젯 선택 해제"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"높이 줄이기"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"높이 늘리기"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"잠금 화면 위젯"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"위젯을 사용하여 앱을 열려면 본인 인증을 해야 합니다. 또한 태블릿이 잠겨 있더라도 누구나 볼 수 있다는 점을 유의해야 합니다. 일부 위젯은 잠금 화면에 적합하지 않고 여기에 추가하기에 안전하지 않을 수 있습니다."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"확인"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"알림 없음"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"새로운 알림 없음"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"알림 쿨다운 사용 중"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"한 번에 너무 많은 알림을 받으면 최대 2분간 자동으로 기기 볼륨이 줄어들고 알림이 최소화됩니다."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"사용 중지"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"잠금 해제하여 이전 알림 보기"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"수정됨"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"머리 추적"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"탭하여 벨소리 장치 모드 변경"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"음소거"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"음소거 해제"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"진동"</string>
@@ -875,7 +872,7 @@
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"입력"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"다음 언어로 전환"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"이전 언어로 전환"</string>
- <string name="input_access_emoji" msgid="8105642858900406351">"이모티콘에 액세스"</string>
+ <string name="input_access_emoji" msgid="8105642858900406351">"이모티콘 열기"</string>
<string name="input_access_voice_typing" msgid="7291201476395326141">"음성 입력에 액세스"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"애플리케이션"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"어시스턴트"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"현재 앱"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"접근성"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"단축키"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"단축키 맞춤설정"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"검색 바로가기"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"검색 결과 없음"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"접기 아이콘"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"맞춤설정"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"완료"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"확장 아이콘"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"또는"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"드래그 핸들"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"앱에서 제공"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"디스플레이"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"알 수 없음"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"타일 재설정"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"타일을 원래 순서 및 크기로 재설정하시겠습니까?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"모든 타일을 재설정하시겠습니까?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"모든 빠른 설정 타일이 기기의 원래 설정으로 재설정됩니다."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 72e86cc..3c58eb7 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Экранды жаздырасызбы?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Бир колдонмону жаздыруу"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүтүндөй экранды жаздыруу"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Толук экранды жаздыруу: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Бүтүндөй экранды жаздырганда, андагы нерселердин баары видеого түшүп калат. Андыктан этият болуп, сырсөздөр, төлөм ыкмалары, билдирүүлөр, сүрөттөр, аудио жана видео материалдар сыяктуу купуя нерселерди көрсөтүп албаңыз."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Колдонмону жаздырганда ал колдонмодо көрсөтүлүп же ойнотулуп жаткан нерселер жаздырылат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Экранды жаздыруу"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Учурда <xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун жаздырып жатасыз"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Жаздырууну токтотуу"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экран бөлүшүлүүдө"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Контент бөлүшүлүүдө"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Экранды бөлүшүүнү токтотосузбу?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Бөлүшүүнү токтотосузбу?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Учурда бүтүндөй экраныңызды <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> менен бөлүшүп жатасыз"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Учурда бүтүндөй экраныңызды колдонмо менен бөлүшүп жатасыз"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Учурда <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> колдонмосун бөлүшүп жатасыз"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Учурда колдонмону бөлүшүп жатасыз"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Учурда колдонмо менен бөлүшүп жатасыз"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Бөлүшүүнү токтотуу"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Тышкы экранга чыгарылууда"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Тышкы экранга чыгарууну токтотосузбу?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Кулпуланган экрандагы виджеттер"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Кулпуланган планшетте баарына көрүнүп турат."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"виджетти тандоодон чыгаруу"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Бийиктигин азайтуу"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Бийиктигин көбөйтүү"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Кулпуланган экрандагы виджеттер"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Колдонмону виджет аркылуу ачуу үчүн өзүңүздү ырасташыңыз керек. Алар кулпуланган планшетиңизде да көрүнүп турат. Кээ бир виджеттерди кулпуланган экранда колдоно албайсыз, андыктан аларды ал жерге кошпой эле койгонуңуз оң."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түшүндүм"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Баарын тазалап салуу"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Башкаруу"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Таржымал"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Билдирмелердин параметрлери"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Билдирмелердин таржымалы"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Жаңы"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Үнсүз"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Билдирмелер"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Билдирме жок"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңы билдирмелер жок"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Билдирмелердин үнүн басаңдатуу күйүк"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Өтө көп билдирме келсе, түзмөктүн үнү 2 мүнөткө басаңдап, эскертүүлөрдүн саны азаят."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өчүрүү"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Билдирмелерди көрүү үчүн кулпуну ачыңыз"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Туруктуу"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Баштын кыймылына көз салуу"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Коңгуроо режимин өзгөртүү үчүн басыңыз"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"үнсүз"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"үнүн чыгаруу"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"дирилдөө"</string>
@@ -1411,19 +1406,16 @@
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Акыркы колдонмолор"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Экранды бөлүү"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Киргизүү"</string>
- <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Колдонмодогу кыска жолдор"</string>
+ <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Колдонмонун ыкчам баскычтары"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Учурдагы колдонмо"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Атайын мүмкүнчүлүктөр"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ыкчам баскычтар"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Ыкчам баскычтарды ыңгайлаштыруу"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ыкчам баскычтарды издөө"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Эч нерсе табылган жок"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жыйыштыруу сүрөтчөсү"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Ыңгайлаштыруу"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Бүттү"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жайып көрсөтүү сүрөтчөсү"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"же"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Cүйрөө маркери"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Колдонмолор сунуштады"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Экран"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Белгисиз"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Карталарды баштапкы абалга келтирүү"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Карталар баштапкы иретине жана өлчөмдөрүнө кайтарылсынбы?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Бардык карталарды баштапкы абалга келтиресизби?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Бардык Ыкчам параметрлер карталары түзмөктүн баштапкы параметрлерине кайтарылат"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index f6fe3cc..1dd534d 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ບັນທຶກໜ້າຈໍຂອງທ່ານບໍ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ບັນທຶກແອັບດຽວ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ບັນທຶກໝົດໜ້າຈໍ"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ບັນທຶກໜ້າຈໍທັງໝົດ: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ເມື່ອທ່ານບັນທຶກໝົດໜ້າຈໍຂອງທ່ານ, ລະບົບຈະບັນທຶກທຸກສິ່ງທີ່ສະແດງຢູ່ໜ້າຈໍຂອງທ່ານ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ, ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ເມື່ອທ່ານບັນທຶກແອັບ, ລະບົບຈະບັນທຶກທຸກສິ່ງທີ່ສະແດງ ຫຼື ຫຼິ້ນຢູ່ໃນແອັບນັ້ນ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ, ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ບັນທຶກໜ້າຈໍ"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"ທ່ານກຳລັງບັນທຶກ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ຢຸດການບັນທຶກ"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ກຳລັງແບ່ງປັນໜ້າຈໍ"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"ກຳລັງແບ່ງປັນເນື້ອຫາ"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ຢຸດການແບ່ງປັນໜ້າຈໍບໍ?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"ຢຸດການແບ່ງປັນບໍ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"ທ່ານກຳລັງແບ່ງປັນທັງໝົດໜ້າຈໍຂອງທ່ານກັບ <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"ທ່ານກຳລັງແບ່ງປັນທັງໝົດໜ້າຈໍຂອງທ່ານກັບແອັບ"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"ທ່ານກຳລັງແບ່ງປັນ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"ທ່ານກຳລັງແບ່ງປັນແອັບ"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"ທ່ານກຳລັງແບ່ງປັນກັບແອັບ"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ຢຸດການແບ່ງປັນ"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ກຳລັງສົ່ງສັນຍານໜ້າຈໍ"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ຢຸດການສົ່ງສັນຍານບໍ?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ວິດເຈັດໃນໜ້າຈໍລັອກ"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"ທຸກຄົນສາມາດເບິ່ງວິດເຈັດຢູ່ໜ້າຈໍລັອກຂອງທ່ານໄດ້, ເຖິງແມ່ນວ່າແທັບເລັດຂອງທ່ານຈະລັອກຢູ່ກໍຕາມ."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ຍົກເລີກການເລືອກວິດເຈັດ"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ຫຼຸດຄວາມສູງ"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ເພີ່ມຄວາມສູງ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ວິດເຈັດໃນໜ້າຈໍລັອກ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ເພື່ອເປີດແອັບໂດຍໃຊ້ວິດເຈັດ, ທ່ານຈະຕ້ອງຢັ້ງຢືນວ່າແມ່ນທ່ານ. ນອກຈາກນັ້ນ, ກະລຸນາຮັບຊາບວ່າທຸກຄົນສາມາດເບິ່ງຂໍ້ມູນດັ່ງກ່າວໄດ້, ເຖິງແມ່ນວ່າແທັບເລັດຂອງທ່ານຈະລັອກຢູ່ກໍຕາມ. ວິດເຈັດບາງຢ່າງອາດບໍ່ໄດ້ມີໄວ້ສຳລັບໜ້າຈໍລັອກຂອງທ່ານ ແລະ ອາດບໍ່ປອດໄພທີ່ຈະເພີ່ມໃສ່ບ່ອນນີ້."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ເຂົ້າໃຈແລ້ວ"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"ລຶບລ້າງທັງໝົດ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ຈັດການ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ປະຫວັດ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"ການຕັ້ງຄ່າການແຈ້ງເຕືອນ"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"ປະຫວັດການແຈ້ງເຕືອນ"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"ໃໝ່"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ປິດສຽງ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ການແຈ້ງເຕືອນ"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ເລີ່ມດຽວນີ້"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ບໍ່ມີການແຈ້ງເຕືອນ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ບໍ່ມີການແຈ້ງເຕືອນໃໝ່"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"ຄູດາວການແຈ້ງເຕືອນເປີດຢູ່"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ສຽງ ແລະ ແຈ້ງເຕືອນອຸປະກອນຂອງທ່ານຖືກຫຼຸດລົງໂດຍອັດຕະໂນມັດເປັນເວລາເຖິງ 2 ນາທີເມື່ອທ່ານໄດ້ຮັບການແຈ້ງເຕືອນຫຼາຍເກີນໄປໃນຄັ້ງດຽວ."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ປິດ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ປົດລັອກເພື່ອເບິ່ງການແຈ້ງເຕືອນເກົ່າ"</string>
@@ -705,6 +698,7 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ຄົງທີ່"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ການຕິດຕາມຫົວ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ແຕະເພື່ອປ່ຽນໂໝດຣິງເກີ"</string>
+ <string name="volume_ringer_mode" msgid="6867838048430807128">"ໂໝດຣິງເກີ"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ປິດສຽງ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ເຊົາປິດສຽງ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ສັ່ນເຕືອນ"</string>
@@ -1415,15 +1409,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ແອັບປັດຈຸບັນ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ຄີລັດ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ປັບແຕ່ງຄີລັດ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ທາງລັດການຊອກຫາ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ບໍ່ມີຜົນການຊອກຫາ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ໄອຄອນຫຍໍ້ລົງ"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ປັບແຕ່ງ"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ແລ້ວໆ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ໄອຄອນຂະຫຍາຍ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ຫຼື"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ບ່ອນຈັບລາກ"</string>
@@ -1485,6 +1476,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ສະໜອງໃຫ້ໂດຍແອັບ"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ການສະແດງຜົນ"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ບໍ່ຮູ້ຈັກ"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"ຣີເຊັດແຜ່ນ"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"ຣີເຊັດແຜ່ນເປັນການຈັດຮຽງ ແລະ ຂະໜາດເດີມບໍ?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ຣີເຊັດແຜ່ນທັງໝົດບໍ?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ແຜ່ນການຕັ້ງຄ່າດ່ວນທັງໝົດຈະຣີເຊັດເປັນການຕັ້ງຄ່າແບບເກົ່າຂອງອຸປະກອນ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 70a0063..a2d26c7 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Įrašyti ekraną?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Įrašyti vieną programą"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Įrašyti visą ekraną"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Įrašyti visą ekraną: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kai įrašote visą ekraną, įrašomas visas ekrane rodomas turinys. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kai įrašote programą, įrašomas visas toje programoje rodomas ar leidžiamas turinys. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Įrašyti ekraną"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Šiuo metu įrašote šią programą: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Sustabdyti įrašymą"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Bendrinamas ekranas"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Bendrint turinį"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Nebebendrinti ekrano?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Nebebendrinti?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Šiuo metu bendrinate visą ekraną su šia programa: <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Šiuo metu bendrinate visą ekraną su programa"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Šiuo metu bendrinate šią programą: <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Šiuo metu bendrinate programą"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Šiuo metu bendrinate su programa"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Nebebendrinti"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Perduodamas ekranas"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Sustabdyti perdavimą?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Užrakinimo ekrano valdikliai"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Visi gali žr. valdiklius užrakinimo ekrane, net užrakinus planšetinį kompiuterį."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"atšaukti valdiklio pasirinkimą"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Sumažinti aukštį"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Padidinti aukštį"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Užrakinimo ekrano valdikliai"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Kad galėtumėte atidaryti programą naudodami valdiklį, turėsite patvirtinti savo tapatybę. Be to, atminkite, kad bet kas gali peržiūrėti valdiklius net tada, kai planšetinis kompiuteris užrakintas. Kai kurie valdikliai gali būti neskirti jūsų užrakinimo ekranui ir gali būti nesaugu juos čia pridėti."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Supratau"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Viską išvalyti"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Tvarkyti"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Istorija"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Pranešimų nustatymai"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Pranešimų istorija"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nauja"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Tylus"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Pranešimai"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Pradėti dabar"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nėra įspėjimų"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Naujų pranešimų nėra"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Pranešimų neaktyvumo laikotarpis įjungtas"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Jūsų įrenginio garsumas ir įspėjimai automatiškai sumažinami iki dviejų minučių, kai iš karto gaunate per daug pranešimų."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Išjungti"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Atrakinę matykite senesnius pranešimus"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksuotas"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Galvos stebėjimas"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Palieskite, kad pakeistumėte skambučio režimą"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"nutildyti"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"įjungti garsą"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibruoti"</string>
@@ -1411,19 +1406,16 @@
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Naujausios programos"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Išskaidyto ekrano režimas"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Įvestis"</string>
- <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Programos šaukiniai"</string>
+ <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Programos spartieji klavišai"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Esama programa"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pritaikomumas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Spartieji klavišai"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Paieškos šaukiniai"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sparčiųjų klavišų tinkinimas"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ieškoti sparčiųjų klavišų"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nėra jokių paieškos rezultatų"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sutraukimo piktograma"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tinkinti"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Atlikta"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Išskleidimo piktograma"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"arba"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkimo rankenėlė"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Teikia programos"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekranas"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nežinoma"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Išklotinės nustatymas iš naujo"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Iš naujo nustatyti išklotinės pradinę tvarką ir dydžius?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Iš naujo nustatyti visus išklotines elementus?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Visi sparčiųjų nustatymų išklotinės elementai bus iš naujo nustatyti į pradinius įrenginio nustatymus"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 360afad..98eebd3 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vai ierakstīt ekrānu?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ierakstīt vienu lietotni"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Ierakstīt visu ekrānu"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Ierakstīt visu ekrānu: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Ierakstot visu ekrānu, viss, kas redzams ekrānā, tiek ierakstīts. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ierakstot lietotni, tiek ierakstīts viss attiecīgajā lietotnē rādītais vai atskaņotais. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ierakstīt ekrānu"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Pašlaik ierakstāt lietotni <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Apturēt ierakstīšanu"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Notiek ekrāna kopīgošana"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Notiek satura kopīgošana"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vai apturēt ekrāna kopīgošanu?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Vai apturēt kopīgošanu?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Pašlaik kopīgojat visu ekrānu ar lietotni <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Pašlaik kopīgojat visu ekrānu ar lietotni"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Pašlaik kopīgojat lietotni <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Pašlaik kopīgojat lietotni"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Pašlaik kopīgojat saturu ar lietotni."</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Apturēt kopīgošanu"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Notiek ekrāna apraide"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vai pārtraukt apraidi?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Bloķēšanas ekrāna logrīki"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Jebkurš var skatīt logrīkus bloķēšanas ekrānā, pat ja planšetdators ir bloķēts."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"noņemt logrīka atlasi"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Samazināt augstumu"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Palielināt augstumu"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Bloķēšanas ekrāna logrīki"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Lai atvērtu lietotni, izmantojot logrīku, jums būs jāapstiprina sava identitāte. Turklāt ņemiet vērā, ka ikviens var skatīt logrīkus, pat ja planšetdators ir bloķēts. Iespējams, daži logrīki nav paredzēti izmantošanai bloķēšanas ekrānā, un var nebūt droši tos šeit pievienot."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Labi"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Dzēst visu"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Pārvaldīt"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Vēsture"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Paziņojumu iestatījumi"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Paziņojumu vēsture"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Jauni"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Klusums"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Paziņojumi"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nav paziņojumu"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nav jaunu paziņojumu"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Nogaidīšanas periods paziņojumiem ir ieslēgts"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Saņemot par daudz paziņojumu uzreiz, skaļums un brīdinājumi tiek automātiski samazināti līdz 2 min."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Izslēgt"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Atbloķējiet vecāku paziņojumu skatīšanai"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksēts"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seko galvai"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Pieskarieties, lai mainītu zvanītāja režīmu."</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izslēgt skaņu"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ieslēgt skaņu"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrēt"</string>
@@ -815,8 +810,8 @@
<string name="keyboard_key_back" msgid="4185420465469481999">"Atpakaļ"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"Atstarpe"</string>
- <string name="keyboard_key_enter" msgid="8633362970109751646">"Ievadīšanas taustiņš"</string>
- <string name="keyboard_key_backspace" msgid="4095278312039628074">"Atpakaļatkāpes taustiņš"</string>
+ <string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
+ <string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Atskaņot/apturēt"</string>
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"Apturēt"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Nākamais"</string>
@@ -826,7 +821,7 @@
<string name="keyboard_key_page_up" msgid="173914303254199845">"Lapa uz augšu"</string>
<string name="keyboard_key_page_down" msgid="9035902490071829731">"Lapa uz leju"</string>
<string name="keyboard_key_forward_del" msgid="5325501825762733459">"Dzēšanas taustiņš"</string>
- <string name="keyboard_key_esc" msgid="6230365950511411322">"Atsoļa taustiņš"</string>
+ <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string>
<string name="keyboard_key_move_home" msgid="3496502501803911971">"Sākumvietas taustiņš"</string>
<string name="keyboard_key_move_end" msgid="99190401463834854">"Beigvietas taustiņš"</string>
<string name="keyboard_key_insert" msgid="4621692715704410493">"Ievietošanas taustiņš"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Pašreizējā lietotne"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pieejamība"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Īsinājumtaustiņi"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Meklēšanas saīsnes"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Īsinājumtaustiņu pielāgošana"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Meklēt saīsnes"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nav meklēšanas rezultātu"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sakļaušanas ikona"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Pielāgot"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gatavs"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Izvēršanas ikona"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vai"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkšanas turis"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Nodrošina lietotnes"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Displejs"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nezināma"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Elementu atiestatīšana"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Vai atiestatīt elementus, atjaunojot to sākotnējo secību un izmērus?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vai atiestatīt visus elementus?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Visiem ātro iestatījumu elementiem tiks atiestatīti sākotnējie iestatījumi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index ebd62a9..f136441 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Да се снима екранот?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Снимање на една апликација"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Снимање на целиот екран"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Снимање на целиот екран: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Додека го снимате целиот екран, сѐ што е прикажано на екранот се снима. Затоа, бидете внимателни со лозинките, деталите за плаќање, пораките, фотографиите и аудиото и видеото."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Додека снимате апликација, може да се сними сѐ што се прикажува или пушта во таа апликација. Затоа, бидете внимателни со лозинките, деталите за плаќање, пораките, фотографиите и аудиото и видеото."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Снимај го екранот"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Во моментов ја снимате <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Сопри го снимањето"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Се споделува екранот"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Се споделуваат содржини"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Да се сопре споделувањето на екранот?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Да се сопре споделувањето?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Во моментов го споделувате целиот екран со <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Во моментов го споделувате целиот екран со апликација"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Во моментов ја споделувате <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Во моментов споделувате апликација"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Во моментов споделувате со апликација"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Сопри го споделувањето"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Се емитува екранот"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Да се сопре емитувањето?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Виџети на заклучен екран"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Секој може да гледа виџети на заклучениот екран, дури и ако таблетот е заклучен."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"поништи го изборот на виџетот"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Намали ја висината"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Зголеми ја висината"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виџети на заклучен екран"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите апликација со помош на виџет, ќе треба да потврдите дека сте вие. Покрај тоа, имајте предвид дека секој може да ги гледа виџетите, дури и кога вашиот таблет е заклучен. Некои виџети можеби не се наменети за вашиот заклучен екран, па можеби не е безбедно да се додадат овде."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Сфатив"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нема известувања"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нови известувања"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"„Подискретни известувања“ е вклучена"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Јачината на звукот и известувањата на уредот се намалуваат автоматски до 2 минути кога добивате премногу известувања одеднаш."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Исклучи"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Отклучете за да ги видите старите известувања"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Фиксно"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Следење на главата"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Допрете за да го промените режимот на ѕвончето"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"исклучен звук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"вклучен звук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрации"</string>
@@ -814,7 +811,7 @@
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
- <string name="keyboard_key_backspace" msgid="4095278312039628074">"Бришење наназад"</string>
+ <string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Пушти/Паузирај"</string>
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"Сопри"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Следно"</string>
@@ -1413,21 +1410,18 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Тековна апликација"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Пристапност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Кратенки од тастатура"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Кратенки за пребарување"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Приспособете ги кратенките од тастатурата"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пребарувајте кратенки"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултати од пребарување"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за собирање"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Приспособете"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширување"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Рачка за влечење"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Поставки за тастатурата"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Движете се со користење на тастатурата"</string>
- <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете кратенки од тастатурата"</string>
+ <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете ги кратенките од тастатурата"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Движете се со користење на допирната подлога"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Научете движења за допирната подлога"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Движете се со користење на тастатурата и допирната подлога"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Обезбедено од апликации"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Екран"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Непознато"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Ресетирајте ги плочките"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Да се ресетираат плочките на нивниот првичен редослед и големини?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Да се ресетираат сите плочки?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Сите плочки на „Брзи поставки“ ќе се ресетираат на првичните поставки на уредот"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 6152fce..3378b11 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"നിങ്ങളുടെ സ്ക്രീൻ റെക്കോർഡ് ചെയ്യണോ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ഒരു ആപ്പ് റെക്കോർഡ് ചെയ്യുക"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"സ്ക്രീൻ പൂർണ്ണമായി റെക്കോർഡ് ചെയ്യുക"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"മുഴുവൻ സ്ക്രീനും റെക്കോർഡ് ചെയ്യുക: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"നിങ്ങളുടെ സ്ക്രീൻ പൂർണ്ണമായി റെക്കോർഡ് ചെയ്യുമ്പോൾ, സ്ക്രീനിൽ ദൃശ്യമാകുന്ന എല്ലാം റെക്കോർഡ് ചെയ്യപ്പെടും. അതിനാൽ പാസ്വേഡുകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"നിങ്ങളുടെ ആപ്പ് റെക്കോർഡ് ചെയ്യുമ്പോൾ, ആ ആപ്പിൽ കാണിക്കുന്നതോ പ്ലേ ചെയ്യുന്നതോ ആയ എല്ലാ കാര്യങ്ങളും റെക്കോർഡ് ചെയ്യപ്പെടും. അതിനാൽ പാസ്വേഡുകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"സ്ക്രീൻ റെക്കോർഡ് ചെയ്യുക"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"നിങ്ങൾ ഇപ്പോൾ <xliff:g id="APP_NAME">%1$s</xliff:g> റെക്കോർഡ് ചെയ്യുകയാണ്"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"റെക്കോർഡിംഗ് നിർത്തുക"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"സ്ക്രീൻ പങ്കിടുന്നു"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"ഉള്ളടക്കം പങ്കിടൽ"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"സ്ക്രീൻ പങ്കിടുന്നത് നിർത്തണോ?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"പങ്കിടൽ നിർത്തണോ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"നിങ്ങൾ ഇപ്പോൾ മുഴുവൻ സ്ക്രീനും <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> എന്നതുമായി പങ്കിടുകയാണ്"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"നിങ്ങൾ ഇപ്പോൾ മുഴുവൻ സ്ക്രീനും ഒരു ആപ്പുമായി പങ്കിടുകയാണ്"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"നിങ്ങൾ ഇപ്പോൾ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> പങ്കിടുകയാണ്"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"നിങ്ങൾ നിലവിൽ ഒരു ആപ്പ് പങ്കിടുകയാണ്"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"നിങ്ങൾ നിലവിൽ ഒരു ആപ്പുമായി പങ്കിടുകയാണ്"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"പങ്കിടൽ നിർത്തുക"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"സ്ക്രീൻ കാസ്റ്റ് ചെയ്യുന്നു"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"കാസ്റ്റ് ചെയ്യുന്നത് അവസാനിപ്പിക്കണോ?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ലോക്ക് സ്ക്രീൻ വിജറ്റുകൾ"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"ടാബ്ലെറ്റ് ലോക്കാണെങ്കിൽ പോലും ലോക്ക് സ്ക്രീനിൽ ആർക്കും വിജറ്റുകൾ കാണാം."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"വിജറ്റ് തിരഞ്ഞെടുത്തത് മാറ്റുക"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ഉയരം കുറയ്ക്കുക"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ഉയരം കൂട്ടുക"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ലോക്ക് സ്ക്രീൻ വിജറ്റുകൾ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"വിജറ്റ് ഉപയോഗിച്ച് ഒരു ആപ്പ് തുറക്കാൻ, ഇത് നിങ്ങൾ തന്നെയാണെന്ന് പരിശോധിച്ചുറപ്പിക്കേണ്ടതുണ്ട്. നിങ്ങളുടെ ടാബ്ലെറ്റ് ലോക്കായിരിക്കുമ്പോഴും എല്ലാവർക്കും അത് കാണാനാകുമെന്നതും ഓർക്കുക. ചില വിജറ്റുകൾ നിങ്ങളുടെ ലോക്ക് സ്ക്രീനിന് ഉള്ളതായിരിക്കില്ല, അവ ഇവിടെ ചേർക്കുന്നത് സുരക്ഷിതവുമായിരിക്കില്ല."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"മനസ്സിലായി"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"പുതിയ അറിയിപ്പുകളൊന്നുമില്ല"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"അറിയിപ്പിന്റെ ശബ്ദം കുറയ്ക്കൽ ഓണാണ്"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"നിരവധി അറിയിപ്പ് ഒരുമിച്ച് ലഭിക്കുമ്പോൾ, ഉപകരണത്തിന്റെ ശബ്ദവും മുന്നറിയിപ്പും 2 മിനിറ്റ് വരെ സ്വയമേവ കുറയ്ക്കും."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ഓഫാക്കുക"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"പഴയ അറിയിപ്പുകൾ കാണാൻ അൺലോക്ക് ചെയ്യുക"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ഓൺ ചെയ്തിരിക്കുന്നു"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ഹെഡ് ട്രാക്കിംഗ്"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"റിംഗർ മോഡ് മാറ്റാൻ ടാപ്പ് ചെയ്യുക"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"മ്യൂട്ട് ചെയ്യുക"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"അൺമ്യൂട്ട് ചെയ്യുക"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"വൈബ്രേറ്റ് ചെയ്യുക"</string>
@@ -869,7 +866,7 @@
<string name="system_multitasking_rhs" msgid="8714224917276297810">"വലതുവശത്തുള്ള നിലവിലെ ആപ്പിനൊപ്പം സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുക"</string>
<string name="system_multitasking_lhs" msgid="8402954791206308783">"ഇടതുവശത്തുള്ള നിലവിലെ ആപ്പിനൊപ്പം സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുക"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"സ്ക്രീൻ വിഭജന മോഡിൽ നിന്ന് പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറുക"</string>
- <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ വലതുവശത്തെ/താഴത്തെ ആപ്പിലേക്ക് മാറൂ"</string>
+ <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ വലതുവശത്തെ/താഴത്തെ ആപ്പിലേക്ക് മാറുക"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ ഇടതുവശത്തെ/മുകളിലെ ആപ്പിലേക്ക് മാറൂ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"സ്ക്രീൻ വിഭജന മോഡിൽ: ഒരു ആപ്പിൽ നിന്ന് മറ്റൊന്നിലേക്ക് മാറുക"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ഇൻപുട്ട്"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"നിലവിലെ ആപ്പ്"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ഉപയോഗസഹായി"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"കീബോഡ് കുറുക്കുവഴികൾ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"കീബോർഡ് കുറുക്കുവഴികൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"തിരയൽ കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"തിരയൽ ഫലങ്ങളൊന്നുമില്ല"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ചുരുക്കൽ ഐക്കൺ"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ഇഷ്ടാനുസൃതമാക്കുക"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"പൂർത്തിയായി"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"വികസിപ്പിക്കൽ ഐക്കൺ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"അല്ലെങ്കിൽ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"വലിച്ചിടുന്നതിനുള്ള ഹാൻഡിൽ"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ആപ്പുകൾ നൽകുന്നത്"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ഡിസ്പ്ലേ"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"അജ്ഞാതം"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"ടൈലുകൾ റീസെറ്റ് ചെയ്യുക"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"ടൈലുകൾ അവയുടെ ഒറിജിനൽ ക്രമത്തിലേക്കും വലുപ്പങ്ങളിലേക്കും റീസെറ്റ് ചെയ്യണോ?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"എല്ലാ ടൈലുകളും റീസെറ്റ് ചെയ്യണോ?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"എല്ലാ ദ്രുത ക്രമീകരണ ടൈലുകളും ഉപകരണത്തിന്റെ ഒറിജിനൽ ക്രമീകരണത്തിലേക്ക് റീസെറ്റ് ചെയ്യും"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index aafc8c61..9aca3ee 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Дэлгэцээ бичих үү?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Нэг аппыг бичих"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүтэн дэлгэцийг бичих"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Дэлгэцийг бүхэлд нь бичих: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Таныг бүтэн дэлгэцээ бичиж байхад дэлгэц дээр тань харуулж буй аливаа зүйлийг бичдэг. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж, зураг, аудио, видео зэрэг зүйлд болгоомжтой хандаарай."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Таныг апп бичиж байхад тухайн аппад харуулж эсвэл тоглуулж буй аливаа зүйлийг бичдэг. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж, зураг, аудио, видео зэрэг зүйлд болгоомжтой хандаарай."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Дэлгэцийг бичих"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Та одоогоор <xliff:g id="APP_NAME">%1$s</xliff:g>-г бичиж байна"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Бичихийг зогсоох"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Дэлгэцийг хуваалцаж байна"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Контент хуваалцаж байна"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Дэлгэц хуваалцахыг зогсоох уу?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Хуваалцахыг зогсоох уу?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Та одоогоор дэлгэцээ бүтнээр нь <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>-тай хуваалцаж байна"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Та одоогоор дэлгэцээ бүтнээр нь нэг апптай хуваалцаж байна"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Та одоогоор <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>-г хуваалцаж байна"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Та одоогоор нэг аппыг хуваалцаж байна"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Та одоогоор нэг апптай хуваалцаж байна"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Хуваалцахыг зогсоох"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Дэлгэцийг дамжуулж байна"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Дамжуулахaa болих уу?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Түгжээтэй дэлгэцийн виджет"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Таны таблет түгжээтэй байсан ч түгжээтэй дэлгэцийн виджетийг тань дурын хүн үзнэ"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"виджетийн сонголтыг болиулах"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Намсгах"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Өндөрсгөх"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Түгжээтэй дэлгэцийн виджет"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Виджет ашиглан аппыг нээхийн тулд та өөрийгөө мөн болохыг баталгаажуулах шаардлагатай болно. Мөн таны таблет түгжээтэй байсан ч тэдгээрийг дурын хүн үзэж болохыг санаарай. Зарим виджет таны түгжээтэй дэлгэцэд зориулагдаагүй байж магадгүй ба энд нэмэхэд аюултай байж болзошгүй."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ойлголоо"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Мэдэгдэл байхгүй"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Шинэ мэдэгдэл алга"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Мэдэгдлийн хөргөлт асаалттай байна"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Таныг хэт олон мэдэгдэл нэг дор авахад таны төхөөрөмжийн дууны түвшин болон дохиог 2 хүртэлх минутын турш автоматаар багасгадаг."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Унтраах"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Хуучин мэдэгдлийг харах бол түгжээг тайл"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Зассан"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Толгой хянах"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Хонхны горимыг өөрчлөхийн тулд товшино уу"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дууг хаах"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дууг нээх"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"чичрэх"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Одоогийн апп"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Хандалт"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Товчлуурын шууд холбоос"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Товчлуурын шууд холбоосыг өөрчлөх"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Товчлолууд хайх"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ямар ч хайлтын илэрц байхгүй"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Хураах дүрс тэмдэг"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Өөрчлөх"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Болсон"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Дэлгэх дүрс тэмдэг"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"эсвэл"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Чирэх бариул"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Аппуудаас өгсөн"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Дэлгэц"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Тодорхойгүй"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Хавтангуудыг шинэчлэх"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Хавтангуудыг эх дараалал, хэмжээ рүү нь шинэчлэх үү?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Бүх хавтанг шинэчлэх үү?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Шуурхай тохиргооны бүх хавтан төхөөрөмжийн эх тохиргоо руу шинэчлэгдэнэ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index fbbb167..82a001a 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"तुमची स्क्रीन रेकॉर्ड करायची आहे का?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक अॅप रेकॉर्ड करा"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूर्ण स्क्रीन रेकॉर्ड करा"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"संपूर्ण स्क्रीन रेकॉर्ड करा: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तुम्ही तुमची पूर्ण स्क्रीन रेकॉर्ड करता, तेव्हा तुमच्या स्क्रीनवर दाखवलेली कोणतीही गोष्टी रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तुम्ही अॅप रेकॉर्ड करता, तेव्हा त्या अॅपमध्ये दाखवलेली किंवा प्ले केलेली कोणतीही गोष्ट रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रेकॉर्ड करा"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"तुम्ही सध्या <xliff:g id="APP_NAME">%1$s</xliff:g> रेकॉर्ड करत आहात"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"रेकॉर्ड करणे थांबवा"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रीन शेअर करत आहे"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"आशय शेअर करत आहे"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"स्क्रीन शेअर करणे थांबवायचे आहे का?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"शेअर करणे थांबवायचे आहे का?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"तुम्ही सध्या तुमची संपूर्ण स्क्रीन <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> सह शेअर करत आहात"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"तुम्ही सध्या तुमची संपूर्ण स्क्रीन एका ॲपसह शेअर करत आहात"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"तुम्ही सध्या <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> शेअर करत आहात"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"तुम्ही सध्या एक ॲप शेअर करत आहात"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"तुम्ही सध्या एक ॲप शेअर करत आहात"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"शेअर करणे थांबवा"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"स्क्रीन कास्ट करत आहे"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"कास्ट करणे थांबवायचे आहे का?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"लॉक स्क्रीन विजेट"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"तुमचा टॅबलेट लॉक केला, तरी कोणीही तुमच्या लॉक स्क्रीनवरील विजेट पाहू शकतो."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"विजेटची निवड रद्द करा"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"उंची कमी करा"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"उंची वाढवा"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लॉक स्क्रीन विजेट"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट वापरून अॅप उघडण्यासाठी, तुम्हाला हे तुम्हीच असल्याची पडताळणी करावी लागेल. तसेच, लक्षात ठेवा, तुमचा टॅबलेट लॉक असतानादेखील कोणीही ती पाहू शकते. काही विजेट कदाचित तुमच्या लॉक स्क्रीनसाठी नाहीत आणि ती इथे जोडणे असुरक्षित असू शकते."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"समजले"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"आता सुरू करा"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"सूचना नाहीत"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"नवीन सूचना नाहीत"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"नोटिफिकेशन कूलडाउन सुरू आहे"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"एकाच वेळी अनेक नोटिफिकेशन मिळाल्यास, डिव्हाइसचा आवाज आणि सूचना आपोआप कमाल २ मिनिटांपर्यंत कमी होतात."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"बंद करा"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"जुन्या सूचना पाहण्यासाठी अनलॉक करा"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"निश्चित केला आहे"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्रॅकिंग"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलण्यासाठी टॅप करा"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करा"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"म्यूट काढून टाका"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"व्हायब्रेट करा"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"सध्याचे अॅप"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"अॅक्सेसिबिलिटी"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट कस्टमाइझ करा"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शोधण्यासाठी शॉर्टकट"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कोणतेही शोध परिणाम नाहीत"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"कोलॅप्स करा आयकन"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"कस्टमाइझ करा"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"पूर्ण झाले"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"विस्तार करा आयकन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"किंवा"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्रॅग हॅंडल"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"अॅप्सद्वारे पुरवलेले"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"डिस्प्ले"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"अज्ञात"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"टाइल रीसेट करा"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"टाइल त्यांच्या मूळ क्रमानुसार आणि मूळ आकारांमध्ये रीसेट करायच्या आहेत का?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"सर्व टाइल रीसेट करायच्या?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"सर्व क्विक सेटिंग्ज टाइल डिव्हाइसच्या मूळ सेटिंग्जवर रीसेट केल्या जातील"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 087c8a6..bc01916 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rakam skrin anda?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rakam satu apl"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rakam seluruh skrin"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Rakam keseluruhan skrin: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Apabila anda merakam seluruh skrin anda, apa-apa sahaja yang dipaparkan pada skrin anda akan dirakam. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Apabila anda merakam apl, apa-apa sahaja yang dipaparkan atau dimainkan dalam apl tersebut akan dirakam. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rakam skrin"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Anda sedang merakam <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Hentikan rakaman"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Berkongsi skrin"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Berkongsi kandungan"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Hentikan perkongsian skrin?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Hentikan perkongsian?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Anda sedang berkongsi seluruh skrin anda dengan <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Anda sedang berkongsi seluruh skrin anda dengan apl"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Anda sedang berkongsi <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Anda sedang berkongsi apl"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Anda sedang berkongsi dengan apl"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Hentikan perkongsian"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Menghantar skrin"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Hentikan penghantaran?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widget skrin kunci"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Sesiapa sahaja boleh melihat widget pada skrin kunci, walaupun tablet dikunci."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"nyahpilih widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Kurangkan ketinggian"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Tambahkan ketinggian"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget skrin kunci"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka apl menggunakan widget, anda perlu mengesahkan identiti anda. Selain itu, perlu diingat bahawa sesiapa sahaja boleh melihat widget tersebut, walaupun semasa tablet anda dikunci. Sesetengah widget mungkin tidak sesuai untuk skrin kunci anda dan mungkin tidak selamat untuk ditambahkan di sini."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Kosongkan semua"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Urus"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Sejarah"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Tetapan pemberitahuan"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Sejarah pemberitahuan"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Baharu"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Senyap"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Pemberitahuan"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Mulakan sekarang"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Tiada pemberitahuan"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Tiada pemberitahuan baharu"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Tempoh bertenang pemberitahuan dihidupkan"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Kelantangan, makluman peranti dikurangkan secara automatik hingga 2 minit apabila menerima banyak pemberitahuan serentak."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Matikan"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Buka kunci untuk melihat pemberitahuan lama"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Tetap"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Penjejakan Kepala"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Ketik untuk menukar mod pendering"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"redam"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"nyahredam"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"getar"</string>
@@ -1415,20 +1410,17 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Apl Semasa"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kebolehaksesan"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan papan kekunci"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sesuaikan pintasan papan kekunci"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan carian"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tiada hasil carian"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kuncupkan ikon"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sesuaikan"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Selesai"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kembangkan ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Pemegang seret"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tetapan Papan Kekunci"</string>
- <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigasi menggunakan papan kekunci anda"</string>
+ <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigasi menggunakan papan kekunci"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ketahui pintasan papan kekunci"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigasi menggunakan pad sentuh anda"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Ketahui gerak isyarat pad sentuh"</string>
@@ -1462,7 +1454,7 @@
<string name="back_edu_toast_content" msgid="4530314597378982956">"Untuk kembali, leret ke kiri atau ke kanan dengan tiga jari pada pad sentuh"</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"Untuk mengakses laman utama, leret ke atas dengan tiga jari pada pad sentuh"</string>
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Untuk melihat apl terbaharu, leret ke atas dan tahan dengan tiga jari pada pad sentuh"</string>
- <string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Untuk melihat semua apl anda, tekan kekunci tindakan pada papan kekunci anda"</string>
+ <string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Untuk melihat semua apl, tekan kekunci tindakan pada papan kekunci"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Disunting"</string>
<string name="redacted_notification_single_line_text" msgid="8684166405005242945">"Buka kunci untuk melihat"</string>
<string name="contextual_education_dialog_title" msgid="4630392552837487324">"Pendidikan kontekstual"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Disediakan oleh apl"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Paparan"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Tidak diketahui"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Tetapkan semula jubin"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Tetapkan semula jubin kepada urutan dan saiz yang asal?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Tetapkan semula semua jubin?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Semua jubin Tetapan Pantas akan ditetapkan semula kepada tetapan asal peranti"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index d456bca..55626f0 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ဖန်သားပြင်ကို ရိုက်ကူးမလား။"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"အက်ပ်တစ်ခုကို ရိုက်ကူးရန်"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ဖန်သားပြင်တစ်ခုလုံးကို ရိုက်ကူးရန်"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ဖန်သားပြင်တစ်ခုလုံးကို ရိုက်ကူးရန်- %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"သင့်ဖန်သားပြင်တစ်ခုလုံး ရိုက်ကူးနေချိန်တွင် ဖန်သားပြင်တွင် ပြထားသည့် အရာအားလုံးကို ရိုက်ကူးသည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"အက်ပ်ကို ရိုက်ကူးနေချိန်တွင် ယင်းအက်ပ်တွင် ပြထားသော (သို့) ဖွင့်ထားသော အရာအားလုံးကို ရိုက်ကူးသည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ဖန်သားပြင်ကို ရိုက်ကူးရန်"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"သင်သည် လက်ရှိတွင် <xliff:g id="APP_NAME">%1$s</xliff:g> ကို ရိုက်ကူးနေသည်"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ရိုက်ကူးမှု ရပ်ရန်"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ဖန်သားပြင်ကို မျှဝေနေသည်"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"အကြောင်းအရာကို မျှဝေနေသည်"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ဖန်သားပြင်မျှဝေခြင်း ရပ်မလား။"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"မျှဝေခြင်းကို ရပ်မလား။"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"သင်သည် လက်ရှိတွင် <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ဖြင့် ဖန်သားပြင်တစ်ခုလုံးကို မျှဝေနေသည်"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"သင်သည် လက်ရှိတွင် အက်ပ်တစ်ခုဖြင့် ဖန်သားပြင်တစ်ခုလုံးကို မျှဝေနေသည်"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"သင်သည် လက်ရှိတွင် <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ကို မျှဝေနေသည်"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"သင်သည် လက်ရှိတွင် အက်ပ်ကို မျှဝေနေသည်"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"သင်သည် လက်ရှိတွင် အက်ပ်ဖြင့် မျှဝေနေသည်"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"မျှဝေခြင်း ရပ်ရန်"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ဖန်သားပြင်ကို ကာစ်လုပ်နေသည်"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ကာစ်လုပ်ခြင်းကို ရပ်လိုသလား။"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"လော့ခ်မျက်နှာပြင် ဝိဂျက်များ"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"တက်ဘလက်လော့ခ်ချထားသော်လည်း မည်သူမဆို လော့ခ်မျက်နှာပြင်ဝိဂျက်ကို ကြည့်နိုင်သည်။"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ဝိဂျက် ပြန်ဖြုတ်ရန်"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"အမြင့်ကို လျှော့ရန်"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"အမြင့်ကို တိုးရန်"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"လော့ခ်မျက်နှာပြင် ဝိဂျက်များ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ဝိဂျက်သုံး၍ အက်ပ်ဖွင့်ရန်အတွက် သင်ဖြစ်ကြောင်း အတည်ပြုရန်လိုသည်။ ထို့ပြင် သင့်တက်ဘလက် လော့ခ်ချထားချိန်၌ပင် မည်သူမဆို ၎င်းတို့ကို ကြည့်နိုင်ကြောင်း သတိပြုပါ။ ဝိဂျက်အချို့ကို လော့ခ်မျက်နှာပြင်အတွက် ရည်ရွယ်ထားခြင်း မရှိသဖြင့် ဤနေရာတွင် ထည့်ပါက မလုံခြုံနိုင်ပါ။"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"နားလည်ပြီ"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"အားလုံးရှင်းရန်"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"စီမံရန်"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"မှတ်တမ်း"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"အကြောင်းကြားချက် ဆက်တင်များ"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"အကြောင်းကြားချက် မှတ်တမ်း"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"အသစ်"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"အသံတိတ်ခြင်း"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"အကြောင်းကြားချက်များ"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"အကြောင်းကြားချက် မရှိပါ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"အကြောင်းကြားချက်သစ် မရှိပါ"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"အကြောင်းကြားချက် သတိပေးမှု လျှော့ချခြင်း ဖွင့်ထားသည်"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"အကြောင်းကြားချက်များစွာ တစ်ပြိုင်နက်ရပါက သင့်စက်၏ အသံနှင့် သတိပေးချက်ကို ၂ မိနစ်ကြာသည်အထိ အလိုအလျောက်လျှော့ချသည်။"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ပိတ်ရန်"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"အကြောင်းကြားချက်ဟောင်းကြည့်ရန် လော့ခ်ဖွင့်ပါ"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ပုံသေ"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ခေါင်းလှုပ်ရှားမှု"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ဖုန်းခေါ်သံမုဒ်သို့ ပြောင်းရန် တို့ပါ"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"အသံပိတ်ရန်"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"အသံဖွင့်ရန်"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"တုန်ခါမှု"</string>
@@ -860,9 +855,9 @@
<string name="group_system_go_back" msgid="2730322046244918816">"ပြန်သွားရန်"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"ပင်မစာမျက်နှာသို့သွားရန်"</string>
<string name="group_system_overview_open_apps" msgid="5659958952937994104">"မကြာသေးမီကအက်ပ်များ ကြည့်ရန်"</string>
- <string name="group_system_cycle_forward" msgid="5478663965957647805">"မကြာသေးမီက အက်ပ်များကို အဝိုင်းပုံရှေ့သို့လှည့်ရန်"</string>
- <string name="group_system_cycle_back" msgid="8194102916946802902">"မကြာသေးမီက အက်ပ်များကို အဝိုင်းပုံနောက်ပြန်လှည့်ရန်"</string>
- <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"အက်ပ်ပြသမှု ဖွင့်ရန်"</string>
+ <string name="group_system_cycle_forward" msgid="5478663965957647805">"လတ်တလော အက်ပ်များတလျှောက် ရှေ့သို့လှည့်ရန်"</string>
+ <string name="group_system_cycle_back" msgid="8194102916946802902">"လတ်တလော အက်ပ်များတလျှောက် နောက်ပြန်လှည့်ရန်"</string>
+ <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"အက်ပ်စာရင်း ဖွင့်ရန်"</string>
<string name="group_system_access_system_settings" msgid="8731721963449070017">"ဆက်တင်များ ဖွင့်ရန်"</string>
<string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ဖွင့်ရန်"</string>
<string name="group_system_lock_screen" msgid="7391191300363416543">"လော့ခ်မျက်နှာပြင်"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"လက်ရှိအက်ပ်"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"အများသုံးနိုင်မှု"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"လက်ကွက်ဖြတ်လမ်းများ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ရှာဖွေစာလုံး ဖြတ်လမ်း"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"လက်ကွက်ဖြတ်လမ်းများကို စိတ်ကြိုက်လုပ်ခြင်း"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ဖြတ်လမ်းများ ရှာရန်"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ရှာဖွေမှုရလဒ် မရှိပါ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"လျှော့ပြရန် သင်္ကေတ"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"စိတ်ကြိုက်လုပ်ရန်"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ပြီးပြီ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ပိုပြရန် သင်္ကေတ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"သို့မဟုတ်"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ဖိဆွဲအထိန်း"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"အက်ပ်များက ပံ့ပိုးထားသည်"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ဖန်သားပြင်"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"အမျိုးအမည်မသိ"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"အကွက်ငယ်များ ပြင်ဆင်သတ်မှတ်ခြင်း"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"အကွက်ငယ်များကို ၎င်းတို့၏ မူလအစီအစဉ်နှင့် အရွယ်အစားများသို့ ပြင်ဆင်သတ်မှတ်မလား။"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"အကွက်ငယ်အားလုံးကို ပြင်ဆင်သတ်မှတ်မလား။"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"အမြန်ဆက်တင်များ အကွက်ငယ်အားလုံးကို စက်ပစ္စည်း၏ မူရင်းဆက်တင်များသို့ ပြင်ဆင်သတ်မှတ်ပါမည်"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 1fbb35b0..9420185 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vil du ta opp skjermen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ta opp én app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Ta opp hele skjermen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Ta opp hele skjermen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Når du tar opp hele skjermen, blir alt som vises på skjermen, tatt opp. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Når du tar opp en app, blir alt som vises eller spilles av i appen, tatt opp. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ta opp skjermen"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Du tar nå opp <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stopp opptaket"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deler skjermen"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Deler innhold"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vil du slutte å dele skjermen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Vil du slutte å dele?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Du deler nå hele skjermen med <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Du deler nå hele skjermen med en app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Du deler nå <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Du deler nå en app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Du deler med en app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Slutt å dele"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Caster skjermen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vil du stoppe castingen?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Moduler på låseskjermen"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Hvem som helst kan se moduler på låseskjermen – selv om nettbrettet er låst."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"velg bort modul"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Reduser høyden"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Øk høyden"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Låseskjermmoduler"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"For å åpne en app ved hjelp av en modul må du bekrefte at det er deg. Husk også at hvem som helst kan se dem, selv om nettbrettet er låst. Noen moduler er kanskje ikke laget for å være på låseskjermen og kan være utrygge å legge til der."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Greit"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Fjern alt"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Logg"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Varslingsinnstillinger"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Varsellogg"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Ny"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Lydløs"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Varsler"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen varsler"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye varsler"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Varseldemping er slått på"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Enhetsvolumet og varsler reduseres automatisk i opptil 2 min når du får for mange varsler samtidig."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slå av"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås opp for å se eldre varsler"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fast"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hodesporing"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Trykk for å endre ringemodus"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"kutt lyden"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på lyden"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrer"</string>
@@ -964,7 +959,7 @@
<string name="data_connection_no_internet" msgid="691058178914184544">"Ingen internettilkobling"</string>
<string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Åpne <xliff:g id="ID_1">%s</xliff:g>-innstillingene."</string>
<string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Endre rekkefølgen på innstillingene."</string>
- <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"På/av-meny"</string>
+ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Av/på-meny"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskjerm"</string>
<string name="finder_active" msgid="7907846989716941952">"Du kan finne denne telefonen med Finn enheten min, selv når den er slått av"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktiv app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tilgjengelighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Hurtigtaster"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpass hurtigtastene"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snarveier til søk"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ingen søkeresultater"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Skjul-ikon"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tilpass"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Ferdig"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Vis-ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtak"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Levert av apper"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Skjerm"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ukjent"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Tilbakestill brikkene"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Vil du tilbakestille brikkene til den opprinnelige rekkefølgen og størrelsen?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vil du tilbakestille alle brikkene?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle brikker for hurtiginnstillinger tilbakestilles til enhetens opprinnelige innstillinger"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 381118a..54644eb 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"तपाईंको स्क्रिन रेकर्ड गर्ने हो?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एउटा एप रेकर्ड गर्नुहोस्"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूरै स्क्रिन रेकर्ड गर्नुहोस्"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"सम्पूर्ण स्क्रिन रेकर्ड गर्नुहोस्: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तपाईंले आफ्नो पूरै स्क्रिन रेकर्ड गरिरहेका बेला तपाईंको स्क्रिनमा देखाइने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तपाईंले यो एप रेकर्ड गरिरहेका बेला यो एपमा देखाइने वा प्ले गरिने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रिन रेकर्ड गर्नुहोस्"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"तपाईं अहिले <xliff:g id="APP_NAME">%1$s</xliff:g> रेकर्ड गरिरहनुभएको छ"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"रेकर्ड गर्न छाड्नुहोस्"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रिन सेयर गरिँदै छ"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"सामग्री सेयर गरिँदै छ"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"स्क्रिन सेयर गर्न छाड्ने हो?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"सेयर गर्न छाड्ने हो?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"तपाईं अहिले <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> सँग आफ्नो डिभाइसको पूरै स्क्रिन सेयर गरिरहनुभएको छ"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"तपाईं अहिले कुनै एपसँग आफ्नो डिभाइसको पूरै स्क्रिन सेयर गरिरहनुभएको छ"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"तपाईं अहिले <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> सेयर गरिरहनुभएको छ"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"तपाईं अहिले कुनै एप सेयर गरिरहनुभएको छ"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"तपाईं अहिले एपसँग सेयर गरिरहनुभएको छ"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"सेयर गर्न छाड्नुहोस्"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"स्क्रिन कास्ट गरिँदै छ"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"कास्ट गर्न छाड्ने हो?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"लक स्क्रिन विजेटहरू"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"तपाईंको ट्याब्लेट लक भएका बेला पनि सबैले लक स्क्रिनमा भएका विजेट हेर्न सक्छन्।"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"विजेटको चयन रद्द गर्नुहोस्"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"उचाइ घटाउनुहोस्"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"उचाइ बढाउनुहोस्"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"लक स्क्रिन विजेटहरू"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट प्रयोग गरी एप खोल्न तपाईंले आफ्नो पहिचान पुष्टि गर्नु पर्ने हुन्छ। साथै, तपाईंको ट्याब्लेट लक भएका बेला पनि सबै जनाले तिनलाई देख्न सक्छन् भन्ने कुरा ख्याल गर्नुहोस्। केही विजेटहरू लक स्क्रिनमा प्रयोग गर्ने उद्देश्यले नबनाइएका हुन सक्छन् र तिनलाई यहाँ हाल्नु सुरक्षित नहुन सक्छ।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"बुझेँ"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"सबै हटाउनुहोस्"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थित गर्नुहोस्"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"हिस्ट्री"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"नोटिफिकेसन सेटिङ"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"नोटिफिकेसनसम्बन्धी हिस्ट्री"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"नयाँ"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"साइलेन्ट"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाहरू"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"अहिले न"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"कुनै सूचनाहरू छैनन्"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"कुनै पनि नयाँ सूचना छैन"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"नोटिफिकेसन कुलडाउन अन छ"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"तपाईंले एकै पटक धेरै नोटिफिकेसन प्राप्त गर्दा बढीमा २ मिनेटसम्म तपाईंको डिभाइसको भोल्युम र अलर्टहरूको सङ्ख्या स्वतः घटाइन्छ।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"अफ गर्नुहोस्"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"पुराना सूचनाहरू हेर्न अनलक गर्नुहोस्"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"निश्चित"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्र्याकिङ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"रिङ्गर मोड बदल्न ट्याप गर्नुहोस्"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्युट गर्नुहोस्"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्युट गर्नुहोस्"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"कम्पन गर्नुहोस्"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"हालको एप"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सर्वसुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"किबोर्डका सर्टकटहरू"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"किबोर्डका सर्टकटहरू कस्टमाइज गर्नुहोस्"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"खोजका सर्टकटहरू"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कुनै पनि खोज परिणाम भेटिएन"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\"कोल्याप्स गर्नुहोस्\" आइकन"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"कस्टमाइज गर्नुहोस्"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"पूरा भयो"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\"एक्स्पान्ड गर्नुहोस्\" आइकन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"वा"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्र्याग ह्यान्डल"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"एपले उपलब्ध गराएका"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"डिस्प्ले"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"अज्ञात"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"टाइलहरू रिसेट गर्नुहोस्"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"टाइलहरूको डिफल्ट क्रम र आकार रिसेट गर्ने हो?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"सबै टाइलहरू रिसेट गर्ने हो?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"द्रुत सेटिङका सबै टाइलहरू रिसेट गरी डिभाइसका मूल सेटिङ लागू गरिने छन्"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 8ff59ee..4c9eeb8 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Je scherm opnemen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Eén app opnemen"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Hele scherm opnemen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Hele scherm opnemen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Als je je hele scherm opneemt, wordt alles opgenomen wat op je scherm wordt getoond. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Als je een app opneemt, wordt alles opgenomen wat wordt getoond of afgespeeld in die app. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Scherm opnemen"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Je neemt op dit moment <xliff:g id="APP_NAME">%1$s</xliff:g> op"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Opname stoppen"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Scherm delen"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Content delen"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Scherm delen stoppen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Delen stoppen?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Je deelt op dit moment je hele scherm met <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Je deelt op dit moment je hele scherm met een app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Je deelt op dit moment <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Je deelt op dit moment een app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Je deelt op dit moment met een app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Delen stoppen"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Scherm casten"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stoppen met casten?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets op het vergrendelscherm"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Iedereen kan widgets op je vergrendelscherm bekijken, ook als je tablet vergrendeld is."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"widget deselecteren"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Hoogte verkleinen"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Hoogte vergroten"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets op het vergrendelscherm"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Als je een app wilt openen met een widget, moet je verifiëren dat jij het bent. Houd er ook rekening mee dat iedereen ze kan bekijken, ook als je tablet vergrendeld is. Bepaalde widgets zijn misschien niet bedoeld voor je vergrendelscherm en kunnen hier niet veilig worden toegevoegd."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Nu starten"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Geen meldingen"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Geen nieuwe meldingen"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Afkoelperiode van meldingen staat aan"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Als je te veel meldingen tegelijk krijgt, worden het volume op je apparaat en meldingen automatisch maximaal 2 minuten beperkt."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Uitzetten"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ontgrendel om oudere meldingen te zien"</string>
@@ -703,6 +698,7 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Vast"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hoofdtracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tik om de beltoonmodus te wijzigen"</string>
+ <string name="volume_ringer_mode" msgid="6867838048430807128">"beltoonmodus"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"geluid uit"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"geluid aanzetten"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"trillen"</string>
@@ -1409,19 +1405,16 @@
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recente apps"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Gesplitst scherm"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Invoer"</string>
- <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-snelkoppelingen"</string>
+ <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-sneltoetsen"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Huidige app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toegankelijkheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Sneltoetsen"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snelkoppelingen voor zoekopdrachten"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sneltoetsen aanpassen"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sneltoetsen zoeken"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen zoekresultaten"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icoon voor samenvouwen"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Aanpassen"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klaar"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icoon voor uitvouwen"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"of"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handgreep voor slepen"</string>
@@ -1483,6 +1476,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Geleverd door apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Scherm"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Onbekend"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Tegels resetten"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Tegels resetten naar de oorspronkelijke volgorde en grootte?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Alle tegels resetten?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alle tegels voor Snelle instellingen worden teruggezet naar de oorspronkelijke instellingen van het apparaat"</string>
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 6086440..7473ff58 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ ରେକର୍ଡ କରିବେ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ଗୋଟିଏ ଆପ ରେକର୍ଡ କରନ୍ତୁ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ ରେକର୍ଡ କରନ୍ତୁ"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ରେକର୍ଡ କରନ୍ତୁ: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ଆପଣ ଆପଣଙ୍କର ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ ରେକର୍ଡ କରିବା ସମୟରେ, ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା ସବୁକିଛି ରେକର୍ଡ ହୋଇଥାଏ। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ଆପଣ ଏକ ଆପ ରେକର୍ଡ କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛି ରେକର୍ଡ ହୋଇଥାଏ। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ସ୍କ୍ରିନ ରେକର୍ଡ କରନ୍ତୁ"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"ଆପଣ ବର୍ତ୍ତମାନ <xliff:g id="APP_NAME">%1$s</xliff:g>ର ବିଷୟବସ୍ତୁକୁ ରେକର୍ଡ କରୁଛନ୍ତି"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ରେକର୍ଡିଂ ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ସ୍କ୍ରିନ ସେୟାର କରାଯାଉଛି"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"ବିଷୟବସ୍ତୁ ସେୟାର କରାଯାଉଛି"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ସ୍କ୍ରିନ ସେୟାର କରିବା ବନ୍ଦ କରିବେ?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"ସେୟାର କରିବା ବନ୍ଦ କରିବେ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"ଆପଣ ବର୍ତ୍ତମାନ ଆପଣଙ୍କର ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ସହ ସେୟାର କରୁଛନ୍ତି"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"ଆପଣ ବର୍ତ୍ତମାନ ଆପଣଙ୍କର ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ଏକ ଆପ ସହ ସେୟାର କରୁଛନ୍ତି"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"ଆପଣ ବର୍ତ୍ତମାନ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>କୁ ସେୟାର କରୁଛନ୍ତି"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"ଆପଣ ବର୍ତ୍ତମାନ ଏକ ଆପକୁ ସେୟାର କରୁଛନ୍ତି"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"ଆପଣ ବର୍ତ୍ତମାନ ଏକ ଆପ ସହ ସେୟାର କରୁଛନ୍ତି"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ସେୟାର କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ସ୍କ୍ରିନ କାଷ୍ଟ କରାଯାଉଛି"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ଲକ ସ୍କ୍ରିନ ୱିଜେଟ"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"ଆପଣଙ୍କ ଟାବଲେଟ ଲକ ଥିଲେ ମଧ୍ୟ ଯେ କୌଣସି ବ୍ୟକ୍ତି ଲକ ସ୍କ୍ରିନରେ ୱିଜେଟକୁ ଭ୍ୟୁ କରିପାରିବେ।"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ୱିଜେଟକୁ ଅଚୟନ କରନ୍ତୁ"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ଉଚ୍ଚତାକୁ କମ କରନ୍ତୁ"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ଉଚ୍ଚତାକୁ ବଢ଼ାନ୍ତୁ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ଲକ ସ୍କ୍ରିନ ୱିଜେଟ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ଏକ ୱିଜେଟ ବ୍ୟବହାର କରି ଗୋଟିଏ ଆପ ଖୋଲିବା ପାଇଁ ଏହା ଆପଣ ଅଟନ୍ତି ବୋଲି ଆପଣଙ୍କୁ ଯାଞ୍ଚ କରିବାକୁ ହେବ। ଆହୁରି ମଧ୍ୟ, ଆପଣଙ୍କ ଟାବଲେଟ ଲକ ଥିଲେ ମଧ୍ୟ ଯେ କୌଣସି ବ୍ୟକ୍ତି ଏହାକୁ ଭ୍ୟୁ କରିପାରିବେ ବୋଲି ମନେ ରଖନ୍ତୁ। କିଛି ୱିଜେଟ ଆପଣଙ୍କ ଲକ ସ୍କ୍ରିନ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ହୋଇନଥାଇପାରେ ଏବଂ ଏଠାରେ ଯୋଗ କରିବା ଅସୁରକ୍ଷିତ ହୋଇପାରେ।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ବୁଝିଗଲି"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"ସବୁ ଖାଲି କରନ୍ତୁ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ଇତିହାସ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"ବିଜ୍ଞପ୍ତି ସେଟିଂସ"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"ବିଜ୍ଞପ୍ତି ଇତିହାସ"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"ନୂଆ"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ନୀରବ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"କୌଣସି ନୂଆ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ନାହିଁ"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"ବିଜ୍ଞପ୍ତି କୁଲଡାଉନ ଚାଲୁ ଅଛି"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ଆପଣ ଥରକେ ଏକାଧିକ ବିଜ୍ଞପ୍ତି ପ୍ରାପ୍ତ କଲେ ଆପଣଙ୍କ ଡିଭାଇସର ଭଲ୍ୟୁମ ଓ ଆଲର୍ଟ ସ୍ୱତଃ 2 ମିନିଟ ପର୍ଯ୍ୟନ୍ତ କମ ହୁଏ।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ପୁରୁଣା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖିବାକୁ ଅନଲକ କରନ୍ତୁ"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ନିଶ୍ଚିତ ହୋଇଛି"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ହେଡ ଟ୍ରାକିଂ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ରିଙ୍ଗର୍ ମୋଡ୍ ବଦଳାଇବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ମ୍ୟୁଟ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ଅନ୍-ମ୍ୟୁଟ୍ କରନ୍ତୁ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ଭାଇବ୍ରେଟ୍"</string>
@@ -814,9 +809,9 @@
<string name="keyboard_key_home" msgid="3734400625170020657">"ହୋମ"</string>
<string name="keyboard_key_back" msgid="4185420465469481999">"ଫେରନ୍ତୁ"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
- <string name="keyboard_key_space" msgid="6980847564173394012">"ସ୍ପେସ୍"</string>
- <string name="keyboard_key_enter" msgid="8633362970109751646">"ଏଣ୍ଟର୍"</string>
- <string name="keyboard_key_backspace" msgid="4095278312039628074">"ବ୍ୟାକସ୍ପେସ୍"</string>
+ <string name="keyboard_key_space" msgid="6980847564173394012">"ସ୍ପେସ"</string>
+ <string name="keyboard_key_enter" msgid="8633362970109751646">"ଏଣ୍ଟର"</string>
+ <string name="keyboard_key_backspace" msgid="4095278312039628074">"ବେକସ୍ପେସ"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"ପ୍ଲେ କରନ୍ତୁ/ପଜ୍ କରନ୍ତୁ"</string>
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"ପରବର୍ତ୍ତୀ"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ବର୍ତ୍ତମାନର ଆପ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ଆକ୍ସେସିବିଲିଟୀ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"କୀବୋର୍ଡ ସର୍ଟକଟ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"କୀବୋର୍ଡ ସର୍ଟକଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ସର୍ଚ୍ଚ ସର୍ଟକଟ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"କୌଣସି ସର୍ଚ୍ଚ ଫଳାଫଳ ନାହିଁ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ଆଇକନକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ହୋଇଗଲା"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ଆଇକନକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"କିମ୍ବା"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ଡ୍ରାଗ ହେଣ୍ଡେଲ"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ଆପ୍ସ ଦ୍ୱାରା ପ୍ରଦାନ କରାଯାଇଛି"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ଡିସପ୍ଲେ"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ଅଜଣା"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"ଟାଇଲଗୁଡ଼ିକୁ ରିସେଟ କରନ୍ତୁ"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"ଟାଇଲଗୁଡ଼ିକୁ ସେଗୁଡ଼ିକର ମୂଳ କ୍ରମ ଏବଂ ସାଇଜ ଅନୁସାରେ ରିସେଟ କରିବେ?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ସମସ୍ତ ଟାଇଲକୁ ରିସେଟ କରିବେ?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ସମସ୍ତ କୁଇକ ସେଟିଂସ ଟାଇଲ ଡିଭାଇସର ମୂଳ ସେଟିଂସରେ ରିସେଟ ହୋଇଯିବ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index b99986a..700bb1c 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ਕੀ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨਾ ਹੈ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ਇੱਕ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰੋ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰੋ"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ਸਾਰੀ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਕਰੋ: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ਜਦੋਂ ਤੁਸੀਂ ਆਪਣੀ ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰ ਰਹੇ ਹੁੰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਖਾਈ ਜਾ ਰਹੀ ਹਰ ਚੀਜ਼ ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਨਾਲ ਹੀ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ਜਦੋਂ ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰ ਰਹੇ ਹੁੰਦੇ ਹੋ, ਤਾਂ ਉਸ ਐਪ ਵਿੱਚ ਦਿਖਾਈ ਜਾਂ ਚਲਾਈ ਜਾ ਰਹੀ ਹਰ ਚੀਜ਼ ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਕਰੋ"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"ਤੁਸੀਂ ਫ਼ਿਲਹਾਲ <xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਰਿਕਾਰਡ ਕਰ ਰਹੇ ਹੋ"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ਰਿਕਾਰਡਿੰਗ ਬੰਦ ਕਰੋ"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ਸਕ੍ਰੀਨ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"ਸਮੱਗਰੀ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"ਕੀ ਸਕ੍ਰੀਨ ਨੂੰ ਸਾਂਝਾ ਕਰਨਾ ਬੰਦ ਕਰਨਾ ਹੈ?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"ਕੀ ਸਾਂਝਾਕਰਨ ਬੰਦ ਕਰਨਾ ਹੈ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"ਤੁਸੀਂ ਫ਼ਿਲਹਾਲ <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ਨਾਲ ਆਪਣੀ ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਸਾਂਝਾ ਕਰ ਰਹੇ ਹੋ"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"ਤੁਸੀਂ ਫ਼ਿਲਹਾਲ ਕਿਸੇ ਐਪ ਨਾਲ ਆਪਣੀ ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਸਾਂਝਾ ਕਰ ਰਹੇ ਹੋ"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"ਤੁਸੀਂ ਫ਼ਿਲਹਾਲ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ਨੂੰ ਸਾਂਝਾ ਕਰ ਰਹੇ ਹੋ"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"ਤੁਸੀਂ ਫ਼ਿਲਹਾਲ ਕਿਸੇ ਐਪ ਨੂੰ ਸਾਂਝਾ ਕਰ ਰਹੇ ਹੋ"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"ਤੁਸੀਂ ਫ਼ਿਲਹਾਲ ਕਿਸੇ ਐਪ ਨਾਲ ਸਾਂਝਾ ਕਰ ਰਹੇ ਹੋ"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"ਸਾਂਝਾਕਰਨ ਬੰਦ ਕਰੋ"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"ਸਕ੍ਰੀਨ \'ਤੇ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ਕੀ ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰਨਾ ਹੈ?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"ਲਾਕ ਸਕ੍ਰੀਨ ਵਿਜੇਟ"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"ਕੋਈ ਵੀ ਤੁਹਾਡੀ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਵਿਜੇਟ ਦੇਖ ਸਕਦਾ ਹੈ, ਭਾਵੇਂ ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਲਾਕ ਹੋਵੇ।"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ਵਿਜੇਟ ਨੂੰ ਅਣਚੁਣਿਆ ਕਰੋ"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ਉਚਾਈ ਘਟਾਓ"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ਉਚਾਈ ਵਧਾਓ"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"ਲਾਕ ਸਕ੍ਰੀਨ ਵਿਜੇਟ"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ਵਿਜੇਟ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਐਪ ਖੋਲ੍ਹਣ ਲਈ, ਤੁਹਾਨੂੰ ਇਹ ਪੁਸ਼ਟੀ ਕਰਨ ਦੀ ਲੋੜ ਪਵੇਗੀ ਕਿ ਇਹ ਤੁਸੀਂ ਹੀ ਹੋ। ਨਾਲ ਹੀ, ਇਹ ਵੀ ਧਿਆਨ ਵਿੱਚ ਰੱਖੋ ਕਿ ਕੋਈ ਵੀ ਉਨ੍ਹਾਂ ਨੂੰ ਦੇਖ ਸਕਦਾ ਹੈ, ਭਾਵੇਂ ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਲਾਕ ਹੋਵੇ। ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਕੁਝ ਵਿਜੇਟ ਤੁਹਾਡੀ ਲਾਕ ਸਕ੍ਰੀਨ ਲਈ ਨਾ ਬਣੇ ਹੋਣ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਇੱਥੇ ਸ਼ਾਮਲ ਕਰਨਾ ਅਸੁਰੱਖਿਅਤ ਹੋਵੇ।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ਸਮਝ ਲਿਆ"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ਕੋਈ ਨਵੀਂ ਸੂਚਨਾ ਨਹੀਂ ਹੈ"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"ਨੋਟੀਫ਼ਿਕੇਸ਼ਨ ਕੂਲਡਾਊਨ ਚਾਲੂ ਹੈ"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ਇੱਕ ਵਾਰ \'ਚ ਕਈ ਸੂਚਨਾਵਾਂ ਮਿਲਣ \'ਤੇ, ਡੀਵਾਈਸ ਦੀ ਅਵਾਜ਼ ਅਤੇ ਅਲਰਟ ਵੱਧੋ-ਵੱਧ 2 ਮਿੰਟਾਂ ਲਈ ਆਪਣੇ-ਆਪ ਘੱਟ ਜਾਂਦੇ ਹਨ।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ਬੰਦ ਕਰੋ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ਪੁਰਾਣੀਆਂ ਸੂਚਨਾਵਾਂ ਦੇਖਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ਸਥਿਰ"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ਹੈੱਡ ਟਰੈਕਿੰਗ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ਰਿੰਗਰ ਮੋਡ ਨੂੰ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ਮਿਊਟ ਕਰੋ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ਅਣਮਿਊਟ ਕਰੋ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ਥਰਥਰਾਹਟ"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ਮੌਜੂਦਾ ਐਪ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ਪਹੁੰਚਯੋਗਤਾ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ਖੋਜ ਸੰਬੰਧੀ ਸ਼ਾਰਟਕੱਟ"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ਸ਼ਾਰਟਕੱਟ ਖੋਜੋ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ਕੋਈ ਖੋਜ ਨਤੀਜਾ ਨਹੀਂ ਮਿਲਿਆ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ਪ੍ਰਤੀਕ ਨੂੰ ਸਮੇਟੋ"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ਹੋ ਗਿਆ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ਪ੍ਰਤੀਕ ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ਜਾਂ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ਘਸੀਟਣ ਵਾਲਾ ਹੈਂਡਲ"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ਐਪਾਂ ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤਾ ਗਿਆ"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ਡਿਸਪਲੇ"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ਅਗਿਆਤ"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"ਟਾਇਲਾਂ ਨੂੰ ਰੀਸੈੱਟ ਕਰੋ"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"ਕੀ ਟਾਇਲਾਂ ਨੂੰ ਉਨ੍ਹਾਂ ਦੇ ਮੂਲ ਕ੍ਰਮ ਅਤੇ ਆਕਾਰਾਂ \'ਤੇ ਰੀਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"ਕੀ ਸਾਰੀਆਂ ਟਾਇਲਾਂ ਨੂੰ ਰੀਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"ਸਾਰੀਆਂ ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਟਾਇਲਾਂ ਡੀਵਾਈਸ ਦੀਆਂ ਮੂਲ ਸੈਟਿੰਗਾਂ \'ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਣਗੀਆਂ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 88177ac..9b03958 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Nagrywać ekran?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Nagrywaj jedną aplikację"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Nagrywaj cały ekran"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Nagraj cały ekran: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kiedy nagrywasz cały ekran, nagrane zostanie wszystko, co jest na nim widoczne. Dlatego uważaj na hasła, dane do płatności, wiadomości, zdjęcia, nagrania audio czy filmy."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kiedy nagrywasz aplikację, wszystko, co jest w niej wyświetlane lub odtwarzane, zostaje nagrane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Nagrywaj ekran"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Obecnie nagrywasz widok aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zatrzymaj nagrywanie"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Udostępniam ekran"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Udostępniasz treści"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Zatrzymać udostępnianie ekranu?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Przestać udostępniać?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Obecnie udostępniasz aplikacji <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> cały widok ekranu"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Obecnie udostępniasz aplikacji cały widok ekranu"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Obecnie udostępniasz aplikację <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Obecnie udostępniasz aplikację"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Obecnie udostępniasz treści aplikacji"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Zatrzymaj udostępnianie"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Przesyłam zawartość ekranu"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Zatrzymać przesyłanie?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widżety na ekranie blokady"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Widżety są widoczne na ekranie blokady, nawet gdy tablet jest zablokowany."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"odznacz widżet"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Zmniejsz wysokość"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Zwiększ wysokość"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widżety na ekranie blokady"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aby otworzyć aplikację za pomocą widżetu, musisz potwierdzić swoją tożsamość. Pamiętaj też, że każdy będzie mógł wyświetlić widżety nawet wtedy, gdy tablet będzie zablokowany. Niektóre widżety mogą nie być przeznaczone do umieszczenia na ekranie blokady i ich dodanie w tym miejscu może być niebezpieczne."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Usuń wszystkie"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Zarządzaj"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Ustawienia powiadomień"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historia powiadomień"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nowe"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Ciche"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Powiadomienia"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Rozpocznij teraz"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Brak powiadomień"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Brak nowych powiadomień"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Wyciszanie powiadomień jest włączone"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Gdy w krótkim czasie otrzymasz za dużo powiadomień, dźwięki zostaną automatycznie wyciszone na maks. 2 min."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Wyłącz"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odblokuj i zobacz starsze powiadomienia"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Stały"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Śledzenie głowy"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Kliknij, aby zmienić tryb dzwonka"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"wycisz"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"wyłącz wyciszenie"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"włącz wibracje"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Bieżąca aplikacja"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ułatwienia dostępu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Skróty klawiszowe"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Dostosuj skróty klawiszowe"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Skróty do wyszukiwania"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Brak wyników wyszukiwania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zwijania"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Dostosuj"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotowe"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozwijania"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"lub"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Uchwyt do przeciągania"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Z aplikacji"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Wyświetlacz"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nieznane"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Zresetuj kafelki"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Zresetować kafelki do pierwotnej kolejności i rozmiarów?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Zresetować wszystkie kafelki?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Wszystkie kafelki Szybkich ustawień zostaną zresetowane do oryginalnych ustawień urządzenia"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index e67c168..e882cb8 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Gravar a tela?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar um app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar a tela toda"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gravar a tela toda: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando você grava a tela toda, tudo o que aparece nela é registrado. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando você grava um app, todas as informações visíveis ou abertas nele ficam registradas. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar a tela"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Você está gravando o app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Parar gravação"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartilhando a tela"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Compartilhando conteúdo"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Parar o compartilhamento de tela?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Parar de compartilhar?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Você está compartilhando a tela inteira com o app <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Você está compartilhando a tela inteira com um app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Você está compartilhando o app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Você está compartilhando um app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Você está compartilhando com um app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Interromper compartilhamento"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Transmitindo a tela"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Parar transmissão?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets da tela de bloqueio"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Todos podem ver os widgets na tela de bloqueio, mesmo com o tablet bloqueado."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desmarcar widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuir altura"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar altura"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da tela de bloqueio"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisa confirmar sua identidade. E não se esqueça que qualquer pessoa pode ver os widgets, mesmo com o tablet bloqueado. Além disso, alguns apps não foram criados para a tela de bloqueio, é melhor manter a segurança."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Remover tudo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Configurações de notificação"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Histórico de notificações"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Novas"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silenciosas"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"O recurso de atenuar notificações está ativo"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volume e alertas são reduzidos por até 2 min quando você recebe muitas notificações juntas."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixo"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rastreamento de cabeça"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -843,7 +838,7 @@
<string name="keyboard_shortcut_join" msgid="3578314570034512676">"ou"</string>
<string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Limpar a consulta de pesquisa"</string>
<string name="keyboard_shortcut_search_list_title" msgid="4271769465397671138">"Atalhos do teclado"</string>
- <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Atalhos de pesquisa"</string>
+ <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pesquisar atalhos"</string>
<string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nenhum atalho encontrado"</string>
<string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"Sistema"</string>
<string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrada"</string>
@@ -859,7 +854,7 @@
<string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar atalhos"</string>
<string name="group_system_go_back" msgid="2730322046244918816">"Voltar"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"Ir para a tela inicial"</string>
- <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Conferir os apps recentes"</string>
+ <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Ver os apps recentes"</string>
<string name="group_system_cycle_forward" msgid="5478663965957647805">"Avançar pela lista de apps recentes"</string>
<string name="group_system_cycle_back" msgid="8194102916946802902">"Voltar pela lista de apps recentes"</string>
<string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Abrir lista de apps"</string>
@@ -868,8 +863,8 @@
<string name="group_system_lock_screen" msgid="7391191300363416543">"Tela de bloqueio"</string>
<string name="group_system_quick_memo" msgid="3764560265935722903">"Criar nota"</string>
<string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Multitarefas"</string>
- <string name="system_multitasking_rhs" msgid="8714224917276297810">"Usar a tela dividida com o aplicativo atual à direita"</string>
- <string name="system_multitasking_lhs" msgid="8402954791206308783">"Usar a tela dividida com o app atual à esquerda"</string>
+ <string name="system_multitasking_rhs" msgid="8714224917276297810">"Usar a tela dividida com o app à direita"</string>
+ <string name="system_multitasking_lhs" msgid="8402954791206308783">"Usar a tela dividida com o app à esquerda"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Mudar da tela dividida para a tela cheia"</string>
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atalhos de pesquisa"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
@@ -1461,7 +1453,7 @@
<string name="volume_undo_action" msgid="5815519725211877114">"Desfazer"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"Se quiser voltar, deslize para a esquerda ou direita com três dedos no touchpad"</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"Se quiser acessar a tela inicial, deslize para cima com três dedos no touchpad"</string>
- <string name="overview_edu_toast_content" msgid="5797030644017804518">"Se quiser ver os apps recentes, deslize para cima e pressione com três dedos no touchpad"</string>
+ <string name="overview_edu_toast_content" msgid="5797030644017804518">"Se quiser ver os apps recentes, deslize para cima e pressione o touchpad com três dedos"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Para ver todos os apps, pressione a tecla de ação no teclado"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Encoberto"</string>
<string name="redacted_notification_single_line_text" msgid="8684166405005242945">"Desbloquear para visualizar"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fornecidos por apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Exibição"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecidos"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Redefinir blocos"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Redefinir os blocos para a ordem e os tamanhos originais?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Redefinir todos os blocos?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos os blocos \"Configurações rápidas\" serão redefinidos para as configurações originais do dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 30e16f0..f1bae0e 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Gravar o ecrã?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar uma app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar o ecrã inteiro"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gravar o ecrã inteiro: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando está a gravar o ecrã inteiro, tudo o que é apresentado no ecrã é gravado. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando está a gravar uma app, tudo o que é apresentado ou reproduzido nessa app é gravado. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar ecrã"</string>
@@ -578,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gerir"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Definições de notificação"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Histórico de notificações"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nova"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silencioso"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
@@ -592,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Começar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Não existem novas notificações"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"O repouso das notificações está ativado"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"O volume e os alertas são reduzidos automaticamente durante até 2 minutos quando recebe muitas notificações de uma vez."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie e veja notificações antigas"</string>
@@ -700,6 +698,7 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Corrigido"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Posição da cabeça"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toque para alterar o modo de campainha"</string>
+ <string name="volume_ringer_mode" msgid="6867838048430807128">"modo de som"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar som"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"reativar som"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1410,15 +1409,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos de teclado"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atalhos de pesquisa"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalize os atalhos de teclado"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado da pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone de reduzir"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone de expandir"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Indicador para arrastar"</string>
@@ -1480,6 +1476,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Disponibilizado por apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ecrã"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecido"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Reponha os mosaicos"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Repor os mosaicos para a ordem e os tamanhos originais?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Repor todos os mosaicos?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos os mosaicos de Definições rápidas vão ser repostos para as definições originais do dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index e67c168..e882cb8 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Gravar a tela?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar um app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar a tela toda"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gravar a tela toda: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando você grava a tela toda, tudo o que aparece nela é registrado. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando você grava um app, todas as informações visíveis ou abertas nele ficam registradas. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar a tela"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Você está gravando o app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Parar gravação"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartilhando a tela"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Compartilhando conteúdo"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Parar o compartilhamento de tela?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Parar de compartilhar?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Você está compartilhando a tela inteira com o app <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Você está compartilhando a tela inteira com um app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Você está compartilhando o app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Você está compartilhando um app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Você está compartilhando com um app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Interromper compartilhamento"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Transmitindo a tela"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Parar transmissão?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets da tela de bloqueio"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Todos podem ver os widgets na tela de bloqueio, mesmo com o tablet bloqueado."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desmarcar widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuir altura"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar altura"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets da tela de bloqueio"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisa confirmar sua identidade. E não se esqueça que qualquer pessoa pode ver os widgets, mesmo com o tablet bloqueado. Além disso, alguns apps não foram criados para a tela de bloqueio, é melhor manter a segurança."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Remover tudo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Configurações de notificação"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Histórico de notificações"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Novas"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silenciosas"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"O recurso de atenuar notificações está ativo"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volume e alertas são reduzidos por até 2 min quando você recebe muitas notificações juntas."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixo"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rastreamento de cabeça"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -843,7 +838,7 @@
<string name="keyboard_shortcut_join" msgid="3578314570034512676">"ou"</string>
<string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Limpar a consulta de pesquisa"</string>
<string name="keyboard_shortcut_search_list_title" msgid="4271769465397671138">"Atalhos do teclado"</string>
- <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Atalhos de pesquisa"</string>
+ <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pesquisar atalhos"</string>
<string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nenhum atalho encontrado"</string>
<string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"Sistema"</string>
<string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Entrada"</string>
@@ -859,7 +854,7 @@
<string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar atalhos"</string>
<string name="group_system_go_back" msgid="2730322046244918816">"Voltar"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"Ir para a tela inicial"</string>
- <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Conferir os apps recentes"</string>
+ <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Ver os apps recentes"</string>
<string name="group_system_cycle_forward" msgid="5478663965957647805">"Avançar pela lista de apps recentes"</string>
<string name="group_system_cycle_back" msgid="8194102916946802902">"Voltar pela lista de apps recentes"</string>
<string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Abrir lista de apps"</string>
@@ -868,8 +863,8 @@
<string name="group_system_lock_screen" msgid="7391191300363416543">"Tela de bloqueio"</string>
<string name="group_system_quick_memo" msgid="3764560265935722903">"Criar nota"</string>
<string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Multitarefas"</string>
- <string name="system_multitasking_rhs" msgid="8714224917276297810">"Usar a tela dividida com o aplicativo atual à direita"</string>
- <string name="system_multitasking_lhs" msgid="8402954791206308783">"Usar a tela dividida com o app atual à esquerda"</string>
+ <string name="system_multitasking_rhs" msgid="8714224917276297810">"Usar a tela dividida com o app à direita"</string>
+ <string name="system_multitasking_lhs" msgid="8402954791206308783">"Usar a tela dividida com o app à esquerda"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Mudar da tela dividida para a tela cheia"</string>
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atalhos de pesquisa"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
@@ -1461,7 +1453,7 @@
<string name="volume_undo_action" msgid="5815519725211877114">"Desfazer"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"Se quiser voltar, deslize para a esquerda ou direita com três dedos no touchpad"</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"Se quiser acessar a tela inicial, deslize para cima com três dedos no touchpad"</string>
- <string name="overview_edu_toast_content" msgid="5797030644017804518">"Se quiser ver os apps recentes, deslize para cima e pressione com três dedos no touchpad"</string>
+ <string name="overview_edu_toast_content" msgid="5797030644017804518">"Se quiser ver os apps recentes, deslize para cima e pressione o touchpad com três dedos"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Para ver todos os apps, pressione a tecla de ação no teclado"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"Encoberto"</string>
<string name="redacted_notification_single_line_text" msgid="8684166405005242945">"Desbloquear para visualizar"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Fornecidos por apps"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Exibição"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Desconhecidos"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Redefinir blocos"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Redefinir os blocos para a ordem e os tamanhos originais?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Redefinir todos os blocos?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Todos os blocos \"Configurações rápidas\" serão redefinidos para as configurações originais do dispositivo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index de7f8da..18cb139 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Înregistrezi ecranul?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Înregistrează o aplicație"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Înregistrează tot ecranul"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Înregistrează tot ecranul: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Când înregistrezi întregul ecran, se înregistrează tot ce apare pe ecran. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Când înregistrezi o aplicație, se înregistrează tot ce se afișează sau se redă în aplicație. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Înregistrează ecranul"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Înregistrezi <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Oprește înregistrarea"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Se permite accesul la ecran"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Se permite accesul la conținut"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Oprești accesul la ecran?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Nu mai permiți accesul?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Permiți accesul <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> la întregul ecran"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Permiți accesul unei aplicații la întregul ecran"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Permiți accesul la <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Permiți accesul la o aplicație"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Permiți accesul unei aplicații"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Nu mai permite accesul"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Se proiectează ecranul"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Oprești proiectarea?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgeturi pe ecranul de blocare"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Oricine poate vedea widgeturile pe ecranul de blocare, chiar cu tableta blocată"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"deselectează widgetul"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Redu înălțimea"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Crește înălțimea"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgeturi pe ecranul de blocare"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pentru a deschide o aplicație folosind un widget, va trebui să-ți confirmi identitatea. În plus, reține că oricine poate să vadă widgeturile, chiar dacă tableta este blocată. Este posibil ca unele widgeturi să nu fi fost create pentru ecranul de blocare și poate fi nesigur să le adaugi aici."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Șterge toate notificările"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestionează"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Istoric"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Setări pentru notificări"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Istoricul notificărilor"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Noi"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silențioase"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificări"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Începe acum"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nicio notificare"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nicio notificare nouă"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Reducerea sunetului notificărilor este activată"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volumul și alertele dispozitivului sunt reduse automat timp de până la 2 min. când primești prea multe notificări odată"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Dezactivează"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Deblochează ca să vezi notificări vechi"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fix"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Urmărirea mișcărilor capului"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Atinge pentru a schimba modul soneriei"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"dezactivează sunetul"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activează sunetul"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrații"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicația actuală"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilitate"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Comenzi rapide de la tastatură"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizează comenzile rapide de la tastatură"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Comenzi directe de căutare"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Niciun rezultat al căutării"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Pictograma de restrângere"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizează"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gata"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Pictograma de extindere"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"sau"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ghidaj de tragere"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Oferite de aplicații"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ecran"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Necunoscută"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Resetează cardurile"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Resetezi cardurile la ordinea și dimensiunile inițiale?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Resetezi toate cardurile?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Toate cardurile Setări rapide se vor reseta la setările inițiale ale dispozitivului"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index a007685..ffab1af 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Начать запись экрана?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записывать одно приложение"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записывать весь экран"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Записывать весь экран: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Во время записи всего экрана все данные и действия, которые на нем показываются, попадают на видео. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Во время записи приложения все данные и действия, которые показываются в его окне, попадают на видео. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Запись экрана"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Вы записываете экран приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Остановить запись"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Демонстрация экрана"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Вы делитесь контентом"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Прекратить показ экрана?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Закрыть доступ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Вы демонстрируете свой экран в приложении \"<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>\"."</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Вы демонстрируете свой экран в приложении."</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Вы демонстрируете экран приложения \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\"."</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Вы демонстрируете экран приложения."</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Сейчас вы делитесь контентом с приложением."</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Прекратить показ"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Трансляция экрана"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Прекратить трансляцию?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Виджеты на заблокированном экране"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Они видны всем, даже если планшет заблокирован."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"отменить выбор виджета"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Уменьшить высоту"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Увеличить высоту"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виджеты на заблокированном экране"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Чтобы открыть приложение, используя виджет, вам нужно будет подтвердить свою личность. Обратите внимание, что виджеты видны всем, даже если планшет заблокирован. Некоторые виджеты не предназначены для использования на заблокированном экране. Добавлять их туда может быть небезопасно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ОК"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нет уведомлений."</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Новых уведомлений нет"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Снижение громкости уведомлений включено"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Если придет слишком много уведомлений, на две минуты громкость и количество оповещений уменьшатся."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Отключить"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблокируйте, чтобы увидеть уведомления"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Без отслеживания"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"С отслеживанием"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Нажмите, чтобы изменить режим звонка."</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"отключить звук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"включить звук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"включить вибрацию"</string>
@@ -1409,19 +1406,16 @@
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Недавние приложения"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Разделение экрана"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ввод"</string>
- <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ярлыки приложений"</string>
+ <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Быстрые клавиши для приложений"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Это приложение"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Быстрые клавиши"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Как настроить быстрые клавиши"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Найти быстрые клавиши"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ничего не найдено"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Свернуть\""</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Настроить"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Развернуть\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перемещения"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Приложения"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Экран"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Неизвестно"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Сброс параметров"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Сбросить порядок и размер параметров?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Сбросить все параметры?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Для всех параметров быстрых настроек будут восстановлены значения по умолчанию."</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index ae9c4d0..1b2a2e4 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ඔබේ තිරය පටිගත කරන්න ද?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"එක් යෙදුමක් පටිගත කරන්න"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"සම්පූර්ණ තිරය පටිගත කරන්න"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"සම්පූර්ණ තිරය පටිගත කරන්න: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ඔබ ඔබේ සම්පූර්ණ තිරය පටිගත කරන විට, ඔබේ තිරයේ පෙන්වන ඕනෑම දෙයක් වාර්තා වේ. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්රව්ය සහ දෘශ්ය වැනි දේවල් පිළිබඳ ප්රවේශම් වන්න."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ඔබ යෙදුමක් පටිගත කරන විට, එම යෙදුමේ පෙන්වන හෝ වාදනය කරන ඕනෑම දෙයක් වාර්තා වේ. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්රව්ය සහ දෘශ්ය වැනි දේවල් පිළිබඳ ප්රවේශම් වන්න."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"තිරය පටිගත කරන්න"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"ඔබ දැනට <xliff:g id="APP_NAME">%1$s</xliff:g> පටිගත කරමින් සිටී"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"පටිගත කිරීම නවත්වන්න"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"තිරය බෙදා ගැනීම"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"අන්තර්ගතය බෙදා ගැනීම"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"තිරය බෙදා ගැනීම නවත්වන්න ද?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"බෙදා ගැනීම නවත්වන්න ද?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"ඔබ දැනට ඔබේ සම්පූර්ණ තිරය <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> සමග බෙදා ගනිමින් සිටී"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"ඔබ දැනට ඔබේ සම්පූර්ණ තිරය යෙදුමක් සමග බෙදා ගනිමින් සිටී"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"ඔබ දැනට <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> බෙදා ගනිමින් සිටී"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"ඔබ දැනට යෙදුමක් බෙදා ගනිමින් සිටී"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"ඔබ දැනට යෙදුමක් සමග බෙදා ගනිමින් සිටී"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"බෙදා ගැනීම නවත්වන්න"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"විකාශ තිරය"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"විකාශය නවතන්න ද?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"අගුළු තිර විජට්"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"ඔබේ ටැබ්ලටය අගුළු දමා තිබුණත්, ඕනෑම කෙනෙකුට ඔබේ අගුළු තිරයෙහි විජට් බැලිය හැක."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"විජට් නොතෝරන්න"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"උස අඩු කරන්න"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"උස වැඩි කරන්න"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"අගුළු තිර විජට්"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"විජට් එකක් භාවිතයෙන් යෙදුමක් විවෘත කිරීමට, ඔබට ඒ ඔබ බව සත්යාපනය කිරීමට අවශ්ය වනු ඇත. එසේම, ඔබේ ටැබ්ලටය අගුළු දමා ඇති විට පවා ඕනෑම කෙනෙකුට ඒවා බැලිය හැකි බව මතක තබා ගන්න. සමහර විජට් ඔබේ අගුළු තිරය සඳහා අදහස් කර නොතිබිය හැකි අතර මෙහි එක් කිරීමට අනාරක්ෂිත විය හැක."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"තේරුණා"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"සියල්ල හිස් කරන්න"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"කළමනාකරණය කරන්න"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ඉතිහාසය"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"දැනුම්දීම් සැකසීම්"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"දැනුම්දීම් ඉතිහාසය"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"නව"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"නිහඬ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"දැනුම් දීම්"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"දැන් අරඹන්න"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"දැනුම්දීම් නැත"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"නව දැනුම්දීම් නැත"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"දැනුම්දීම් සිසිල් කිරීම ක්රියාත්මකයි"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ඔබට එකවර දැනුම්දීම් වැඩි ප්රමාණයක් ලැබෙන විට ඔබේ උපාංග පරිමාව සහ ඇඟවීම් මිනිත්තු 2ක් දක්වා ස්වයංක්රීයව අඩු වේ."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ක්රියාවිරහිත කරන්න"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"පැරණි දැනුම්දීම් බැලීමට අගුළු හරින්න"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"නියම කළ"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"හිස ලුහුබැඳීම"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"නාදකය වෙනස් කිරීමට තට්ටු කරන්න"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"නිහඬ කරන්න"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"නිශ්ශබ්දතාවය ඉවත් කරන්න"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"කම්පනය"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"වත්මන් යෙදුම"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්රවේශ්යතාව"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"යතුරු පුවරු කෙටි මං"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"යතුරුපුවරු කෙටිමං අභිරුචිකරණය කරන්න"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"කෙටි මං සොයන්න"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"සෙවීම් ප්රතිඵල නැත"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"හැකුළුම් නිරූපකය"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"අභිරුචිකරණය කරන්න"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"නිමයි"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"දිගහැරීම් නිරූපකය"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"හෝ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ඇදීම් හැඬලය"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"යෙදුම් මගින් සපයනු ලැබේ"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"සංදර්ශකය"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"නොදනී"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"ටයිල් යළි සකසන්න"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"ටයිල් ඒවායේ මුල් අනුපිළිවෙලට සහ ප්රමාණයට යළි සකසන්න ද?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"සියලු ටයිල් නැවත සකසන්න ද?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"සියලු ඉක්මන් සැකසීම් ටයිල් උපාංගයේ මුල් සැකසීම් වෙත නැවත සකසනු ඇත"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c223566..2e03aab 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Chcete nahrávať obrazovku?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Nahrávať jednu aplikáciu"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Nahrávať celú obrazovku"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Nahrať celú obrazovku: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pri nahrávaní celej obrazovky sa zaznamená všetko, čo sa na nej zobrazuje. Preto venujte pozornosť položkám, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Pri nahrávaní aplikácie sa zaznamená všetko, čo sa v nej zobrazuje alebo prehráva. Preto venujte pozornosť položkám, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Nahrávať obrazovku"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Momentálne nahrávate aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Zastaviť nahrávanie"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Zdieľa sa obrazovka"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Obsah sa zdieľa"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Chcete prestať zdieľať obrazovku?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Chcete zastaviť zdieľanie?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Momentálne zdieľate celú obrazovku s aplikáciou <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Momentálne zdieľate celú obrazovku s aplikáciou"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Momentálne zdieľate aplikáciu <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Momentálne zdieľate aplikáciu"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Momentálne zdieľate s aplikáciou"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Prestať zdieľať"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Prenáša sa obrazovka"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Chcete zastaviť prenos?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Miniaplikácie na uzamknutej obrazovke"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Miniaplikácie na uzamknutej obrazovke uvidia všetci, aj keď je tablet uzamknutý."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"zrušiť výber miniaplikácie"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Znížiť výšku"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Zväčšiť výšku"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Miniaplikácie na uzamknutej obrazovke"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ak chcete otvoriť aplikáciu pomocou miniaplikácie, budete musieť overiť svoju totožnosť. Pamätajte, že si miniaplikáciu môže pozrieť ktokoľvek, aj keď máte tablet uzamknutý. Niektoré miniaplikácie možno nie sú určené pre uzamknutú obrazovku a ich pridanie tu môže byť nebezpečné."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Dobre"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Žiadne upozornenia"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Žiadne nové upozornenia"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Stlmenie upozornení je zapnuté"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Keď dostanete priveľa upozornení naraz, až na dve minúty sa zníži hlasitosť zariadenia a upozornenia sa obmedzia."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnúť"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odomknutím zobrazíte staršie upozornenia"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Pevné"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sled. polohy hlavy"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Režim zvonenia zmeníte klepnutím"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnite zvuk"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnite zvuk"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"zapnite vibrovanie"</string>
@@ -862,12 +859,12 @@
<string name="group_system_cycle_back" msgid="8194102916946802902">"Cyklické prechádzanie dozadu po nedávnych aplikáciách"</string>
<string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvorenie zoznamu aplikácií"</string>
<string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvorenie nastavení"</string>
- <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvorenie Asistenta"</string>
+ <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvoriť asistenta"</string>
<string name="group_system_lock_screen" msgid="7391191300363416543">"Uzamknutie obrazovky"</string>
<string name="group_system_quick_memo" msgid="3764560265935722903">"Napísanie poznámky"</string>
<string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Multitasking"</string>
- <string name="system_multitasking_rhs" msgid="8714224917276297810">"Použite rozdelenú obrazovku s aktuálnou aplikáciou vpravo"</string>
- <string name="system_multitasking_lhs" msgid="8402954791206308783">"Použite rozdelenú obrazovku s aktuálnou aplikáciou vľavo"</string>
+ <string name="system_multitasking_rhs" msgid="8714224917276297810">"Rozdeliť obrazovku, aktuálna aplikácia vpravo"</string>
+ <string name="system_multitasking_lhs" msgid="8402954791206308783">"Rozdeliť obrazovku, aktuálna aplikácia vľavo"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Prepnutie rozdelenej obrazovky na celú"</string>
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prechod na aplikáciu vpravo alebo dole pri rozdelenej obrazovke"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prechod na aplikáciu vľavo alebo hore pri rozdelenej obrazovke"</string>
@@ -1409,19 +1406,16 @@
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedávne aplikácie"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Rozdelená obrazovka"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vstup"</string>
- <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Odkazy do aplikácií"</string>
+ <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Skratky aplikácií"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuálna aplikácia"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostupnosť"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové skratky"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Vyhľadávacie odkazy"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prispôsobenie klávesových skratiek"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prehľadávať skratky"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žiadne výsledky vyhľadávania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zbalenia"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prispôsobiť"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalenia"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"alebo"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Presúvadlo"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Poskytnuté aplikáciami"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Zobrazovanie"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznáme"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Resetovanie kariet"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Chcete resetovať karty na pôvodné poradie a veľkosti?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Chcete resetovať všetky karty?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Všetky karty rýchlych nastavení sa resetujú na pôvodné nastavenia zariadenia"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 15f1b3c..ad71a77 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Želite posneti zaslon?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snemanje ene aplikacije"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snemanje celotnega zaslona"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snemanje celotnega zaslona: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pri snemanju celotnega zaslona se posname vse, kar je prikazano na zaslonu. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Pri snemanju aplikacije se posname vse, kar je prikazano ali predvajano v tej aplikaciji. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snemanje zaslona"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Trenutno snemate aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Ustavi snemanje"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deljenje zaslona"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Deljenje vsebine"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Želite ustaviti deljenje zaslona?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Želite ustaviti deljenje?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Trenutno delite celotni zaslon z aplikacijo <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Trenutno delite celotni zaslon z eno od aplikacij"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Trenutno delite aplikacijo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Trenutno delite eno od aplikacij"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Trenutno delite z eno od aplikacij"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Ustavi deljenje"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Predvajanje vsebine zaslona"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Želite ustaviti predvajanje?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Pripomočki na zaklenjenem zaslonu"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Pripomočki na zaklenjenem zaslonu so vidni vsem, tudi če je tablica zaklenjena."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"preklic izbire pripomočka"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Zmanjšanje višine"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Povečanje višine"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Pripomočki na zaklenjenem zaslonu"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Če želite aplikacijo odpreti s pripomočkom, morate potrditi, da ste to vi. Upoštevajte tudi, da si jih lahko ogledajo vsi, tudi ko je tablični računalnik zaklenjen. Nekateri pripomočki morda niso predvideni za uporabo na zaklenjenem zaslonu, zato jih tukaj morda ni varno dodati."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumem"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Izbriši vse"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljaj"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Zgodovina"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Nastavitve obvestil"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Zgodovina obvestil"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Novo"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Tiho"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obvestila"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Začni zdaj"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ni obvestil"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ni novih obvestil"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Utišanje obvestil je vklopljeno"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Ko prejmete preveč obvestil naenkrat, se glasnost naprave in opozoril samodejno zmanjša za največ 2 minuti."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Izklopi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odklenite za ogled starejših obvestil"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksno"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Spremljanje premikov glave"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Dotaknite se, če želite spremeniti način zvonjenja."</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izklop zvoka"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vklop zvoka"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string>
@@ -815,7 +810,7 @@
<string name="keyboard_key_back" msgid="4185420465469481999">"Nazaj"</string>
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"Preslednica"</string>
- <string name="keyboard_key_enter" msgid="8633362970109751646">"Vnesi"</string>
+ <string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Vračalka"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Predvajaj/zaustavi"</string>
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"Ustavi"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostopnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Bližnjične tipke"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Bližnjice za iskanje"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagajanje bližnjičnih tipk"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Iskanje po bližnjicah"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ni rezultatov iskanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za strnitev"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Končano"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za razširitev"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ali"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ročica za vlečenje"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Zagotavljajo aplikacije"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Zaslon"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Neznano"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Ponastavitev ploščic"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Želite ponastaviti ploščice na prvotni vrstni red in prvotno velikost?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Želite ponastaviti vse ploščice?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Vse ploščice v hitrih nastavitvah bodo ponastavljene na prvotne nastavitve naprave."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 7f74487..027636f 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Të regjistrohet ekrani?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Regjistro një aplikacion"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Regjistro të gjithë ekranin"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Regjistro gjithë ekranin: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kur regjistron të gjithë ekranin, regjistrohet çdo gjë e shfaqur në ekranin tënd. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kur regjistron një aplikacion, regjistrohet çdo gjë që shfaqet ose luhet në atë aplikacion. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Regjistro ekranin"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Po regjistron aktualisht \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Ndalo regjistrimin"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekrani po ndahet"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Po ndan përmbajtjen"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Të ndalohet ndarja e ekranit?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Të ndalohet ndarja?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Po ndan aktualisht të gjithë ekranin me \"<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>\""</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Po ndan aktualisht të gjithë ekranin me një aplikacion"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Po ndan aktualisht \"<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>\""</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Po ndan aktualisht një aplikacion"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Po ndan aktualisht me një aplikacion"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Ndalo ndarjen"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Po transmeton ekranin"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Të ndalohet transmetimi?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Miniaplikacionet në ekranin e kyçjes"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Çdo person mund të shikojë miniaplikacionet në ekranin tënd të kyçjes, edhe nëse tableti është i kyçur."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"anulo zgjedhjen e miniaplikacionit"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Zvogëlo lartësinë"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Rrit lartësinë"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Miniaplikacionet në ekranin e kyçjes"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Për të hapur një aplikacion duke përdorur një miniaplikacion, do të duhet të verifikosh që je ti. Ki parasysh gjithashtu që çdo person mund t\'i shikojë, edhe kur tableti yt është i kyçur. Disa miniaplikacione mund të mos jenë planifikuar për ekranin tënd të kyçjes dhe mund të mos jetë e sigurt t\'i shtosh këtu."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"E kuptova"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Pastroji të gjitha"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Menaxho"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historiku"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Cilësimet e njoftimeve"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historiku i njoftimeve"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Të reja"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Në heshtje"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Njoftimet"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Asnjë njoftim"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nuk ka njoftime të reja"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Reduktimi i njoftimeve është aktiv"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volumi i pajisjes dhe sinjalizimet zvogëlohen automatikisht për deri në 2 minuta kur merr shumë njoftime në të njëjtën kohë."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Çaktivizo"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Shkyç për të parë njoftimet e vjetra"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"E fiksuar"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Ndjekja e lëvizjeve të kokës"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Trokit për të ndryshuar modalitetin e ziles"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"çaktivizo audion"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktivizo audion"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"lësho dridhje"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplikacioni aktual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qasshmëria"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Shkurtoret e tastierës"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizo shkurtoret e tastierës"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Kërko për shkurtoret"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Asnjë rezultat kërkimi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona e palosjes"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizo"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"U krye"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona e zgjerimit"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ose"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Doreza e zvarritjes"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Mundësuar nga aplikacionet"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekrani"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Nuk njihet"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Rivendos pllakëzat"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Të rivendosen pllakëzat në rendin dhe madhësinë e tyre origjinale?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Të rivendosen të gjitha pllakëzat?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Të gjitha pllakëzat e \"Cilësimeve të shpejta\" do të rivendosen te cilësimet origjinale të pajisjes"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index a1952d4..bc3a050 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Желите да снимите екран?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Сними једну апликацију"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Сними цео екран"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Снимите цео екран: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Када снимате цео екран, снима се све што је на њему. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Када снимате апликацију, снима се сав садржај који се приказује или пушта у њој. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Сними екран"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Тренутно снимате: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Заустави снимање"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Екран се дели"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Дељење садржаја"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Желите да зауставите дељење екрана?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Желите да зауставите дељење?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Тренутно делите цео екран са: <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Тренутно делите цео екран са апликацијом"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Тренутно делите: <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Тренутно делите апликацију"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Тренутно делите са апликацијом"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Заустави дељење"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Пребацује се екран"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Желите да зауставите пребацивање?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Виџети за закључани екран"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Сви могу да виде виџете на закључаном екрану, чак и када је таблет закључан."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"поништи избор виџета"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Смањи висину"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Повећај висину"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Виџети за закључани екран"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Да бисте отворили апликацију која користи виџет, треба да потврдите да сте то ви. Имајте у виду да свако може да га види, чак и када је таблет закључан. Неки виџети можда нису намењени за закључани екран и можда није безбедно да их тамо додате."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Важи"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нема обавештења"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нових обавештења"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Утишавање обавештења је укључено"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Звук и број упозорења на уређају се аутоматски смањују на 2 минута када добијете превише обавештења."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Искључи"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Откључајте за старија обавештења"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Фиксно"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Праћење главе"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Додирните да бисте променили режим звона"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"искључите звук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"укључите звук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрација"</string>
@@ -814,7 +811,7 @@
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"Размак"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
- <string name="keyboard_key_backspace" msgid="4095278312039628074">"Тастер за брисање уназад"</string>
+ <string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Тастер за репродукцију/паузирање"</string>
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"Тастер за заустављање"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Тастер Следећа"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Актуелна апликација"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Приступачност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Тастерске пречице"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пречице претраге"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Прилагодите тастерске пречице"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Претражите пречице"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултата претраге"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за скупљање"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Прилагоди"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширивање"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер за превлачење"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Обезбеђују апликације"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Екран"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Непознато"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Ресетујте плочице"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Желите да ресетујете плочице на првобитни редослед и величине?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Желите да ресетујете све плочице?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Све плочице Брзих подешавања ће се ресетовати на првобитна подешавања уређаја"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index b898eaf..66b5851 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vill du spela in det som visas på skärmen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Spela in en app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Spela in hela skärmen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Spela in hela skärmen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"När du spelar in hela skärmen spelas allt som visas på skärmen in. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton, ljud och video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"När du spelar in en app spelas allt som visas eller spelas upp i appen in. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton, ljud och video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Spela in skärmen"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Du spelar för närvarande in <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Sluta spela in"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Skärmen delas"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Delar innehåll"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vill du sluta dela skärmen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Vill du sluta dela?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Du delar för närvarande hela din skärm med <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Du delar för närvarande hela din skärm med en app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Du delar för närvarande <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Du delar för närvarande en app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Du delar för närvarande med en app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Sluta dela"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Skärmen castas"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vill du sluta att casta?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgetar för låsskärm"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Vem som helst kan se widgetar på din låsskärm, även om surfplattan är låst."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"avmarkera widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Minska höjden"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Öka höjden"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgetar för låsskärm"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Du måste verifiera din identitet innan du öppnar en app med en widget. Tänk också på att alla kan se dem, även när surfplattan är låst. Vissa widgetar kanske inte är avsedda för låsskärmen och det kan vara osäkert att lägga till dem här."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Rensa alla"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Hantera"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historik"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Aviseringsinställningar"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Aviseringshistorik"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Ny"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Ljudlöst"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Aviseringar"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Inga aviseringar"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Det finns inga nya aviseringar"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Dämpning av aviseringar är på"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Enheten sänker volymen och minimerar aviseringar i upp till två minuter när du får för många aviseringar samtidigt."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Inaktivera"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås upp för att se äldre aviseringar"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Statiskt"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Huvudspårning"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tryck för att ändra ringsignalens läge"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"stänga av ljudet"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på ljudet"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibration"</string>
@@ -1410,20 +1405,17 @@
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multikörning"</string>
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Senaste apparna"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Delad skärm"</string>
- <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ingång"</string>
+ <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Inmatning"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Genvägar till appar"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuell app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tillgänglighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortkommandon"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Anpassa kortkommandon"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sökgenvägar"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Inga sökresultat"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikonen Komprimera"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Anpassa"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klar"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikonen Utöka"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handtag"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Tillhandahålls av appar"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Skärm"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Okänt"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Återställ rutor"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Vill du återställa rutorna till den ursprungliga ordningen och storleken?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Vill du återställa alla rutor?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Alla Snabbinställningsrutor återställs till enhetens ursprungliga inställningar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 8731337..67abd41 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ungependa kurekodi skrini yako?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rekodi programu moja"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rekodi skrini nzima"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Rekodi skrini nzima: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Unaporekodi skrini yako nzima, chochote kinachoonyeshwa kwenye skrini yako kitarekodiwa. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Unaporekodi programu, chochote kinachoonyeshwa au kuchezwa kwenye programu hiyo kitarekodiwa. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rekodi skrini"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Kwa sasa unarekodi <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Acha kurekodi"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Inaruhusu ufikiaji kwenye skrini"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Unatuma maudhui"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ungependa kuacha kuonyesha skrini?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Ungependa kuacha kutuma maudhui?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Kwa sasa unatuma maudhui yaliyo katika skrini yako nzima kwenye <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Kwa sasa unatuma maudhui yaliyo katika skrini yako nzima kwenye programu"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Kwa sasa unaonyesha <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Kwa sasa unatumia programu pamoja na wengine"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Kwa sasa unatuma maudhui kwenye programu"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Acha kuonyesha skrini"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Inatuma skrini"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Ungependa kuacha kutuma?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Wijeti zinazoonekana kwenye skrini iliyofungwa"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Yeyote anaweza kuona wijeti kwenye skrini yako iliyofungwa, hata ikiwa umefunga kishikwambi chako."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"acha kuchagua wijeti"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Punguza urefu"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Ongeza urefu"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Wijeti zinazoonekana kwenye skrini iliyofungwa"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Utahitaji kuthibitisha kuwa ni wewe ili ufungue programu ukitumia wijeti. Pia, kumbuka kuwa mtu yeyote anaweza kuziona, hata kishikwambi chako kikiwa kimefungwa. Huenda baadhi ya wijeti hazikukusudiwa kutumika kwenye skrini yako iliyofungwa na huenda si salama kuziweka hapa."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Nimeelewa"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Futa zote"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Dhibiti"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Mipangilio ya arifa"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historia ya arifa"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Mpya"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Kimya"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Arifa"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Hakuna arifa"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Hakuna arifa mpya"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Umewasha mipangilio ya kutuliza arifa"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Arifa na sauti hupunguzwa kiotomatiki kwenye kifaa chako kwa hadi dakika 2 unapopokea arifa nyingi kwa wakati mmoja."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Zima"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Fungua ili uone arifa za zamani"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Imerekebishwa"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Ufuatilizi wa Kichwa"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Gusa ili ubadilishe hali ya programu inayotoa milio ya simu"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"zima sauti"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"washa sauti"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"tetema"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Programu Inayotumika Sasa"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mikato ya kibodi"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Weka mapendeleo ya mikato ya kibodi"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Njia mkato za kutafutia"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hamna matokeo ya utafutaji"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kunja aikoni"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Weka mapendeleo"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Nimemaliza"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Panua aikoni"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"au"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Aikoni ya buruta"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Vinavyotolewa na programu"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Maonyesho"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Visivyojulikana"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Badilisha mipangilio ya vigae"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Ungependa kurejesha mipangilio chaguomsingi ya ukubwa na mpangilio wa vigae?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Ungependa kubadilisha vigae vyote?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Vigae vyote vya Mipangilio ya Haraka vitabadilishwa kuwa katika mipangilio halisi ya kifaa"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index b75a218..dd4f367f 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"உங்கள் திரையை ரெக்கார்டு செய்யவா?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ஓர் ஆப்ஸை ரெக்கார்டு செய்தல்"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"முழுத் திரையை ரெக்கார்டு செய்தல்"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"முழுத் திரையை ரெக்கார்டு செய்தல்: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"முழுத் திரையை நீங்கள் ரெக்கார்டு செய்யும்போது அதில் காட்டப்படும் அனைத்தும் ரெக்கார்டு செய்யப்படும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ஓர் ஆப்ஸை ரெக்கார்டு செய்யும்போது அதில் காட்டப்படும் அல்லது பிளே செய்யப்படும் அனைத்தும் ரெக்கார்டு செய்யப்படும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"திரையை ரெக்கார்டு செய்"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"இப்போது நீங்கள் <xliff:g id="APP_NAME">%1$s</xliff:g> ஐ ரெக்கார்டு செய்கிறீர்கள்"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ரெக்கார்டிங்கை நிறுத்து"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"திரையைப் பகிர்கிறது"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"உள்ளடக்கம் பகிரப்படுகிறது"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"திரையைப் பகிர்வதை நிறுத்தவா?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"பகிர்வதை நிறுத்தவா?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"இப்போது உங்கள் முழுத்திரையையும் <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> உடன் பகிர்கிறீர்கள்"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"இப்போது உங்கள் முழுத்திரையையும் ஆப்ஸுடன் பகிர்கிறீர்கள்"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"இப்போது நீங்கள் <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ஐப் பகிர்கிறீர்கள்"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"இப்போது நீங்கள் ஓர் ஆப்ஸைப் பகிர்கிறீர்கள்"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"இப்போது நீங்கள் ஓர் ஆப்ஸுடன் பகிர்கிறீர்கள்"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"பகிர்வதை நிறுத்து"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"திரையை அலைபரப்புகிறது"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"அலைபரப்பை நிறுத்தவா?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"பூட்டுத் திரை விட்ஜெட்கள்"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"டேப்லெட் பூட்டப்பட்டிருந்தாலும் பூட்டுத் திரையில் விட்ஜெட்டை எவரும் பார்க்கலாம்."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"விட்ஜெட்டைத் தேர்வுநீக்கும்"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"உயரத்தைக் குறைக்கும்"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"உயரத்தை அதிகரிக்கும்"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"பூட்டுத் திரை விட்ஜெட்கள்"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"விட்ஜெட்டைப் பயன்படுத்தி ஆப்ஸைத் திறக்க, அது நீங்கள்தான் என்பதை உறுதிசெய்ய வேண்டும். அத்துடன், உங்கள் டேப்லெட் பூட்டப்பட்டிருந்தாலும்கூட அவற்றை யார் வேண்டுமானாலும் பார்க்கலாம் என்பதை நினைவில்கொள்ளுங்கள். சில விட்ஜெட்கள் உங்கள் பூட்டுத் திரைக்காக உருவாக்கப்பட்டவை அல்ல என்பதையும் அவற்றை இங்கே சேர்ப்பது பாதுகாப்பற்றதாக இருக்கக்கூடும் என்பதையும் நினைவில்கொள்ளுங்கள்."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"சரி"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"எல்லாவற்றையும் அழி"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"நிர்வகி"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"இதுவரை வந்த அறிவிப்புகள்"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"அறிவிப்பு அமைப்புகள்"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"இதுவரையான அறிவிப்புகள்"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"புதிது"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"சைலன்ட்"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"அறிவிப்புகள்"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"இப்போது தொடங்கு"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"அறிவிப்புகள் இல்லை"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"புதிய அறிவிப்புகள் இல்லை"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"\'குறைந்த ஒலியளவில் அறிவிப்புகள்\' இயக்கப்பட்டுள்ளது"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ஒரே நேரம் பல அறிவிப்புகள் வரும்போது சாதன ஒலியளவும் விழிப்பூட்டலும் தானாக 2 நிமிடம் குறைக்கப்படும்."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"முடக்கு"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"பழைய அறிவிப்பைப் பார்க்க அன்லாக் செய்க"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"நிலையானது"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ஹெட் டிராக்கிங்"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ரிங்கர் பயன்முறையை மாற்ற தட்டவும்"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ஒலியடக்கும்"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ஒலி இயக்கும்"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"அதிர்வுறும்"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"தற்போதைய ஆப்ஸ்"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"மாற்றுத்திறன் வசதி"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"கீபோர்டு ஷார்ட்கட்கள்"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"தேடல் ஷார்ட்கட்கள்"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"கீபோர்டு ஷார்ட்கட்களைப் பிரத்தியேகப்படுத்துதல்"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ஷார்ட்கட்களைத் தேடுக"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"தேடல் முடிவுகள் இல்லை"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"சுருக்குவதற்கான ஐகான்"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"பிரத்தியேகப்படுத்தும்"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"முடிந்தது"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"விரிவாக்குவதற்கான ஐகான்"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"அல்லது"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"இழுப்பதற்கான ஹேண்டில்"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ஆப்ஸ் வழங்குபவை"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"டிஸ்ப்ளே"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"தெரியவில்லை"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"கட்டங்களை மீட்டமைத்தல்"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"கட்டங்களை அவற்றின் அசல் வரிசைக்கும் அளவுகளுக்கும் மீட்டமைக்கவா?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"அனைத்துக் கட்டங்களையும் மீட்டமைக்கவா?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"விரைவு அமைப்புகளின் கட்டங்கள் அனைத்தும் சாதனத்தின் அசல் அமைப்புகளுக்கு மீட்டமைக்கப்படும்"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index d66c656..ed4c0ef 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"మీ స్క్రీన్ను రికార్డ్ చేయాలా?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ఒక యాప్ను రికార్డ్ చేయండి"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ఫుల్ స్క్రీన్ను రికార్డ్ చేయండి"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ఫుల్-స్క్రీన్ను రికార్డ్ చేయండి: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"మీ ఫుల్ స్క్రీన్ను మీరు రికార్డ్ చేసేటప్పుడు, మీ స్క్రీన్పై కనిపించేవన్నీ రికార్డ్ అవుతాయి. కాబట్టి పాస్వర్డ్లు, పేమెంట్ వివరాలు, మెసేజ్లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"మీరు యాప్ను రికార్డ్ చేసేటప్పుడు, సంబంధిత యాప్లో కనిపించేవన్నీ లేదా ప్లే అయ్యేవన్నీ రికార్డ్ అవుతాయి. కాబట్టి పాస్వర్డ్లు, పేమెంట్ వివరాలు, మెసేజ్లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"స్క్రీన్ను రికార్డ్ చేయండి"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"మీరు ప్రస్తుతం <xliff:g id="APP_NAME">%1$s</xliff:g>ను రికార్డ్ చేస్తున్నారు"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"రికార్డింగ్ను ఆపివేయండి"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"స్క్రీన్ను షేర్ చేస్తోంది"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"కంటెంట్ను షేర్ చేస్తోంది"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"స్క్రీన్ను షేర్ చేయడం ఆపివేయాలా?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"షేర్ చేయడాన్ని ఆపివేయాలా?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"మీరు ప్రస్తుతం మీ మొత్తం స్క్రీన్ను <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>తో షేర్ చేస్తున్నారు"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"మీరు ప్రస్తుతం మీ మొత్తం స్క్రీన్ను యాప్తో షేర్ చేస్తున్నారు"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"మీరు ప్రస్తుతం <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>ను షేర్ చేస్తున్నారు"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"మీరు ప్రస్తుతం యాప్ను షేర్ చేస్తున్నారు"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"మీరు ప్రస్తుతం యాప్తో షేర్ చేస్తున్నారు"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"షేర్ చేయడాన్ని ఆపివేయండి"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"స్క్రీన్ను ప్రసారం చేస్తోంది"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"ప్రసారం చేయడం ఆపివేయాలా?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"లాక్ స్క్రీన్ విడ్జెట్లు"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"మీ టాబ్లెట్ లాక్ చేసి ఉన్నా, మీ లాక్ స్క్రీన్లో విడ్జెట్లను ఎవరైనా చూడవచ్చు."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"విడ్జెట్ ఎంపిక రద్దు చేయండి"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ఎత్తును తగ్గించండి"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"ఎత్తును పెంచండి"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"లాక్ స్క్రీన్ విడ్జెట్లు"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"విడ్జెట్ను ఉపయోగించి యాప్ను తెరవడానికి, ఇది మీరేనని వెరిఫై చేయాల్సి ఉంటుంది. అలాగే, మీ టాబ్లెట్ లాక్ చేసి ఉన్నప్పటికీ, ఎవరైనా వాటిని చూడగలరని గుర్తుంచుకోండి. కొన్ని విడ్జెట్లు మీ లాక్ స్క్రీన్కు తగినవి కాకపోవచ్చు, వాటిని ఇక్కడ జోడించడం సురక్షితం కాకపోవచ్చు."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"అర్థమైంది"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ఇప్పుడే ప్రారంభించండి"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"నోటిఫికేషన్లు లేవు"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"కొత్త నోటిఫికేషన్లు ఏవీ లేవు"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"నోటిఫికేషన్ కూల్డౌన్ ఆన్ అయింది"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ఒకేసారి పలు నోటిఫికేషన్లు వస్తే, పరికర వాల్యూమ్, అలర్ట్స్ ఆటోమేటిగ్గా 2 నిమిషాలకు తగ్గించబడతాయి."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ఆఫ్ చేయండి"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"పాత నోటిఫికేషన్ల కోసం అన్లాక్ చేయండి"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ఫిక్స్డ్"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"హెడ్ ట్రాకింగ్"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"రింగర్ మోడ్ను మార్చడానికి ట్యాప్ చేయండి"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"మ్యూట్ చేయి"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"అన్మ్యూట్ చేయి"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"వైబ్రేట్"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ప్రస్తుత యాప్"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"యాక్సెసిబిలిటీ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"కీబోర్డ్ షార్ట్కట్లు"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"సెర్చ్ షార్ట్కట్లు"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"కీబోర్డ్ షార్ట్కట్లను అనుకూలంగా మార్చండి"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"షార్ట్కట్లను వెతకండి"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"సెర్చ్ ఫలితాలు ఏవీ లేవు"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"కుదించండి చిహ్నం"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"అనుకూలంగా మార్చండి"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"పూర్తయింది"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"విస్తరించండి చిహ్నం"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"లేదా"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"లాగే హ్యాండిల్"</string>
@@ -1458,7 +1452,7 @@
<string name="home_controls_dream_description" msgid="4644150952104035789">"హోమ్ కంట్రోల్స్ను స్క్రీన్ సేవర్గా చేసి వేగంగా యాక్సెస్ పొందండి"</string>
<string name="volume_undo_action" msgid="5815519725211877114">"చర్య రద్దు చేయండి"</string>
<string name="back_edu_toast_content" msgid="4530314597378982956">"వెనుకకు వెళ్లడానికి, టచ్ప్యాడ్లో మూడు వేళ్లను ఉపయోగించి ఎడమ లేదా కుడి వైపునకు స్వైప్ చేయండి"</string>
- <string name="home_edu_toast_content" msgid="3381071147871955415">"హోమ్కు వెళ్లడానికి, టచ్ప్యాడ్లో మీ మూడు వెళ్లతో పైకి స్వైప్ చేయండి"</string>
+ <string name="home_edu_toast_content" msgid="3381071147871955415">"హోమ్కు వెళ్లడానికి, టచ్ప్యాడ్లో మీ మూడు వేళ్లతో పైకి స్వైప్ చేయండి"</string>
<string name="overview_edu_toast_content" msgid="5797030644017804518">"ఇటీవలి యాప్లను చూడటానికి, టచ్ప్యాడ్లో మూడు వేళ్లతో పైకి స్వైప్ చేసి, హోల్డ్ చేయండి"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"మీ యాప్లన్నింటినీ చూడటానికి, మీ కీబోర్డ్లో యాక్షన్ కీని నొక్కండి"</string>
<string name="redacted_notification_single_line_title" msgid="212019960919261670">"దాచిపెట్టినది"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"యాప్ల ద్వారా అందించబడినవి"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"డిస్ప్లే"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"తెలియదు"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"టైల్స్ను రీసెట్ చేయండి"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"టైల్స్ను వాటి ఒరిజినల్ క్రమానికి, సైజ్లకు రీసెట్ చేయాలా?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"టైల్స్ అన్ని రీసెట్ చేయాలా?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"అన్ని క్విక్ సెట్టింగ్ల టైల్స్, పరికరం తాలూకు ఒరిజినల్ సెట్టింగ్లకు రీసెట్ చేయబడతాయి"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index b7d1a32..49ba43e 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"บันทึกหน้าจอไหม"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"บันทึกแอปเดียว"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"บันทึกทั้งหน้าจอ"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"บันทึกทั้งหน้าจอ: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ขณะบันทึกทั้งหน้าจอ ระบบจะบันทึกทุกสิ่งที่แสดงอยู่บนหน้าจอ ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ขณะบันทึกแอป ระบบจะบันทึกทุกสิ่งที่แสดงหรือเล่นอยู่ในแอปดังกล่าว ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"บันทึกหน้าจอ"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"คุณกำลังบันทึก <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"หยุดบันทึก"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"กำลังแชร์หน้าจอ"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"กำลังแชร์เนื้อหา"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"หยุดแชร์หน้าจอไหม"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"หยุดการแชร์ใช่ไหม"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"คุณกำลังแชร์ทั้งหน้าจอกับ <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"คุณกำลังแชร์ทั้งหน้าจอกับแอป"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"คุณกำลังแชร์ <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"คุณกำลังแชร์แอป"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"คุณกำลังแชร์กับแอป"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"หยุดแชร์"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"กำลังแคสต์หน้าจอ"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"หยุดแคสต์ไหม"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"วิดเจ็ตในหน้าจอล็อก"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"ทุกคนจะดูวิดเจ็ตที่อยู่ในหน้าจอล็อกของคุณได้ แม้ว่าแท็บเล็ตจะล็อกอยู่ก็ตาม"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ยกเลิกการเลือกวิดเจ็ต"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"ลดความสูง"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"เพิ่มความสูง"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"วิดเจ็ตในหน้าจอล็อก"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"หากต้องการเปิดแอปโดยใช้วิดเจ็ต คุณจะต้องยืนยันตัวตนของคุณ นอกจากนี้ โปรดทราบว่าผู้อื่นจะดูวิดเจ็ตเหล่านี้ได้แม้ว่าแท็บเล็ตจะล็อกอยู่ก็ตาม วิดเจ็ตบางอย่างอาจไม่ได้มีไว้สำหรับหน้าจอล็อกของคุณ และอาจไม่ปลอดภัยที่จะเพิ่มที่นี่"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"รับทราบ"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"ล้างทั้งหมด"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"จัดการ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ประวัติ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"การตั้งค่าการแจ้งเตือน"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"ประวัติการแจ้งเตือน"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"ใหม่"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ปิดเสียง"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"การแจ้งเตือน"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"เริ่มเลย"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ไม่มีการแจ้งเตือน"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ไม่มีการแจ้งเตือนใหม่"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"การพักการแจ้งเตือนเปิดอยู่"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ระบบจะลดระดับเสียงและจำนวนการแจ้งเตือนของอุปกรณ์โดยอัตโนมัติสูงสุด 2 นาทีเมื่อคุณได้รับการแจ้งเตือนพร้อมกันมากเกินไป"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ปิด"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ปลดล็อกเพื่อดูการแจ้งเตือนเก่า"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"คงที่"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"การติดตามการเคลื่อนไหวของศีรษะ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"แตะเพื่อเปลี่ยนโหมดเสียงเรียกเข้า"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ปิดเสียง"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"เปิดเสียง"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"สั่น"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"แอปปัจจุบัน"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"การช่วยเหลือพิเศษ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"แป้นพิมพ์ลัด"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ปรับแต่งแป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ค้นหาแป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ไม่พบผลการค้นหา"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ไอคอนยุบ"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ปรับแต่ง"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"เสร็จสิ้น"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ไอคอนขยาย"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"หรือ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"แฮนเดิลการลาก"</string>
@@ -1469,9 +1461,9 @@
<string name="back_edu_notification_title" msgid="5624780717751357278">"ใช้ทัชแพดเพื่อย้อนกลับ"</string>
<string name="back_edu_notification_content" msgid="2497557451540954068">"ใช้ 3 นิ้วปัดไปทางซ้ายหรือขวา แตะเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับท่าทางสัมผัสต่างๆ"</string>
<string name="home_edu_notification_title" msgid="6097902076909654045">"ใช้ทัชแพดเพื่อไปยังหน้าแรก"</string>
- <string name="home_edu_notification_content" msgid="6631697734535766588">"ใช้ 3 นิ้วปัดขึ้น แตะเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับท่าทางสัมผัสต่างๆ"</string>
+ <string name="home_edu_notification_content" msgid="6631697734535766588">"ใช้ 3 นิ้วปัดขึ้น แตะเพื่อดูท่าทางสัมผัสต่างๆ เพิ่มเติม"</string>
<string name="overview_edu_notification_title" msgid="1265824157319562406">"ใช้ทัชแพดเพื่อดูแอปล่าสุด"</string>
- <string name="overview_edu_notification_content" msgid="3578204677648432500">"ใช้ 3 นิ้วปัดขึ้นแล้วค้างไว้ แตะเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับท่าทางสัมผัสต่างๆ"</string>
+ <string name="overview_edu_notification_content" msgid="3578204677648432500">"ใช้ 3 นิ้วปัดขึ้นแล้วค้างไว้ แตะเพื่อดูท่าทางสัมผัสต่างๆ เพิ่มเติม"</string>
<string name="all_apps_edu_notification_title" msgid="372262997265569063">"ใช้แป้นพิมพ์เพื่อดูแอปทั้งหมด"</string>
<string name="all_apps_edu_notification_content" msgid="3255070575694025585">"กดปุ่มดำเนินการได้ทุกเมื่อ แตะเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับท่าทางสัมผัสต่างๆ"</string>
<string name="accessibility_deprecate_extra_dim_dialog_title" msgid="910988771011857460">"ตอนนี้การหรี่แสงเพิ่มเติมเป็นส่วนหนึ่งของแถบเลื่อนความสว่างแล้ว"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ให้บริการโดยแอป"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"จอแสดงผล"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"ไม่ทราบ"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"รีเซ็ตการ์ด"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"รีเซ็ตการ์ดเป็นลำดับและขนาดเดิมไหม"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"รีเซ็ตการ์ดทั้งหมดใช่ไหม"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"การ์ดการตั้งค่าด่วนทั้งหมดจะรีเซ็ตเป็นการตั้งค่าเดิมของอุปกรณ์"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index a30a2f2..e589d31 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"I-record ang iyong screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Mag-record ng isang app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"I-record ang buong screen"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"I-record ang buong screen: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kapag nire-record mo ang iyong buong screen, nire-record ang anumang ipinapakita sa screen mo. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kapag nagre-record ka ng app, nire-record ang anumang ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"I-record ang screen"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Kasalukuyan mong nire-record ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Huminto sa pag-record"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ibinabahagi ang screen"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Pagbabahagi ng content"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ihinto ang pagbabahagi ng screen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Itigil ang pagbabahagi?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Kasalukuyan mong ibinabahagi ang iyong buong screen sa <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Kasalukuyan mong ibinabahagi ang iyong buong screen sa isang app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Kasalukuyan kang nagbabahagi ng <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Kasalukuyan kang nagbabahagi ng app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Kasalukuyan kang nagbabahagi sa isang app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Ihinto ang pagbabahagi"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Kina-cast ang screen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Ihinto ang pag-cast?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Mga widget ng lock screen"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Makikita ng sinuman ang mga widget sa lock screen, kahit naka-lock ang tablet."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"i-unselect ang widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Bawasan ang taas"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Dagdagan ang taas"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Mga widget ng lock screen"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para magbukas ng app gamit ang isang widget, kakailanganin mong i-verify na ikaw iyan. Bukod pa rito, tandaang puwedeng tingnan ng kahit na sino ang mga ito, kahit na naka-lock ang iyong tablet. Posibleng hindi para sa iyong lock screen ang ilang widget at posibleng hindi ligtas ang mga ito na idagdag dito."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"I-clear lahat"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Pamahalaan"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"History"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Mga setting ng notification"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"History ng notification"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Bago"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Naka-silent"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Mga Notification"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Magsimula ngayon"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Walang mga notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Walang bagong notification"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Naka-on ang cooldown sa notification"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Babawasan ang volume at alerto nang hanggang 2 minuto kapag nakatanggap ng maraming notification."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"I-off"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"I-unlock para makita ang mga mas lumang notification"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Nakapirmi"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pag-track ng Ulo"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"I-tap para baguhin ang ringer mode"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"i-mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"i-unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"i-vibrate"</string>
@@ -1408,22 +1403,19 @@
<string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Mga kontrol ng system"</string>
<string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Mga system app"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Pag-multitask"</string>
- <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Kamakailang mga app"</string>
+ <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Mga kamakailang app"</string>
<string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
<string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
<string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Mga shortcut ng app"</string>
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Kasalukuyang App"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mga keyboard shortcut"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"I-customize ang mga keyboard shortcut"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Mga shortcut ng paghahanap"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Walang resulta ng paghahanap"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"I-collapse ang icon"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"I-customize"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Tapos na"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"I-expand ang icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handle sa pag-drag"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Ibinibigay ng mga app"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Display"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Hindi Alam"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"I-reset ang mga tile"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"I-reset ang mga tile sa orihinal na pagkakasunod-sunod at mga laki ng mga ito?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"I-reset ang lahat ng tile?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Magre-reset sa mga orihinal na setting ng device ang lahat ng tile ng Mga Mabilisang Setting"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index c79dfcf..6c2aa50 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekranınız kaydedilsin mi?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bir uygulamayı kaydet"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tüm ekranı kaydedin"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Tüm ekranı kaydet: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Tüm ekranınızı kaydettiğinizde ekranınızda gösterilen her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Bir uygulamayı kaydettiğinizde o uygulamada gösterilen veya oynatılan her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranı kaydet"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Şu anda <xliff:g id="APP_NAME">%1$s</xliff:g> içeriğini kaydediyorsunuz"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Kaydı durdur"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran paylaşılıyor"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"İçerik paylaşma"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ekran paylaşımı durdurulsun mu?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Paylaşım durdurulsun mu?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Şu anda ekranınızın tamamını <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ile paylaşıyorsunuz"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Şu anda ekranınızın tamamını bir uygulamayla paylaşıyorsunuz"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Şu anda <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> içeriğini paylaşıyorsunuz"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Şu anda bir uygulamayı paylaşıyorsunuz"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Şu anda bir uygulamayla paylaşıyorsunuz"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Paylaşımı durdur"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Ekran yayınlanıyor"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Yayın durdurulsun mu?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Kilit ekranı widget\'ları"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Kilit ekranınızdaki widget\'lar, tabletiniz kilitliyken bile herkes tarafından görüntülenebilir."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"widget\'ın seçimini kaldırın"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Yüksekliği azalt"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Yüksekliği artır"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Kilit ekranı widget\'ları"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Widget kullanarak bir uygulamayı açmak için kimliğinizi doğrulamanız gerekir. Ayrıca, tabletiniz kilitliyken bile widget\'ların herkes tarafından görüntülenebileceğini unutmayın. Bazı widget\'lar kilit ekranınız için tasarlanmamış olabileceğinden buraya eklenmeleri güvenli olmayabilir."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tümünü temizle"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Yönet"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Geçmiş"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Bildirim ayarları"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Bildirim geçmişi"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Yeni"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Sessiz"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirimler"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Bildirim yok"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildirim yok"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Bildirim şiddetini düşürme etkin"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Aynı anda çok sayıda bildirim aldığınızda 2 dakika boyunca otomatik olarak cihazınızın sesi kısılır ve uyarıları azaltılır."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Kapat"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Eski bildirimler için kilidi açın"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Sabit"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Baş Takibi"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Telefon zili modunu değiştirmek için dokunun"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"sesi kapat"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"sesi aç"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"titreşim"</string>
@@ -868,10 +863,10 @@
<string name="group_system_lock_screen" msgid="7391191300363416543">"Kilit ekranı"</string>
<string name="group_system_quick_memo" msgid="3764560265935722903">"Not al"</string>
<string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Çoklu görev"</string>
- <string name="system_multitasking_rhs" msgid="8714224917276297810">"Sağdaki mevcut uygulamayla birlikte bölünmüş ekranı kullanın"</string>
- <string name="system_multitasking_lhs" msgid="8402954791206308783">"Soldaki mevcut uygulamayla birlikte bölünmüş ekranı kullanın"</string>
+ <string name="system_multitasking_rhs" msgid="8714224917276297810">"Sağdaki mevcut uygulamayla birlikte bölünmüş ekranı kullan"</string>
+ <string name="system_multitasking_lhs" msgid="8402954791206308783">"Soldaki mevcut uygulamayla birlikte bölünmüş ekranı kullan"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Bölünmüş ekrandan tam ekrana geç"</string>
- <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran kullanırken sağdaki veya alttaki uygulamaya geçiş yapın"</string>
+ <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran kullanırken sağdaki veya alttaki uygulamaya geçiş yap"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran kullanırken soldaki veya üstteki uygulamaya geçiş yapın"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran etkinken: Bir uygulamayı başkasıyla değiştir"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Giriş"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Mevcut Uygulama"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erişilebilirlik"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klavye kısayolları"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klavye kısayollarını özelleştirin"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Arama kısayolları"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Arama sonucu yok"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Daralt simgesi"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Özelleştir"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Bitti"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Genişlet simgesi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"veya"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sürükleme tutamacı"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Uygulamalar tarafından sağlanır"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekran"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Bilinmiyor"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Kartları sıfırla"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Kartlar orijinal sıralarına ve boyutlarına sıfırlansın mı?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Tüm ayar kutuları sıfırlansın mı?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Tüm Hızlı Ayarlar kutuları cihazın özgün ayarlarına sıfırlanır"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 2808922..a7590ab 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Записати відео з екрана?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записувати один додаток"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записувати весь екран"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Записувати весь вміст екрана: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Коли ви записуєте вміст усього екрана, на відео потрапляє все, що на ньому відображається. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Коли ви записуєте додаток, на відео потрапляє все, що відображається або відтворюється в ньому. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Записувати вміст екрана"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Ви зараз записуєте вміст екрана додатка <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Зупинити запис"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Показ екрана"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Ви ділитеся контентом"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Зупинити показ екрана?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Більше не ділитися?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Ви зараз показуєте вміст усього екрана в додатку <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Ви зараз показуєте вміст усього екрана в додатку."</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Ви зараз показуєте вікно додатка <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Ви зараз показуєте вікно додатка"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Ви зараз ділитеся контентом із додатком"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Зупинити показ"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Трансляція екрана"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Зупинити трансляцію?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Віджети для заблокованого екрана"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Будь-хто бачитиме віджети навіть на заблокованому екрані планшета."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"скасувати вибір віджета"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Зменшити висоту"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Збільшити висоту"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Віджети для заблокованого екрана"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Щоб відкрити додаток за допомогою віджета, вам потрібно буде підтвердити особу. Пам’ятайте також, що бачити віджети можуть усі, навіть коли планшет заблоковано. Можливо, деякі віджети не призначені для заблокованого екрана, і додавати їх на нього може бути небезпечно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Очистити все"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Керувати"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Історія"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Налаштування сповіщень"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Історія сповіщень"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Нові"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Без звуку"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Сповіщення"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Сповіщень немає"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Немає нових сповіщень"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Зниження гучності сповіщень увімкнено"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Коли ви отримуєте забагато сповіщень за раз, пристрій автоматично знижує їх гучність і кількість на період до 2 хвилин."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Вимкнути"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Розблокуйте, щоб переглянути старіші"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Завжди ввімкнено"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Відстеження рухів голови"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Торкніться, щоб змінити режим дзвінка"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"вимкнути звук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"увімкнути звук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"увімкнути вібросигнал"</string>
@@ -860,8 +855,8 @@
<string name="group_system_go_back" msgid="2730322046244918816">"Назад"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"Перейти на головний екран"</string>
<string name="group_system_overview_open_apps" msgid="5659958952937994104">"Переглянути нещодавні додатки"</string>
- <string name="group_system_cycle_forward" msgid="5478663965957647805">"Перемикатися між нещодавніми додатками вперед"</string>
- <string name="group_system_cycle_back" msgid="8194102916946802902">"Перемикатися між нещодавніми додатками назад"</string>
+ <string name="group_system_cycle_forward" msgid="5478663965957647805">"Прокрутити вперед список нещодавніх додатків"</string>
+ <string name="group_system_cycle_back" msgid="8194102916946802902">"Прокрутити назад список нещодавніх додатків"</string>
<string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Відкрити список додатків"</string>
<string name="group_system_access_system_settings" msgid="8731721963449070017">"Відкрити налаштування"</string>
<string name="group_system_access_google_assistant" msgid="7210074957915968110">"Відкрити додаток Асистент"</string>
@@ -871,7 +866,7 @@
<string name="system_multitasking_rhs" msgid="8714224917276297810">"Розділити екран і показувати поточний додаток праворуч"</string>
<string name="system_multitasking_lhs" msgid="8402954791206308783">"Розділити екран і показувати поточний додаток ліворуч"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"Перейти з розділення екрана на весь екран"</string>
- <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Під час розділення екрана перемикатися на додаток праворуч або внизу"</string>
+ <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти до додатка праворуч або внизу на розділеному екрані"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Під час розділення екрана перемикатися на додаток ліворуч або вгорі"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Під час розділення екрана: замінити додаток іншим"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Метод введення"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Поточний додаток"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Комбінації клавіш"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Налаштуйте комбінації клавіш"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Комбінації клавіш для пошуку"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нічого не знайдено"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок згортання"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Налаштувати"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок розгортання"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер переміщення"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Надано додатками"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Екран"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Невідомо"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Скинути панелі"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Відновити початковий порядок і розмір панелей?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Скинути всі панелі?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Усі панелі швидких налаштувань буде скинуто до стандартних налаштувань пристрою"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index b72464ca..f377ecd 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"آپ کی اسکرین ریکارڈ کریں؟"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ایک ایپ ریکارڈ کریں"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"پوری اسکرین کو ریکارڈ کریں"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"پوری اسکرین ریکارڈ کریں: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"جب آپ اپنی پوری اسکرین کو ریکارڈ کر رہے ہوتے ہیں تو آپ کی اسکرین پر دکھائی گئی ہر چیز ریکارڈ کی جاتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"جب آپ کسی ایپ کو ریکارڈ کر رہے ہوتے ہیں تو اس ایپ میں دکھائی گئی یا چلائی گئی ہر چیز ریکارڈ کی جاتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"اسکرین ریکارڈ کریں"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"آپ فی الحال <xliff:g id="APP_NAME">%1$s</xliff:g> ریکارڈ کر رہے ہیں"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"ریکارڈنگ روکیں"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"اسکرین کا اشتراک ہو رہا ہے"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"مواد کا اشتراک کیا جا رہا ہے"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"اسکرین کا اشتراک روکیں؟"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"اشتراک کرنا روکیں؟"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"آپ فی الحال <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> کے ساتھ اپنی پوری اسکرین کا اشتراک کر رہے ہیں"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"آپ فی الحال ایک ایپ کے ساتھ اپنی پوری اسکرین کا اشتراک کر رہے ہیں"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"آپ فی الحال <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> کا اشتراک کر رہے ہیں"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"آپ فی الحال ایک ایپ کا اشتراک کر رہے ہیں"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"آپ فی الحال ایک ایپ کے ساتھ اشتراک کر رہے ہیں"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"اشتراک کرنا روکیں"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"اسکرین کاسٹ ہو رہی ہے"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"کاسٹ کرنا بند کریں؟"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"مقفل اسکرین کے ویجیٹس"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"کوئی بھی آپ کی مقفل اسکرین پر ویجیٹ دیکھ سکتا ہے اگرچہ آپ کا ٹیبلیٹ مقفل ہو۔"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"ویجیٹ غیر منتخب کریں"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"اونچائی کم کریں"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"اونچائی بڑھائیں"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"مقفل اسکرین کے ویجیٹس"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ویجیٹ کے ذریعے ایپ کھولنے کے لیے آپ کو تصدیق کرنی ہوگی کہ یہ آپ ہی ہیں۔ نیز، ذہن میں رکھیں کہ کوئی بھی انہیں دیکھ سکتا ہے، یہاں تک کہ جب آپ کا ٹیبلیٹ مقفل ہو۔ ہو سکتا ہے کچھ ویجٹس آپ کی لاک اسکرین کے لیے نہ بنائے گئے ہوں اور یہاں شامل کرنا غیر محفوظ ہو سکتا ہے۔"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"سمجھ آ گئی"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"سبھی کو صاف کریں"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"نظم کریں"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"سرگزشت"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"اطلاع کی ترتیبات"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"اطلاع کی سرگزشت"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"نیا"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"خاموش"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"اطلاعات"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ابھی شروع کریں"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"کوئی اطلاعات نہیں ہیں"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"کوئی نئی اطلاعات نہیں"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"ںوٹیفیکیشن کول ڈاؤن آن ہے"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"جب آپ کو ایک ساتھ بہت زیادہ اطلاعات موصول ہوتی ہیں تو آپ کے آلے کا والیوم اور الرٹس خودکار طور پر 2 منٹ تک کم ہو جاتے ہیں۔"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"آف کریں"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"پرانی اطلاعات دیکھنے کیلئے غیر مقفل کریں"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"مقرر"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"سر کی ٹریکنگ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"رنگر وضع تبدیل کرنے کیلئے تھپتھپائیں"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"خاموش کریں"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"غیر خاموش کریں"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"وائبریٹ"</string>
@@ -865,7 +860,7 @@
<string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ایپس کی فہرست کھولیں"</string>
<string name="group_system_access_system_settings" msgid="8731721963449070017">"ترتیبات کھولیں"</string>
<string name="group_system_access_google_assistant" msgid="7210074957915968110">"اسسٹنٹ کھولیں"</string>
- <string name="group_system_lock_screen" msgid="7391191300363416543">"مقفل اسکرین"</string>
+ <string name="group_system_lock_screen" msgid="7391191300363416543">"اسکرین لاک کریں"</string>
<string name="group_system_quick_memo" msgid="3764560265935722903">"نوٹ لیں"</string>
<string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"ملٹی ٹاسکنگ"</string>
<string name="system_multitasking_rhs" msgid="8714224917276297810">"دائیں جانب موجودہ ایپ کے ساتھ اسپلٹ اسکرین کا استعمال کریں"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"موجودہ ایپ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ایکسیسبیلٹی"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"کی بورڈ شارٹ کٹس"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"کی بورڈ شارٹ کٹس کو حسب ضرورت بنائیں"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"تلاش کے شارٹ کٹس"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"تلاش کا کوئی نتیجہ نہیں ہے"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"آئیکن سکیڑیں"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"حسب ضرورت بنائیں"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ہو گیا"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"آئیکن پھیلائیں"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"گھسیٹنے کا ہینڈل"</string>
@@ -1431,11 +1423,11 @@
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"اپنے کی بورڈ کا استعمال کر کے نیویگیٹ کریں"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"کی بورڈ شارٹ کٹس جانیں"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"اپنے ٹچ پیڈ کا استعمال کر کے نیویگیٹ کریں"</string>
- <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"ٹچ پیڈ کے اشارے کو جانیں"</string>
+ <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"ٹچ پیڈ کے اشاروں کو جانیں"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"اپنے کی بورڈ اور ٹچ پیڈ کا استعمال کر کے نیویگیٹ کریں"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"ٹچ پیڈ کے اشارے، کی بورڈ شارٹ کٹس اور مزید جانیں"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"واپس جائیں"</string>
- <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"گھر جائیں"</string>
+ <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"ہوم پر جائیں"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"حالیہ ایپس دیکھیں"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ہو گیا"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"واپس جائیں"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"ایپس کے ذریعہ فراہم کردہ"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"ڈسپلے"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"نامعلوم"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"ٹائلز ری سیٹ کریں"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"ٹائلز کو ان کے اصل آرڈر اور سائزز پر ری سیٹ کریں؟"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"سبھی ٹائلز ری سیٹ کریں؟"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"سبھی فوری ترتیبات کی ٹائلز آلہ کی اصل ترتیبات پر ری سیٹ ہو جائیں گی"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 7f6275c..f8b944a 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekran yozib olinsinmi?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bitta ilovani yozib olish"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Butun ekranni yozib olish"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Butun ekranni yozib olish: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Butun ekranni yozib olishda ekranda koʻrsatilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ilovani yozib olishda ilova koʻrsatilgan yoki ijro etilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranni yozib olish"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Hozir <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi yozib olinmoqda"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Yozuvni toʻxtatish"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran ulashilmoqda"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Kontent ulashilmoqda"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Ekran namoyishi toʻxtatilsinmi?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Ulashuv tugatilsinmi?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Hozir butun ekran <xliff:g id="HOST_APP_NAME">%1$s</xliff:g> ilovasiga ulashilmoqda"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Hozir butun ekran ilovaga ulashilmoqda"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Hozir <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g> ilovasiga kontent ulashilmoqda"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Hozir ilovaga kontent ulashilmoqda"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Hozir ilova bilan ulashilmoqda"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Namoyishni toʻxtatish"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Ekran translatsiya qilinmoqda"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Toʻxtatilsinmi?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Ekran qulfi vidjetlari"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Ekran quflidagi vidjetlar hammaga koʻrinadi, hatto planshet qulflanganda ham."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"vidjetni bekor qilish"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Balandligini kichraytirish"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Balandligini oshirish"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Ekran qulfi vidjetlari"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ilovani vidjet orqali ochish uchun shaxsingizni tasdiqlashingiz kerak. Shuningdek, planshet qulflanganda ham bu axborotlar hammaga koʻrinishini unutmang. Ayrim vidjetlar ekran qulfiga moslanmagan va ularni bu yerda chiqarish xavfli boʻlishi mumkin."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hammasini tozalash"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Boshqarish"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Tarix"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Bildirishnoma sozlamalari"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Bildirishnomalar tarixi"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Yangi"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Sokin"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirishnomalar"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Boshlash"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Bildirishnomalar yo‘q"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Yangi bildirishoma yoʻq"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Bildirishnomalar ovozini pasaytirish yoniq"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Bir vaqtda juda koʻp bildirishnoma olsangiz, qurilmangiz tovushi va ogohlantirishlar 2 daqiqagacha avtomatik pasaytiriladi."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Faolsizlantirish"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Eskilarini koʻrish uchun qulfni yeching"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Statik"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Boshni kuzatish"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Jiringlagich rejimini oʻzgartirish uchun bosing"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ovozsiz qilish"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ovozni yoqish"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"tebranish"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Joriy ilova"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tezkor tugmalarni moslash"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tezkor tugmalar qidiruvi"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hech narsa topilmadi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Yigʻish belgisi"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Moslash"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Tayyor"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Yoyish belgisi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"yoki"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Surish dastagi"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Ilovalarga tegishli"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Ekran"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Noaniq"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Katakchalarni asliga qaytarish"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Katakchalar asl tartibi va oʻlchamiga qaytarilsinmi?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Barcha katakchalar asliga qaytarilsinmi?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Barcha Tezkor sozlamalar katakchalari qurilmaning asl sozlamalariga qaytariladi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 388ebb8..bdcea11 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ghi màn hình?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ghi một ứng dụng"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Ghi toàn màn hình"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Ghi toàn bộ màn hình: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Khi bạn ghi toàn màn hình, mọi nội dung trên màn hình của bạn đều được ghi. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Khi bạn ghi một ứng dụng, mọi nội dung xuất hiện hoặc phát trong ứng dụng đó sẽ đều được ghi. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ghi màn hình"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Bạn đang ghi lại nội dung của <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Dừng ghi"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Đang chia sẻ màn hình"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Chia sẻ nội dung"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Dừng chia sẻ màn hình?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Dừng chia sẻ?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Bạn đang chia sẻ toàn bộ nội dung trên màn hình với <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Bạn đang chia sẻ toàn bộ nội dung trên màn hình với một ứng dụng"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Bạn đang chia sẻ nội dung của <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Bạn đang chia sẻ một ứng dụng"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Bạn đang chia sẻ với một ứng dụng"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Dừng chia sẻ"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Đang truyền màn hình"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Dừng truyền?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Tiện ích trên màn hình khoá"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Ai cũng thấy được tiện ích trên màn hình khoá, kể cả khi khoá máy tính bảng."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"bỏ chọn tiện ích"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Giảm chiều cao"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Tăng chiều cao"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Tiện ích trên màn hình khoá"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Để dùng tiện ích mở một ứng dụng, bạn cần xác minh danh tính của mình. Ngoài ra, hãy lưu ý rằng bất kỳ ai cũng có thể xem các tiện ích này, ngay cả khi máy tính bảng của bạn được khoá. Một số tiện ích có thể không dành cho màn hình khoá và không an toàn khi thêm vào đây."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Tôi hiểu"</string>
@@ -595,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Không có thông báo nào"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Không có thông báo mới"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Chế độ Giảm dần âm lượng thông báo đang bật"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Khi bạn nhận quá nhiều thông báo cùng lúc, âm lượng và cảnh báo tự động giảm trong tối đa 2 phút."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Tắt"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Mở khoá để xem thông báo cũ"</string>
@@ -703,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Cố định"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Theo dõi chuyển động của đầu"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Nhấn để thay đổi chế độ chuông"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"tắt tiếng"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"bật tiếng"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"rung"</string>
@@ -1403,7 +1400,7 @@
<string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) đang dùng"</string>
<string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) đã dùng gần đây"</string>
<string name="shortcut_helper_category_system" msgid="462110876978937359">"Hệ thống"</string>
- <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Cài đặt hệ thống"</string>
+ <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Điều khiển hệ thống"</string>
<string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Ứng dụng hệ thống"</string>
<string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Đa nhiệm"</string>
<string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ứng dụng gần đây"</string>
@@ -1413,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Ứng dụng hiện tại"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hỗ trợ tiếp cận"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Phím tắt"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
- <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Lối tắt tìm kiếm"</string>
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tuỳ chỉnh phím tắt"</string>
+ <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tìm lối tắt"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Không có kết quả tìm kiếm nào"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Biểu tượng Thu gọn"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tuỳ chỉnh"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Xong"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Biểu tượng Mở rộng"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"hoặc"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Nút kéo"</string>
@@ -1483,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Do các ứng dụng cung cấp"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Hiển thị"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Không xác định"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Đặt lại các ô"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Đặt lại các ô về thứ tự và kích thước ban đầu?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Đặt lại mọi ô?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Mọi ô Cài đặt nhanh sẽ được đặt lại về chế độ cài đặt ban đầu của thiết bị"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index b463900..2101539 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要录制屏幕吗?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"录制单个应用"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"录制整个屏幕"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"全屏录制:%s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"录制整个屏幕时,屏幕上显示的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"录制单个应用时,该应用中显示或播放的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"录制屏幕"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"您正在录制“<xliff:g id="APP_NAME">%1$s</xliff:g>”"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"停止录制"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在共享屏幕"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"分享内容"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"要停止共享屏幕吗?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"要停止分享吗?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"您正在与“<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>”分享整个屏幕"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"您正在与一个应用分享整个屏幕"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"您正在分享“<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>”的画面"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"您正在分享一个应用的画面"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"您目前正在与应用进行分享"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"停止共享"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"正在投屏"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"停止投屏吗?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"锁屏微件"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"任何人都可以查看锁屏上的微件,平板电脑处于锁定状态时也是如此。"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"取消选中微件"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"减小高度"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"增加高度"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"锁屏微件"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"若要使用微件打开应用,您需要验证是您本人在操作。另外请注意,任何人都可以查看此类微件,即使您的平板电脑已锁定。有些微件可能不适合显示在锁定的屏幕中,因此添加到这里可能不安全。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"历史记录"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"通知设置"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"通知历史记录"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"最新"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"静音"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即开始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"没有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"没有新通知"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"已触发“通知音量渐降”"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"如果您在短时间内收到很多通知,设备音量和提醒次数会自动降低,最长持续 2 分钟。"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"关闭"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解锁即可查看旧通知"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"固定"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"头部跟踪"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"点按即可更改振铃器模式"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"静音"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消静音"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"振动"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"当前应用"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"无障碍功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"键盘快捷键"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自定义键盘快捷键"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜索快捷键"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"无搜索结果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收起图标"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"自定义"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完成"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展开图标"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖动手柄"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"由应用提供"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"显示"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"未知"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"重置功能块"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"要将功能块重置为原始排序和大小吗?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"要重置所有功能块吗?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"所有“快捷设置”功能块都将重置为设备的原始设置"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 9118591..b2e7886 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要錄影螢幕畫面嗎?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"錄影一個應用程式"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"錄影整個螢幕畫面"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"錄製整個螢幕:%s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"當你錄影整個螢幕畫面時,系統會錄影螢幕畫面上顯示的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"當你錄影應用程式時,系統會錄影該應用程式中顯示或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"錄影螢幕畫面"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"你正在錄影「<xliff:g id="APP_NAME">%1$s</xliff:g>」"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"停止錄製"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在分享螢幕"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"分享內容"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"要停止分享螢幕嗎?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"要停止分享嗎?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"你正與「<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>」分享整個螢幕畫面"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"你正與一個應用程式分享整個螢幕畫面"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"你正在分享「<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>」"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"你正在分享一個應用程式"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"你正與一個應用程式分享內容"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"停止分享"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"正在投放螢幕"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"要停止投放嗎?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"上鎖畫面小工具"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"無論平板電腦的螢幕是否已上鎖,任何人都可以看到上鎖畫面小工具。"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"取消揀小工具"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"調低高度"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"調高高度"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"上鎖畫面小工具"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,系統會要求你驗證身分。請注意,所有人都能查看小工具,即使平板電腦已鎖定亦然。部分小工具可能不適用於上鎖畫面,新增至這裡可能會有安全疑慮。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"記錄"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"通知設定"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"通知記錄"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"新"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"靜音"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"通知緩和已開啟"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"當你在短時間內收到太多通知時,裝置就會調低音量並減少通知數量最多兩分鐘。"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"固定"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"頭部追蹤"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"輕按即可變更響鈴模式"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"震動"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"目前的應用程式"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"沒有相符的搜尋結果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"自訂"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完成"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"由應用程式提供"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"螢幕"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"重設圖塊"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"要重設圖塊的順序和大小嗎?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"要重設所有圖塊嗎?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"所有「快速設定」圖塊將重設為裝置的原始設定"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 2189cbf..adb2838 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要錄製畫面嗎?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"錄製單一應用程式"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"錄製整個畫面"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"錄製整個畫面:%s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"錄製整個畫面時,系統會錄下畫面上的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"當你錄製應用程式畫面時,系統會錄下該應用程式顯示或播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"錄製畫面"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"目前正在錄製「<xliff:g id="APP_NAME">%1$s</xliff:g>」的畫面"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"停止錄製"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在分享畫面"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"正在分享內容"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"停止分享?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"要停止分享嗎?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"目前正在與「<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>」分享整個畫面"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"目前正在與某個應用程式分享整個畫面"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"目前正在分享「<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>」的畫面"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"目前正在分享應用程式畫面"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"目前正在與應用程式分享內容"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"停止分享"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"正在投放畫面"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"停止投放?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"螢幕鎖定小工具"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"即使平板電腦已鎖定,所有人仍可查看螢幕鎖定畫面上的小工具。"</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"取消選取小工具"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"調低"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"調高"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"螢幕鎖定小工具"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,需先驗證身分。請留意,即使平板電腦已鎖定,所有人都還是能查看小工具。某些小工具可能不適用於螢幕鎖定畫面,新增到此可能會有安全疑慮。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"我知道了"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"記錄"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"通知設定"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"通知記錄"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"最新"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"靜音"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"通知緩和設定已開啟"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"如果一次收到過多通知,裝置就會自動降低音量並減少通知數量,持續時間最多 2 分鐘。"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"固定"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"頭部追蹤"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"輕觸即可變更鈴聲模式"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"震動"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"目前的應用程式"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"找不到相符的搜尋結果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"自訂"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完成"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"由應用程式提供"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"螢幕"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"不明"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"重設設定方塊"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"要將設定方塊的順序和大小恢復預設值嗎?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"要重設所有設定方塊嗎?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"所有快速設定方塊都會恢復裝置的原始設定"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 05b5040..245ece8 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -112,8 +112,7 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rekhoda isikrini sakho?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rekhoda i-app eyodwa"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rekhoda sonke isikrini"</string>
- <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
- <skip />
+ <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Rekhoda sonke isikrini: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Uma urekhoda sonke isikrini sakho, noma yini evela esikrinini iyarekhodwa. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yenkokhelo, imilayezo, izithombe, nomsindo nevidiyo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Uma urekhoda i-app, noma yini evezwa noma edlala kuleyo app iyarekhodwa. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yenkokhelo, imilayezo, izithombe, nomsindo nevidiyo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rekhoda isikrini"</string>
@@ -138,17 +137,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Njengamanje urekhoda i-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Misa ukurekhoda"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Yabelana ngesikrini"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Ukwabelana ngokuqukethwe"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Misa ukwabelana ngeskrini?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Misa ukwabelana?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Njengamanje wabelana ngaso sonke isikrini sakho ne-<xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Njengamanje wabelana ngaso sonke isikrini sakho ne-app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Njengamanje wabelana nge-<xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Njengamanje wabelana nge-app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Njengamanje wabelana ne-app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Misa ukwabelana"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Isikrini sokusakaza"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Misa ukusakaza?"</string>
@@ -523,10 +519,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Amawijethi wesikrini esikhiyiwe"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Noma ubani angabuka amawijethi ngisho noma ithebulethi ikhiyiwe."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"yeka ukukhetha iwijethi"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Nciphisa ubude"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Khuphula ubude"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Amawijethi wesikrini esikhiyiwe"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ukuze uvule i-app usebenzisa iwijethi, uzodinga ukuqinisekisa ukuthi nguwe. Futhi, khumbula ukuthi noma ubani angakwazi ukuzibuka, nanoma ithebhulethi yakho ikhiyiwe. Amanye amawijethi kungenzeka abengahloselwe ukukhiya isikrini sakho futhi kungenzeka awaphephile ukuthi angafakwa lapha."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ngiyezwa"</string>
@@ -583,10 +577,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Sula konke"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Phatha"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Umlando"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Amasethingi esaziso"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Umlando wesaziso"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Okusha"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Kuthulile"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Izaziso"</string>
@@ -597,7 +589,8 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Azikho izaziso"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Azikho izaziso ezintsha"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="7790738150177329960">"Ukwehlisa umsindo wezaziso kuvuliwe"</string>
+ <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
+ <skip />
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Ivolumu yedivayisi yakho kanye nezexwayiso kuncishiswa ngokuzenzakalelayo imizuzu efika kwemi-2 lapho uthola izaziso eziningi kakhulu ngesikhathi esisodwa."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vala"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vula ukuze ubone izaziso ezindala"</string>
@@ -705,6 +698,8 @@
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Okugxilile"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Ukulandelela Ikhanda"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Thepha ukuze ushintshe imodi yokukhala"</string>
+ <!-- no translation found for volume_ringer_mode (6867838048430807128) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"thulisa"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"susa ukuthula"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"dlidliza"</string>
@@ -1415,15 +1410,12 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"I-App yamanje"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ukufinyeleleka"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Izinqamuleli zekhibhodi"</string>
- <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Hlela izinqamuleli zekhibhodi ngendlela oyifisayo"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sesha izinqamuleli"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ayikho imiphumela yosesho"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Goqa isithonjana"</string>
- <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
- <skip />
- <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
- <skip />
+ <string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Enza ngendlela oyifisayo"</string>
+ <string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Kwenziwe"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Nweba isithonjana"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"noma"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Hudula isibambi"</string>
@@ -1485,6 +1477,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Kuhlinzekwe ama-app"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Bonisa"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Akwaziwa"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="8841270491554460726">"Setha amathayela kabusha"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="8626426097929954027">"Setha kabusha amathayela ekuhlelekeni nakosayizi bawo bangempela?"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Qala kabusha onke amathayela?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Ithayela Lamasethingi Asheshayo lizosetha kabusha libuyele kumasethingi okuqala edivayisi"</string>
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index c8ef093..82c8c44 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -116,7 +116,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
- internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue,hearing_devices
+ internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue,hearing_devices,notes
</string>
<!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1766cdf..53ab686 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -794,6 +794,7 @@
<!-- QuickSettings: Bluetooth secondary label shown when bluetooth is being enabled [CHAR LIMIT=NONE] -->
<string name="quick_settings_bluetooth_secondary_label_transient">Turning on…</string>
<!-- QuickSettings: Brightness [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_brightness_unable_adjust_msg">Can\'t adjust brightness because it\'s being\n controlled by the top app</string>
<!-- QuickSettings: Rotation Unlocked [CHAR LIMIT=NONE] -->
<string name="quick_settings_rotation_unlocked_label">Auto-rotate</string>
<!-- Accessibility label for Auto-ratate QuickSettings tile [CHAR LIMIT=NONE] -->
@@ -1004,6 +1005,9 @@
<!-- QuickSettings: Tool name for hearing devices dialog related tools [CHAR LIMIT=40] [BACKUP_MESSAGE_ID=8916875614623730005]-->
<string name="quick_settings_hearing_devices_live_caption_title">Live Caption</string>
+ <!-- QuickSettings: Notes tile. The label of a quick settings tile for launching the default notes taking app. [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_notes_label">Note</string>
+
<!--- Title of dialog triggered if the microphone is disabled but an app tried to access it. [CHAR LIMIT=150] -->
<string name="sensor_privacy_start_use_mic_dialog_title">Unblock device microphone?</string>
<!--- Title of dialog triggered if the camera is disabled but an app tried to access it. [CHAR LIMIT=150] -->
@@ -1518,7 +1522,7 @@
<string name="no_unseen_notif_text">No new notifications</string>
<!-- Title of heads up notification for adaptive notifications user education. [CHAR LIMIT=60] -->
- <string name="adaptive_notification_edu_hun_title">Notification cooldown is on</string>
+ <string name="adaptive_notification_edu_hun_title">Notification cooldown is now on</string>
<!-- Text of heads up notification for adaptive notifications user education. [CHAR LIMIT=100] -->
<string name="adaptive_notification_edu_hun_text">Your device volume and alerts are reduced automatically for up to 2 minutes when you get too many notifications at once.</string>
@@ -2270,6 +2274,8 @@
<string name="system_multitasking_splitscreen_focus_lhs">Switch to app on left or above while using split screen</string>
<!-- User visible title for the keyboard shortcut that replaces an app from one to another during split screen [CHAR LIMIT=70] -->
<string name="system_multitasking_replace">During split screen: replace an app from one to another</string>
+ <!-- User visible title for the keyboard shortcut that moves a focused task to a next display [CHAR LIMIT=70] -->
+ <string name="system_multitasking_move_to_next_display">Move active window between displays</string>
<!-- User visible title for the input keyboard shortcuts list. [CHAR LIMIT=70] -->
<string name="keyboard_shortcut_group_input">Input</string>
@@ -3738,6 +3744,11 @@
is a component that shows the user which keyboard shortcuts they can use.
[CHAR LIMIT=NONE] -->
<string name="shortcut_helper_customize_mode_title">Customize keyboard shortcuts</string>
+ <!-- Sub title at the top of the keyboard shortcut helper customization dialog. Explains to the
+ user what action they need to take in the customization dialog to assign a new custom shortcut.
+ The helper is a component that shows the user which keyboard shortcuts they can use.
+ [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_customize_mode_sub_title">Press key to assign shortcut</string>
<!-- Placeholder text shown in the search box of the keyboard shortcut helper, when the user
hasn't typed in anything in the search box yet. The helper is a component that shows the
user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
@@ -3749,6 +3760,16 @@
use. The helper shows shortcuts in categories, which can be collapsed or expanded.
[CHAR LIMIT=NONE] -->
<string name="shortcut_helper_content_description_collapse_icon">Collapse icon</string>
+ <!-- Content description of the Meta key (also called Action Key) icon that prompts users to
+ press some key combination starting with meta key to assign new key combination to shortcut
+ in shortcut helper customization dialog. The helper is a component that shows the user
+ which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_content_description_meta_key">Action or Meta key icon</string>
+ <!-- Content description of the plus icon after the meta key icon prompts users to
+ press some key combination starting with meta key to assign new key combination to shortcut
+ in shortcut helper customization dialog. The helper is a component that shows the user
+ which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_content_description_plus_icon">Plus icon</string>
<!-- Description text of the button that allows user to customize shortcuts in keyboard
shortcut helper The helper is a component that shows the user which keyboard shortcuts
they can use. [CHAR LIMIT=NONE] -->
@@ -3779,6 +3800,24 @@
open keyboard settings while in shortcut helper. The helper is a component that shows the
user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
<string name="shortcut_helper_keyboard_settings_buttons_label">Keyboard Settings</string>
+ <!-- Label on the set shortcut button in keyboard shortcut helper customize dialog, that allows user to
+ confirm and assign key combination to selected shortcut. The helper is a component that
+ shows the user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label">Set shortcut</string>
+ <!-- Label on the cancel button in keyboard shortcut helper customize dialog, that allows user to
+ cancel and exit shortcut customization dialog, returning to the main shortcut helper page.
+ The helper is a component that shows the user which keyboard shortcuts they can use.
+ [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_customize_dialog_cancel_button_label">Cancel</string>
+ <!-- Placeholder text, prompting user to Press key combination assign to shortcut. This is shown
+ in shortcut helper's "Add Custom Shortcut" Dialog text field when user hasn't pressed
+ any key yet. The helper is a component that shows the user which keyboard shortcuts
+ they can use. [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder">Press key</string>
+ <!-- Error message displayed when the user select a key combination that is already in use while
+ assigning a new custom key combination to a shortcut in shortcut helper. The helper is a
+ component that shows the user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_customize_dialog_error_message">Key combination already in use. Try another key.</string>
<!-- Keyboard touchpad tutorial scheduler-->
diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml
index ad09b46..d885e00 100644
--- a/packages/SystemUI/res/values/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values/tiles_states_strings.xml
@@ -348,4 +348,14 @@
<item>Off</item>
<item>On</item>
</string-array>
+
+ <!-- State names for notes tile: unavailable, off, on.
+ This subtitle is shown when the tile is in that particular state but does not set its own
+ subtitle, so some of these may never appear on screen. They should still be translated as
+ if they could appear. [CHAR LIMIT=32] -->
+ <string-array name="tile_states_notes">
+ <item>Unavailable</item>
+ <item>Off</item>
+ <item>On</item>
+ </string-array>
</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
index 283e455..83ca496 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
@@ -115,23 +115,23 @@
/**
* Sent when {@link TaskbarDelegate#checkNavBarModes} is called.
*/
- void checkNavBarModes() = 30;
+ void checkNavBarModes(int displayId) = 30;
/**
* Sent when {@link TaskbarDelegate#finishBarAnimations} is called.
*/
- void finishBarAnimations() = 31;
+ void finishBarAnimations(int displayId) = 31;
/**
* Sent when {@link TaskbarDelegate#touchAutoDim} is called. {@param reset} is true, when auto
* dim is reset after a timeout.
*/
- void touchAutoDim(boolean reset) = 32;
+ void touchAutoDim(int displayid, boolean reset) = 32;
/**
* Sent when {@link TaskbarDelegate#transitionTo} is called.
*/
- void transitionTo(int barMode, boolean animate) = 33;
+ void transitionTo(int displayId, int barMode, boolean animate) = 33;
/**
* Sent when {@link TaskbarDelegate#appTransitionPending} is called.
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index 6209ed8..e332280 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -21,6 +21,7 @@
import android.graphics.Rect;
import android.os.Bundle;
import android.os.UserHandle;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import com.android.internal.util.ScreenshotRequest;
@@ -102,9 +103,9 @@
oneway void expandNotificationPanel() = 29;
/**
- * Notifies SystemUI to invoke Back.
+ * Notifies SystemUI of a back KeyEvent.
*/
- oneway void onBackPressed() = 44;
+ oneway void onBackEvent(in KeyEvent keyEvent) = 44;
/** Sets home rotation enabled. */
oneway void setHomeRotationEnabled(boolean enabled) = 45;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index 7ec977a..9e8cabf 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -243,10 +243,6 @@
public Rect appBounds;
- // Last snapshot data, only used for recent tasks
- public ActivityManager.RecentTaskInfo.PersistedTaskSnapshotData lastSnapshotData =
- new ActivityManager.RecentTaskInfo.PersistedTaskSnapshotData();
-
@ViewDebug.ExportedProperty(category="recents")
public boolean isVisible;
@@ -283,7 +279,6 @@
public Task(Task other) {
this(other.key, other.colorPrimary, other.colorBackground, other.isDockable,
other.isLocked, other.taskDescription, other.topActivity);
- lastSnapshotData.set(other.lastSnapshotData);
positionInParent = other.positionInParent;
appBounds = other.appBounds;
isVisible = other.isVisible;
@@ -315,33 +310,10 @@
: key.baseIntent.getComponent();
}
- public void setLastSnapshotData(ActivityManager.RecentTaskInfo rawTask) {
- lastSnapshotData.set(rawTask.lastSnapshotData);
- }
-
public TaskKey getKey() {
return key;
}
- /**
- * Returns the visible width to height ratio. Returns 0f if snapshot data is not available.
- */
- public float getVisibleThumbnailRatio(boolean clipInsets) {
- if (lastSnapshotData.taskSize == null || lastSnapshotData.contentInsets == null) {
- return 0f;
- }
-
- float availableWidth = lastSnapshotData.taskSize.x;
- float availableHeight = lastSnapshotData.taskSize.y;
- if (clipInsets) {
- availableWidth -=
- (lastSnapshotData.contentInsets.left + lastSnapshotData.contentInsets.right);
- availableHeight -=
- (lastSnapshotData.contentInsets.top + lastSnapshotData.contentInsets.bottom);
- }
- return availableWidth / availableHeight;
- }
-
@Override
public boolean equals(Object o) {
if (o == this) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 8b59370..8ca0e80 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -121,6 +121,7 @@
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.CoreStartable;
import com.android.systemui.Dumpable;
+import com.android.systemui.Flags;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
@@ -218,7 +219,6 @@
private static final int MSG_USER_UNLOCKED = 334;
private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
private static final int MSG_BIOMETRIC_AUTHENTICATION_CONTINUE = 336;
- private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
private static final int MSG_TELEPHONY_CAPABLE = 338;
private static final int MSG_TIMEZONE_UPDATE = 339;
private static final int MSG_USER_STOPPED = 340;
@@ -401,7 +401,6 @@
protected int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
private boolean mFingerprintDetectRunning;
private boolean mIsDreaming;
- private boolean mLogoutEnabled;
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private final FingerprintInteractiveToAuthProvider mFingerprintInteractiveToAuthProvider;
@@ -473,6 +472,7 @@
}
}
+ @Deprecated
private final SparseBooleanArray mUserIsUnlocked = new SparseBooleanArray();
private final SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
private final SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
@@ -1737,9 +1737,6 @@
mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
} else if (TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) {
mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
- } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
- action)) {
- mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
}
}
};
@@ -2326,9 +2323,6 @@
case MSG_BIOMETRIC_AUTHENTICATION_CONTINUE:
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
break;
- case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
- updateLogoutEnabled();
- break;
case MSG_TELEPHONY_CAPABLE:
updateTelephonyCapable((boolean) msg.obj);
break;
@@ -2494,7 +2488,6 @@
boolean isUserUnlocked = mUserManager.isUserUnlocked(user);
mLogger.logUserUnlockedInitialState(user, isUserUnlocked);
mUserIsUnlocked.put(user, isUserUnlocked);
- mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
updateSecondaryLockscreenRequirement(user);
List<UserInfo> allUsers = mUserManager.getUsers();
for (UserInfo userInfo : allUsers) {
@@ -2688,7 +2681,11 @@
* @see Intent#ACTION_USER_UNLOCKED
*/
public boolean isUserUnlocked(int userId) {
- return mUserIsUnlocked.get(userId);
+ if (Flags.userEncryptedSource()) {
+ return mUserManager.isUserUnlocked(userId);
+ } else {
+ return mUserIsUnlocked.get(userId);
+ }
}
/**
@@ -4054,28 +4051,6 @@
return null; // not found
}
- /**
- * @return a cached version of DevicePolicyManager.isLogoutEnabled()
- */
- public boolean isLogoutEnabled() {
- return mLogoutEnabled;
- }
-
- private void updateLogoutEnabled() {
- Assert.isMainThread();
- boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
- if (mLogoutEnabled != logoutEnabled) {
- mLogoutEnabled = logoutEnabled;
-
- for (int i = 0; i < mCallbacks.size(); i++) {
- KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
- if (cb != null) {
- cb.onLogoutEnabledChanged();
- }
- }
- }
- }
-
protected int getBiometricLockoutDelay() {
return BIOMETRIC_LOCKOUT_RESET_DELAY_MS;
}
@@ -4213,7 +4188,7 @@
pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
pw.println("ActiveUnlockRunning="
+ mTrustManager.isActiveUnlockRunning(mSelectedUserInteractor.getSelectedUserId()));
- pw.println("userUnlockedCache[userid=" + userId + "]=" + isUserUnlocked(userId));
+ pw.println("userUnlockedCache[userid=" + userId + "]=" + mUserIsUnlocked.get(userId));
pw.println("actualUserUnlocked[userid=" + userId + "]="
+ mUserManager.isUserUnlocked(userId));
new DumpsysTableLogger(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 7ac5ac2..fdee21b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -286,11 +286,6 @@
public void onTrustAgentErrorMessage(CharSequence message) { }
/**
- * Called when a value of logout enabled is change.
- */
- public void onLogoutEnabledChanged() { }
-
- /**
* Called when authenticated fingerprint biometrics are cleared.
*/
public void onFingerprintsCleared() { }
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
index ef172a1..d6648a3 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
@@ -68,7 +68,6 @@
context,
layoutInflater,
resources,
- featureFlags.isEnabled(Flags.STEP_CLOCK_ANIMATION),
MigrateClocksToBlueprint.isEnabled(),
com.android.systemui.Flags.clockReactiveVariants()
),
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
index bebfd85..cd19aaac 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
@@ -116,7 +116,7 @@
fun logUpdateLockScreenUserLockedMsg(
userId: Int,
- userUnlocked: Boolean,
+ userStorageUnlocked: Boolean,
encryptedOrLockdown: Boolean,
) {
buffer.log(
@@ -124,12 +124,12 @@
LogLevel.DEBUG,
{
int1 = userId
- bool1 = userUnlocked
+ bool1 = userStorageUnlocked
bool2 = encryptedOrLockdown
},
{
"updateLockScreenUserLockedMsg userId=$int1 " +
- "userUnlocked:$bool1 encryptedOrLockdown:$bool2"
+ "userStorageUnlocked:$bool1 encryptedOrLockdown:$bool2"
}
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java
index f8b445b..3cf400a 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java
@@ -38,7 +38,6 @@
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IMagnificationConnection;
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
@@ -138,10 +137,7 @@
mWindowMagnifierCallback,
mSysUiState,
mSecureSettings,
- scvhSupplier,
- new SfVsyncFrameCallbackProvider(),
- WindowManagerGlobal::getWindowSession,
- mViewCaptureAwareWindowManager);
+ scvhSupplier);
}
}
@@ -407,7 +403,8 @@
}
}
- boolean isMagnificationSettingsPanelShowing(int displayId) {
+ @MainThread
+ private boolean isMagnificationSettingsPanelShowing(int displayId) {
final MagnificationSettingsController magnificationSettingsController =
mMagnificationSettingsSupplier.get(displayId);
if (magnificationSettingsController != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 0883a06..7d5cf23 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -54,11 +54,8 @@
import android.util.Size;
import android.util.SparseArray;
import android.util.TypedValue;
-import android.view.Choreographer;
import android.view.Display;
import android.view.Gravity;
-import android.view.IWindow;
-import android.view.IWindowSession;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
@@ -80,10 +77,8 @@
import androidx.annotation.UiThread;
import androidx.core.math.MathUtils;
-import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.internal.accessibility.common.MagnificationConstants;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.systemui.Flags;
import com.android.systemui.model.SysUiState;
import com.android.systemui.res.R;
@@ -127,7 +122,6 @@
private final SurfaceControl.Transaction mTransaction;
private final WindowManager mWm;
- private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager;
private float mScale;
private int mSettingsButtonIndex = MagnificationSize.DEFAULT;
@@ -219,11 +213,8 @@
private int mMinWindowSize;
private final WindowMagnificationAnimationController mAnimationController;
- private final Supplier<IWindowSession> mGlobalWindowSessionSupplier;
- private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
private final MagnificationGestureDetector mGestureDetector;
private int mBounceEffectDuration;
- private final Choreographer.FrameCallback mMirrorViewGeometryVsyncCallback;
private Locale mLocale;
private NumberFormat mPercentFormat;
private float mBounceEffectAnimationScale;
@@ -258,18 +249,11 @@
@NonNull WindowMagnifierCallback callback,
SysUiState sysUiState,
SecureSettings secureSettings,
- Supplier<SurfaceControlViewHost> scvhSupplier,
- SfVsyncFrameCallbackProvider sfVsyncFrameProvider,
- Supplier<IWindowSession> globalWindowSessionSupplier,
- ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) {
+ Supplier<SurfaceControlViewHost> scvhSupplier) {
mContext = context;
mHandler = handler;
mAnimationController = animationController;
- mAnimationController.setOnAnimationEndRunnable(() -> {
- if (Flags.createWindowlessWindowMagnifier()) {
- notifySourceBoundsChanged();
- }
- });
+ mAnimationController.setOnAnimationEndRunnable(this::notifySourceBoundsChanged);
mAnimationController.setWindowMagnificationController(this);
mWindowMagnifierCallback = callback;
mSysUiState = sysUiState;
@@ -283,7 +267,6 @@
mWm = context.getSystemService(WindowManager.class);
mWindowBounds = new Rect(mWm.getCurrentWindowMetrics().getBounds());
- mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager;
mResources = mContext.getResources();
mScale = secureSettings.getFloatForUser(
@@ -313,76 +296,31 @@
mGestureDetector =
new MagnificationGestureDetector(mContext, handler, this);
mWindowInsetChangeRunnable = this::onWindowInsetChanged;
- mGlobalWindowSessionSupplier = globalWindowSessionSupplier;
- mSfVsyncFrameProvider = sfVsyncFrameProvider;
// Initialize listeners.
- if (Flags.createWindowlessWindowMagnifier()) {
- mMirrorViewRunnable = new Runnable() {
- final Rect mPreviousBounds = new Rect();
+ mMirrorViewRunnable = new Runnable() {
+ final Rect mPreviousBounds = new Rect();
- @Override
- public void run() {
- if (mMirrorView != null) {
- if (mPreviousBounds.width() != mMirrorViewBounds.width()
- || mPreviousBounds.height() != mMirrorViewBounds.height()) {
- mMirrorView.setSystemGestureExclusionRects(Collections.singletonList(
- new Rect(0, 0, mMirrorViewBounds.width(),
- mMirrorViewBounds.height())));
- mPreviousBounds.set(mMirrorViewBounds);
- }
- updateSystemUIStateIfNeeded();
- mWindowMagnifierCallback.onWindowMagnifierBoundsChanged(
- mDisplayId, mMirrorViewBounds);
- }
- }
- };
-
- mMirrorSurfaceViewLayoutChangeListener =
- (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
- mMirrorView.post(this::applyTapExcludeRegion);
-
- mMirrorViewGeometryVsyncCallback = null;
- } else {
- mMirrorViewRunnable = () -> {
+ @Override
+ public void run() {
if (mMirrorView != null) {
- final Rect oldViewBounds = new Rect(mMirrorViewBounds);
- mMirrorView.getBoundsOnScreen(mMirrorViewBounds);
- if (oldViewBounds.width() != mMirrorViewBounds.width()
- || oldViewBounds.height() != mMirrorViewBounds.height()) {
+ if (mPreviousBounds.width() != mMirrorViewBounds.width()
+ || mPreviousBounds.height() != mMirrorViewBounds.height()) {
mMirrorView.setSystemGestureExclusionRects(Collections.singletonList(
- new Rect(0, 0,
- mMirrorViewBounds.width(), mMirrorViewBounds.height())));
+ new Rect(0, 0, mMirrorViewBounds.width(),
+ mMirrorViewBounds.height())));
+ mPreviousBounds.set(mMirrorViewBounds);
}
updateSystemUIStateIfNeeded();
mWindowMagnifierCallback.onWindowMagnifierBoundsChanged(
mDisplayId, mMirrorViewBounds);
}
- };
+ }
+ };
- mMirrorSurfaceViewLayoutChangeListener =
- (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
- mMirrorView.post(this::applyTapExcludeRegion);
-
- mMirrorViewGeometryVsyncCallback =
- l -> {
- if (isActivated() && mMirrorSurface != null && calculateSourceBounds(
- mMagnificationFrame, mScale)) {
- // The final destination for the magnification surface should be at 0,0
- // since the ViewRootImpl's position will change
- mTmpRect.set(0, 0, mMagnificationFrame.width(),
- mMagnificationFrame.height());
- mTransaction.setGeometry(mMirrorSurface, mSourceBounds, mTmpRect,
- Surface.ROTATION_0).apply();
-
- // Notify source bounds change when the magnifier is not animating.
- if (!mAnimationController.isAnimating()) {
- mWindowMagnifierCallback.onSourceBoundsChanged(mDisplayId,
- mSourceBounds);
- }
- }
- };
- }
+ mMirrorSurfaceViewLayoutChangeListener =
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+ mMirrorView.post(this::applyTouchableRegion);
mMirrorViewLayoutChangeListener =
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
@@ -463,7 +401,7 @@
if (isActivated()) {
updateDimensions();
- applyTapExcludeRegion();
+ applyTouchableRegion();
}
if (!enable) {
@@ -513,9 +451,6 @@
if (mMirrorView != null) {
mHandler.removeCallbacks(mMirrorViewRunnable);
mMirrorView.removeOnLayoutChangeListener(mMirrorViewLayoutChangeListener);
- if (!Flags.createWindowlessWindowMagnifier()) {
- mViewCaptureAwareWindowManager.removeView(mMirrorView);
- }
mMirrorView = null;
}
@@ -624,11 +559,7 @@
if (!isActivated()) return;
LayoutParams params = (LayoutParams) mMirrorView.getLayoutParams();
params.accessibilityTitle = getAccessibilityWindowTitle();
- if (Flags.createWindowlessWindowMagnifier()) {
- mSurfaceControlViewHost.relayout(params);
- } else {
- mWm.updateViewLayout(mMirrorView, params);
- }
+ mSurfaceControlViewHost.relayout(params);
}
/**
@@ -678,62 +609,6 @@
return (oldRotation - newRotation + 4) % 4 * 90;
}
- private void createMirrorWindow() {
- if (Flags.createWindowlessWindowMagnifier()) {
- createWindowlessMirrorWindow();
- return;
- }
-
- // The window should be the size the mirrored surface will be but also add room for the
- // border and the drag handle.
- int windowWidth = mMagnificationFrame.width() + 2 * mMirrorSurfaceMargin;
- int windowHeight = mMagnificationFrame.height() + 2 * mMirrorSurfaceMargin;
-
- LayoutParams params = new LayoutParams(
- windowWidth, windowHeight,
- LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
- LayoutParams.FLAG_NOT_TOUCH_MODAL
- | LayoutParams.FLAG_NOT_FOCUSABLE,
- PixelFormat.TRANSPARENT);
- params.gravity = Gravity.TOP | Gravity.LEFT;
- params.x = mMagnificationFrame.left - mMirrorSurfaceMargin;
- params.y = mMagnificationFrame.top - mMirrorSurfaceMargin;
- params.layoutInDisplayCutoutMode = LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- params.receiveInsetsIgnoringZOrder = true;
- params.setTitle(mContext.getString(R.string.magnification_window_title));
- params.accessibilityTitle = getAccessibilityWindowTitle();
-
- mMirrorView = LayoutInflater.from(mContext).inflate(R.layout.window_magnifier_view, null);
- mMirrorSurfaceView = mMirrorView.findViewById(R.id.surface_view);
-
- mMirrorBorderView = mMirrorView.findViewById(R.id.magnification_inner_border);
-
- // Allow taps to go through to the mirror SurfaceView below.
- mMirrorSurfaceView.addOnLayoutChangeListener(mMirrorSurfaceViewLayoutChangeListener);
-
- mMirrorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_FULLSCREEN
- | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
- | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
- mMirrorView.addOnLayoutChangeListener(mMirrorViewLayoutChangeListener);
- mMirrorView.setAccessibilityDelegate(new MirrorWindowA11yDelegate());
- mMirrorView.setOnApplyWindowInsetsListener((v, insets) -> {
- if (!mHandler.hasCallbacks(mWindowInsetChangeRunnable)) {
- mHandler.post(mWindowInsetChangeRunnable);
- }
- return v.onApplyWindowInsets(insets);
- });
-
- mViewCaptureAwareWindowManager.addView(mMirrorView, params);
-
- SurfaceHolder holder = mMirrorSurfaceView.getHolder();
- holder.addCallback(this);
- holder.setFormat(PixelFormat.RGBA_8888);
- addDragTouchListeners();
- }
-
private void createWindowlessMirrorWindow() {
// The window should be the size the mirrored surface will be but also add room for the
// border and the drag handle.
@@ -802,62 +677,6 @@
}
}
- private void applyTapExcludeRegion() {
- if (Flags.createWindowlessWindowMagnifier()) {
- applyTouchableRegion();
- return;
- }
-
- // Sometimes this can get posted and run after deleteWindowMagnification() is called.
- if (mMirrorView == null) return;
-
- final Region tapExcludeRegion = calculateTapExclude();
- final IWindow window = IWindow.Stub.asInterface(mMirrorView.getWindowToken());
- try {
- IWindowSession session = mGlobalWindowSessionSupplier.get();
- session.updateTapExcludeRegion(window, tapExcludeRegion);
- } catch (RemoteException e) {
- }
- }
-
- private Region calculateTapExclude() {
- Region regionInsideDragBorder = new Region(mBorderDragSize, mBorderDragSize,
- mMirrorView.getWidth() - mBorderDragSize,
- mMirrorView.getHeight() - mBorderDragSize);
-
- Region tapExcludeRegion = new Region();
-
- Rect dragArea = new Rect();
- mDragView.getHitRect(dragArea);
-
- Rect topLeftArea = new Rect();
- mTopLeftCornerView.getHitRect(topLeftArea);
-
- Rect topRightArea = new Rect();
- mTopRightCornerView.getHitRect(topRightArea);
-
- Rect bottomLeftArea = new Rect();
- mBottomLeftCornerView.getHitRect(bottomLeftArea);
-
- Rect bottomRightArea = new Rect();
- mBottomRightCornerView.getHitRect(bottomRightArea);
-
- Rect closeArea = new Rect();
- mCloseView.getHitRect(closeArea);
-
- // add tapExcludeRegion for Drag or close
- tapExcludeRegion.op(dragArea, Region.Op.UNION);
- tapExcludeRegion.op(topLeftArea, Region.Op.UNION);
- tapExcludeRegion.op(topRightArea, Region.Op.UNION);
- tapExcludeRegion.op(bottomLeftArea, Region.Op.UNION);
- tapExcludeRegion.op(bottomRightArea, Region.Op.UNION);
- tapExcludeRegion.op(closeArea, Region.Op.UNION);
-
- regionInsideDragBorder.op(tapExcludeRegion, Region.Op.DIFFERENCE);
-
- return regionInsideDragBorder;
- }
-
private void applyTouchableRegion() {
// Sometimes this can get posted and run after deleteWindowMagnification() is called.
if (mMirrorView == null) return;
@@ -1085,13 +904,8 @@
* {@link #mMagnificationFrame}.
*/
private void modifyWindowMagnification(boolean computeWindowSize) {
- if (Flags.createWindowlessWindowMagnifier()) {
- updateMirrorSurfaceGeometry();
- updateWindowlessMirrorViewLayout(computeWindowSize);
- } else {
- mSfVsyncFrameProvider.postFrameCallback(mMirrorViewGeometryVsyncCallback);
- updateMirrorViewLayout(computeWindowSize);
- }
+ updateMirrorSurfaceGeometry();
+ updateWindowlessMirrorViewLayout(computeWindowSize);
}
/**
@@ -1169,58 +983,6 @@
mMirrorViewRunnable.run();
}
- /**
- * Updates the layout params of MirrorView based on the size of {@link #mMagnificationFrame}
- * and translates MirrorView position when the view is moved close to the screen edges;
- *
- * @param computeWindowSize set to {@code true} to compute window size with
- * {@link #mMagnificationFrame}.
- */
- private void updateMirrorViewLayout(boolean computeWindowSize) {
- if (!isActivated()) {
- return;
- }
- final int maxMirrorViewX = mWindowBounds.width() - mMirrorView.getWidth();
- final int maxMirrorViewY = mWindowBounds.height() - mMirrorView.getHeight();
-
- LayoutParams params =
- (LayoutParams) mMirrorView.getLayoutParams();
- params.x = mMagnificationFrame.left - mMirrorSurfaceMargin;
- params.y = mMagnificationFrame.top - mMirrorSurfaceMargin;
- if (computeWindowSize) {
- params.width = mMagnificationFrame.width() + 2 * mMirrorSurfaceMargin;
- params.height = mMagnificationFrame.height() + 2 * mMirrorSurfaceMargin;
- }
-
- // Translates MirrorView position to make MirrorSurfaceView that is inside MirrorView
- // able to move close to the screen edges.
- final float translationX;
- final float translationY;
- if (params.x < 0) {
- translationX = Math.max(params.x, -mOuterBorderSize);
- } else if (params.x > maxMirrorViewX) {
- translationX = Math.min(params.x - maxMirrorViewX, mOuterBorderSize);
- } else {
- translationX = 0;
- }
- if (params.y < 0) {
- translationY = Math.max(params.y, -mOuterBorderSize);
- } else if (params.y > maxMirrorViewY) {
- translationY = Math.min(params.y - maxMirrorViewY, mOuterBorderSize);
- } else {
- translationY = 0;
- }
- mMirrorView.setTranslationX(translationX);
- mMirrorView.setTranslationY(translationY);
- mWm.updateViewLayout(mMirrorView, params);
-
- // If they are not dragging the handle, we can move the drag handle immediately without
- // disruption. But if they are dragging it, we avoid moving until the end of the drag.
- if (!mIsDragging) {
- mMirrorView.post(this::maybeRepositionButton);
- }
- }
-
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v == mDragView
@@ -1474,7 +1236,7 @@
calculateMagnificationFrameBoundary();
updateMagnificationFramePosition((int) offsetX, (int) offsetY);
if (!isActivated()) {
- createMirrorWindow();
+ createWindowlessMirrorWindow();
showControls();
applyResourcesValues();
} else {
@@ -1766,7 +1528,7 @@
if (newGravity != layoutParams.gravity) {
layoutParams.gravity = newGravity;
mDragView.setLayoutParams(layoutParams);
- mDragView.post(this::applyTapExcludeRegion);
+ mDragView.post(this::applyTouchableRegion);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
index b8ff3bb..178e111 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
@@ -24,6 +24,7 @@
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
@@ -42,7 +43,7 @@
@Application private val applicationScope: CoroutineScope,
@Application private val context: Context,
repository: FingerprintPropertyRepository,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
displayStateInteractor: DisplayStateInteractor,
udfpsOverlayInteractor: UdfpsOverlayInteractor,
) {
@@ -73,15 +74,12 @@
* - device's natural orientation
*/
private val unscaledSensorLocation: Flow<SensorLocationInternal> =
- combine(
- repository.sensorLocations,
- uniqueDisplayId,
- ) { locations, displayId ->
+ combine(repository.sensorLocations, uniqueDisplayId) { locations, displayId ->
// Devices without multiple physical displays do not use the display id as the key;
// instead, the key is an empty string.
locations.getOrDefault(
displayId,
- locations.getOrDefault("", SensorLocationInternal.DEFAULT)
+ locations.getOrDefault("", SensorLocationInternal.DEFAULT),
)
}
@@ -92,16 +90,15 @@
* - device's natural orientation
*/
val sensorLocation: Flow<SensorLocation> =
- combine(
+ combine(unscaledSensorLocation, configurationInteractor.scaleForResolution) {
unscaledSensorLocation,
- configurationInteractor.scaleForResolution,
- ) { unscaledSensorLocation, scale ->
+ scale ->
val sensorLocation =
SensorLocation(
naturalCenterX = unscaledSensorLocation.sensorLocationX,
naturalCenterY = unscaledSensorLocation.sensorLocationY,
naturalRadius = unscaledSensorLocation.sensorRadius,
- scale = scale
+ scale = scale,
)
sensorLocation
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index e178c09..7039d5e 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -17,6 +17,7 @@
package com.android.systemui.bouncer.domain.interactor
import android.app.StatusBarManager.SESSION_KEYGUARD
+import com.android.app.tracing.coroutines.asyncTraced as async
import com.android.compose.animation.scene.SceneKey
import com.android.internal.logging.UiEventLogger
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
@@ -39,9 +40,9 @@
import com.android.systemui.scene.domain.interactor.SceneBackInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import com.android.app.tracing.coroutines.asyncTraced as async
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
@@ -65,7 +66,7 @@
private val uiEventLogger: UiEventLogger,
private val sessionTracker: SessionTracker,
sceneBackInteractor: SceneBackInteractor,
- private val configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
) {
private val _onIncorrectBouncerInput = MutableSharedFlow<Unit>()
val onIncorrectBouncerInput: SharedFlow<Unit> = _onIncorrectBouncerInput
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt
index 4fe6fc6..f50a2ab 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModel.kt
@@ -18,7 +18,6 @@
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
@@ -33,16 +32,14 @@
*/
class BouncerUserActionsViewModel
@AssistedInject
-constructor(
- private val bouncerInteractor: BouncerInteractor,
-) : UserActionsViewModel() {
+constructor(private val bouncerInteractor: BouncerInteractor) : UserActionsViewModel() {
override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
bouncerInteractor.dismissDestination
.map { prevScene ->
mapOf(
Back to UserActionResult(prevScene),
- Swipe(SwipeDirection.Down) to UserActionResult(prevScene),
+ Swipe.Down to UserActionResult(prevScene),
)
}
.collect { actions -> setActions(actions) }
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt b/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt
index 06d3917..6c78b8b 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt
@@ -19,6 +19,7 @@
import android.annotation.SuppressLint
import android.hardware.display.BrightnessInfo
import android.hardware.display.DisplayManager
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.brightness.shared.model.BrightnessLog
import com.android.systemui.brightness.shared.model.LinearBrightness
import com.android.systemui.brightness.shared.model.formatBrightness
@@ -46,7 +47,6 @@
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.withContext
/**
@@ -64,6 +64,9 @@
/** Current maximum value for the brightness */
val maxLinearBrightness: Flow<LinearBrightness>
+ /** Whether the current brightness value is overridden by the application window */
+ val isBrightnessOverriddenByWindow: StateFlow<Boolean>
+
/** Gets the current values for min and max brightness */
suspend fun getMinMaxLinearBrightness(): Pair<LinearBrightness, LinearBrightness>
@@ -90,10 +93,7 @@
@Background private val backgroundContext: CoroutineContext,
) : ScreenBrightnessRepository {
- private val apiQueue =
- Channel<SetBrightnessMethod>(
- capacity = UNLIMITED,
- )
+ private val apiQueue = Channel<SetBrightnessMethod>(capacity = UNLIMITED)
init {
applicationScope.launch(context = backgroundContext) {
@@ -132,7 +132,8 @@
displayManager.registerDisplayListener(
listener,
null,
- DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS,
+ /* eventFlags */ 0,
+ DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS,
)
awaitClose { displayManager.unregisterDisplayListener(listener) }
@@ -180,6 +181,11 @@
.logDiffForTable(tableBuffer, TABLE_PREFIX_LINEAR, TABLE_COLUMN_BRIGHTNESS, null)
.stateIn(applicationScope, SharingStarted.WhileSubscribed(), LinearBrightness(0f))
+ override val isBrightnessOverriddenByWindow = brightnessInfo
+ .filterNotNull()
+ .map { it.isBrightnessOverrideByWindow }
+ .stateIn(applicationScope, SharingStarted.WhileSubscribed(), false)
+
override fun setTemporaryBrightness(value: LinearBrightness) {
apiQueue.trySend(SetBrightnessMethod.Temporary(value))
}
@@ -190,8 +196,10 @@
private sealed interface SetBrightnessMethod {
val value: LinearBrightness
+
@JvmInline
value class Temporary(override val value: LinearBrightness) : SetBrightnessMethod
+
@JvmInline
value class Permanent(override val value: LinearBrightness) : SetBrightnessMethod
}
@@ -201,7 +209,7 @@
LOG_BUFFER_BRIGHTNESS_CHANGE_TAG,
if (permanent) LogLevel.DEBUG else LogLevel.VERBOSE,
{ str1 = value.formatBrightness() },
- { "Change requested: $str1" }
+ { "Change requested: $str1" },
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractor.kt b/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractor.kt
index 5647f521..b794c5c 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractor.kt
@@ -25,12 +25,12 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.log.table.TableLogBuffer
-import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
+import javax.inject.Inject
/**
* Converts between [GammaBrightness] and [LinearBrightness].
@@ -68,6 +68,8 @@
.stateIn(applicationScope, SharingStarted.WhileSubscribed(), GammaBrightness(0))
}
+ val brightnessOverriddenByWindow = screenBrightnessRepository.isBrightnessOverriddenByWindow
+
/** Sets the brightness temporarily, while the user is changing it. */
suspend fun setTemporaryBrightness(gammaBrightness: GammaBrightness) {
screenBrightnessRepository.setTemporaryBrightness(
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
index 02161d2..917a4ff 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
@@ -19,6 +19,7 @@
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.interaction.DragInteraction
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
@@ -27,8 +28,10 @@
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
@@ -38,6 +41,7 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
@@ -62,6 +66,7 @@
@Composable
private fun BrightnessSlider(
+ viewModel: BrightnessSliderViewModel,
gammaValue: Int,
valueRange: IntRange,
label: Text.Resource,
@@ -97,21 +102,31 @@
null
}
+ val overriddenByAppState by if (Flags.showToastWhenAppControlBrightness()) {
+ viewModel.brightnessOverriddenByWindow.collectAsStateWithLifecycle()
+ } else {
+ mutableStateOf(false)
+ }
+
PlatformSlider(
value = animatedValue,
valueRange = floatValueRange,
enabled = !isRestricted,
onValueChange = {
if (!isRestricted) {
- hapticsViewModel?.onValueChange(it)
- value = it.toInt()
- onDrag(value)
+ if (!overriddenByAppState) {
+ hapticsViewModel?.onValueChange(it)
+ value = it.toInt()
+ onDrag(value)
+ }
}
},
onValueChangeFinished = {
if (!isRestricted) {
- hapticsViewModel?.onValueChangeEnded()
- onStop(value)
+ if (!overriddenByAppState) {
+ hapticsViewModel?.onValueChangeEnded()
+ onStop(value)
+ }
}
},
modifier =
@@ -136,6 +151,21 @@
},
interactionSource = interactionSource,
)
+ // Showing the warning toast if the current running app window has controlled the
+ // brightness value.
+ if (Flags.showToastWhenAppControlBrightness()) {
+ val context = LocalContext.current
+ LaunchedEffect(interactionSource) {
+ interactionSource.interactions.collect { interaction ->
+ if (interaction is DragInteraction.Start && overriddenByAppState) {
+ viewModel.showToast(
+ context,
+ R.string.quick_settings_brightness_unable_adjust_msg
+ )
+ }
+ }
+ }
+ }
}
private val sliderBackgroundFrameSize = 8.dp
@@ -167,6 +197,7 @@
Box(modifier = modifier.fillMaxWidth().sysuiResTag("brightness_slider")) {
BrightnessSlider(
+ viewModel = viewModel,
gammaValue = gamma,
valueRange = viewModel.minBrightness.value..viewModel.maxBrightness.value,
label = viewModel.label,
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
index a61ce8f..1630ee5 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
@@ -17,7 +17,8 @@
package com.android.systemui.brightness.ui.viewmodel
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.setValue
+import android.content.Context
+import androidx.annotation.StringRes
import com.android.systemui.brightness.domain.interactor.BrightnessPolicyEnforcementInteractor
import com.android.systemui.brightness.domain.interactor.ScreenBrightnessInteractor
import com.android.systemui.brightness.shared.model.GammaBrightness
@@ -29,6 +30,7 @@
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.res.R
import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor
+import com.android.systemui.settings.brightness.ui.BrightnessWarningToast
import com.android.systemui.utils.PolicyRestriction
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -51,6 +53,7 @@
val hapticsViewModelFactory: SliderHapticsViewModel.Factory,
private val brightnessMirrorShowingInteractor: BrightnessMirrorShowingInteractor,
@Assisted private val supportsMirroring: Boolean,
+ private val brightnessWarningToast: BrightnessWarningToast,
) : ExclusiveActivatable() {
private val hydrator = Hydrator("BrightnessSliderViewModel.hydrator")
@@ -75,6 +78,15 @@
brightnessPolicyEnforcementInteractor.startAdminSupportDetailsDialog(restriction)
}
+ val brightnessOverriddenByWindow = screenBrightnessInteractor.brightnessOverriddenByWindow
+
+ fun showToast(viewContext: Context, @StringRes resId: Int) {
+ if (brightnessWarningToast.isToastActive()) {
+ return
+ }
+ brightnessWarningToast.show(viewContext, resId)
+ }
+
/**
* As a brightness slider is dragged, the corresponding events should be sent using this method.
*/
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardIndicationCallback.kt
similarity index 67%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardIndicationCallback.kt
index e21bf8f..ddd6bc9 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardIndicationCallback.kt
@@ -14,6 +14,11 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package com.android.systemui.clipboardoverlay
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+/** Interface for listening to indication text changed from [ClipboardIndicationProvider]. */
+interface ClipboardIndicationCallback {
+
+ /** Notifies the indication text changed. */
+ fun onIndicationTextChanged(text: CharSequence)
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardIndicationProvider.kt
similarity index 62%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardIndicationProvider.kt
index e21bf8f..be32723 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardIndicationProvider.kt
@@ -14,6 +14,15 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package com.android.systemui.clipboardoverlay
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+/** Interface to provide the clipboard indication to be shown under the overlay. */
+interface ClipboardIndicationProvider {
+
+ /**
+ * Gets the indication text async.
+ *
+ * @param callback callback for getting the indication text.
+ */
+ fun getIndicationText(callback: ClipboardIndicationCallback)
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardIndicationProviderImpl.kt
similarity index 65%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardIndicationProviderImpl.kt
index e21bf8f..da94d5b 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardIndicationProviderImpl.kt
@@ -14,6 +14,13 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package com.android.systemui.clipboardoverlay
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+@SysUISingleton
+open class ClipboardIndicationProviderImpl @Inject constructor() : ClipboardIndicationProvider {
+
+ override fun getIndicationText(callback: ClipboardIndicationCallback) {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index 65c01ed..ac74784 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -21,6 +21,7 @@
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_SHOW_ACTIONS;
import static com.android.systemui.Flags.clipboardImageTimeout;
import static com.android.systemui.Flags.clipboardSharedTransitions;
+import static com.android.systemui.Flags.showClipboardIndication;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_SHOWN;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_TAPPED;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_DISMISSED_OTHER;
@@ -99,6 +100,7 @@
private final ClipboardTransitionExecutor mTransitionExecutor;
private final ClipboardOverlayView mView;
+ private final ClipboardIndicationProvider mClipboardIndicationProvider;
private Runnable mOnSessionCompleteListener;
private Runnable mOnRemoteCopyTapped;
@@ -173,6 +175,13 @@
}
};
+ private ClipboardIndicationCallback mIndicationCallback = new ClipboardIndicationCallback() {
+ @Override
+ public void onIndicationTextChanged(@NonNull CharSequence text) {
+ mView.setIndicationText(text);
+ }
+ };
+
@Inject
public ClipboardOverlayController(@OverlayWindowContext Context context,
ClipboardOverlayView clipboardOverlayView,
@@ -185,11 +194,13 @@
@Background Executor bgExecutor,
ClipboardImageLoader clipboardImageLoader,
ClipboardTransitionExecutor transitionExecutor,
+ ClipboardIndicationProvider clipboardIndicationProvider,
UiEventLogger uiEventLogger) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
mClipboardImageLoader = clipboardImageLoader;
mTransitionExecutor = transitionExecutor;
+ mClipboardIndicationProvider = clipboardIndicationProvider;
mClipboardLogger = new ClipboardLogger(uiEventLogger);
@@ -288,6 +299,9 @@
boolean shouldAnimate = !model.dataMatches(mClipboardModel) || wasExiting;
mClipboardModel = model;
mClipboardLogger.setClipSource(mClipboardModel.getSource());
+ if (showClipboardIndication()) {
+ mClipboardIndicationProvider.getIndicationText(mIndicationCallback);
+ }
if (clipboardImageTimeout()) {
if (shouldAnimate) {
reset();
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
index 1762d82..7e4d762 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
@@ -18,6 +18,8 @@
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static com.android.systemui.Flags.showClipboardIndication;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -53,6 +55,7 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.view.ViewCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
@@ -103,6 +106,8 @@
private View mShareChip;
private View mRemoteCopyChip;
private View mActionContainerBackground;
+ private View mIndicationContainer;
+ private TextView mIndicationText;
private View mDismissButton;
private LinearLayout mActionContainer;
private ClipboardOverlayCallbacks mClipboardCallbacks;
@@ -136,6 +141,8 @@
mShareChip = requireViewById(R.id.share_chip);
mRemoteCopyChip = requireViewById(R.id.remote_copy_chip);
mDismissButton = requireViewById(R.id.dismiss_button);
+ mIndicationContainer = requireViewById(R.id.indication_container);
+ mIndicationText = mIndicationContainer.findViewById(R.id.indication_text);
bindDefaultActionChips();
@@ -208,6 +215,14 @@
}
}
+ void setIndicationText(CharSequence text) {
+ mIndicationText.setText(text);
+
+ // Set the visibility of clipboard indication based on the text is empty or not.
+ int visibility = text.isEmpty() ? View.GONE : View.VISIBLE;
+ mIndicationContainer.setVisibility(visibility);
+ }
+
void setMinimized(boolean minimized) {
if (minimized) {
mMinimizedPreview.setVisibility(View.VISIBLE);
@@ -221,6 +236,18 @@
mPreviewBorder.setVisibility(View.VISIBLE);
mActionContainer.setVisibility(View.VISIBLE);
}
+
+ if (showClipboardIndication()) {
+ // Adjust the margin of clipboard indication based on the minimized state.
+ int marginStart = minimized ? getResources().getDimensionPixelSize(
+ R.dimen.overlay_action_container_margin_horizontal)
+ : getResources().getDimensionPixelSize(
+ R.dimen.overlay_action_container_minimum_edge_spacing);
+ ConstraintLayout.LayoutParams params =
+ (ConstraintLayout.LayoutParams) mIndicationContainer.getLayoutParams();
+ params.setMarginStart(marginStart);
+ mIndicationContainer.setLayoutParams(params);
+ }
}
void setInsets(WindowInsets insets, int orientation) {
@@ -313,6 +340,7 @@
setTranslationX(0);
setAlpha(0);
mActionContainerBackground.setVisibility(View.GONE);
+ mIndicationContainer.setVisibility(View.GONE);
mDismissButton.setVisibility(View.GONE);
mShareChip.setVisibility(View.GONE);
mRemoteCopyChip.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlaySuppressionModule.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayOverrideModule.kt
similarity index 69%
rename from packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlaySuppressionModule.kt
rename to packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayOverrideModule.kt
index 527819c..c81f0d9 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlaySuppressionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayOverrideModule.kt
@@ -15,18 +15,26 @@
*/
package com.android.systemui.clipboardoverlay.dagger
+import com.android.systemui.clipboardoverlay.ClipboardIndicationProvider
+import com.android.systemui.clipboardoverlay.ClipboardIndicationProviderImpl
import com.android.systemui.clipboardoverlay.ClipboardOverlaySuppressionController
import com.android.systemui.clipboardoverlay.ClipboardOverlaySuppressionControllerImpl
import dagger.Binds
import dagger.Module
-/** Dagger Module for code in the clipboard overlay package. */
+/** Dagger Module to provide default implementations which could be overridden. */
@Module
-interface ClipboardOverlaySuppressionModule {
+interface ClipboardOverlayOverrideModule {
/** Provides implementation for [ClipboardOverlaySuppressionController]. */
@Binds
fun provideClipboardOverlaySuppressionController(
clipboardOverlaySuppressionControllerImpl: ClipboardOverlaySuppressionControllerImpl
): ClipboardOverlaySuppressionController
+
+ /** Provides implementation for [ClipboardIndicationProvider]. */
+ @Binds
+ fun provideClipboardIndicationProvider(
+ clipboardIndicationProviderImpl: ClipboardIndicationProviderImpl
+ ): ClipboardIndicationProvider
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
index ca4bbc0..00c6209 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
@@ -33,6 +33,7 @@
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.compose.theme.PlatformTheme
import com.android.internal.logging.UiEventLogger
import com.android.systemui.Flags.communalEditWidgetsActivityFinishFix
@@ -44,6 +45,7 @@
import com.android.systemui.communal.ui.view.layout.sections.CommunalAppWidgetSection
import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
import com.android.systemui.communal.util.WidgetPickerIntentUtils.getWidgetExtraFromIntent
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
@@ -52,13 +54,13 @@
import com.android.systemui.settings.UserTracker
import javax.inject.Inject
import kotlinx.coroutines.flow.first
-import com.android.app.tracing.coroutines.launchTraced as launch
/** An Activity for editing the widgets that appear in hub mode. */
class EditWidgetsActivity
@Inject
constructor(
private val communalViewModel: CommunalEditModeViewModel,
+ private val keyguardInteractor: KeyguardInteractor,
private var windowManagerService: IWindowManager? = null,
private val uiEventLogger: UiEventLogger,
private val widgetConfiguratorFactory: WidgetConfigurationController.Factory,
@@ -223,6 +225,9 @@
communalViewModel.currentScene.first { it == CommunalScenes.Blank }
}
+ // Wait for dream to exit, if we were previously dreaming.
+ keyguardInteractor.isDreaming.first { !it }
+
communalViewModel.setEditModeState(EditModeState.SHOWING)
// Inform the ActivityController that we are now fully visible.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java b/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
index d727a70..769d7fa 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
@@ -16,6 +16,7 @@
package com.android.systemui.dagger;
+
import com.android.systemui.classifier.FalsingManagerProxy;
import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.globalactions.GlobalActionsImpl;
@@ -26,18 +27,20 @@
import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore;
+import com.android.systemui.statusbar.data.repository.SysuiDarkIconDispatcherStore;
import com.android.systemui.statusbar.phone.ActivityStarterImpl;
-import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher;
import com.android.systemui.volume.VolumeDialogControllerImpl;
import dagger.Binds;
import dagger.Module;
+import dagger.Provides;
/**
* Module for binding Plugin implementations.
*
- * TODO(b/166258224): Many of these should be moved closer to their implementations.
+ * <p>TODO(b/166258224): Many of these should be moved closer to their implementations.
*/
@Module
public abstract class PluginModule {
@@ -47,12 +50,18 @@
abstract ActivityStarter provideActivityStarter(ActivityStarterImpl activityStarterImpl);
/** */
- @Binds
- abstract DarkIconDispatcher provideDarkIconDispatcher(DarkIconDispatcherImpl controllerImpl);
+ @Provides
+ @SysUISingleton
+ static DarkIconDispatcher provideDarkIconDispatcher(DarkIconDispatcherStore store) {
+ return store.getDefaultDisplay();
+ }
- @Binds
- abstract SysuiDarkIconDispatcher provideSysuiDarkIconDispatcher(
- DarkIconDispatcherImpl controllerImpl);
+ @Provides
+ @SysUISingleton
+ static SysuiDarkIconDispatcher provideSysuiDarkIconDispatcher(
+ SysuiDarkIconDispatcherStore store) {
+ return store.getDefaultDisplay();
+ }
/** */
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index 609b733..2e323d4 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -29,7 +29,7 @@
import com.android.systemui.accessibility.SystemActionsModule;
import com.android.systemui.accessibility.data.repository.AccessibilityRepositoryModule;
import com.android.systemui.battery.BatterySaverModule;
-import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlaySuppressionModule;
+import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayOverrideModule;
import com.android.systemui.display.ui.viewmodel.ConnectingDisplayViewModel;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
@@ -125,7 +125,7 @@
AospPolicyModule.class,
BatterySaverModule.class,
CentralSurfacesModule.class,
- ClipboardOverlaySuppressionModule.class,
+ ClipboardOverlayOverrideModule.class,
CollapsedStatusBarFragmentStartableModule.class,
ConnectingDisplayViewModel.StartableModule.class,
DefaultBlueprintModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
index 034cb31..1fa829a 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
@@ -264,7 +264,8 @@
displayManager.registerDisplayListener(
callback,
backgroundHandler,
- DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
+ /* eventFlags */ 0,
+ DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
)
awaitClose { displayManager.unregisterDisplayListener(callback) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsClassicDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsClassicDebug.java
index 303f916..911331b 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsClassicDebug.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsClassicDebug.java
@@ -42,7 +42,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.settings.UserContextProvider;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.util.settings.GlobalSettings;
import java.io.PrintWriter;
@@ -51,6 +51,7 @@
import java.util.Objects;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
import javax.inject.Inject;
@@ -74,7 +75,6 @@
static final String TAG = "SysUIFlags";
private final FlagManager mFlagManager;
- private final Context mContext;
private final GlobalSettings mGlobalSettings;
private final Resources mResources;
private final SystemPropertiesHelper mSystemProperties;
@@ -84,6 +84,8 @@
private final Map<String, String> mStringFlagCache = new ConcurrentHashMap<>();
private final Map<String, Integer> mIntFlagCache = new ConcurrentHashMap<>();
private final Restarter mRestarter;
+ private final UserTracker mUserTracker;
+ private final Executor mMainExecutor;
private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
new ServerFlagReader.ChangeListener() {
@@ -118,6 +120,18 @@
}
};
+ private final UserTracker.Callback mUserChangedCallback =
+ new UserTracker.Callback() {
+ @Override
+ public void onUserChanged(int newUser, @NonNull Context userContext) {
+ mContext.unregisterReceiver(mReceiver);
+ mContext = userContext;
+ registerReceiver();
+ }
+ };
+
+ private Context mContext;
+
@Inject
public FeatureFlagsClassicDebug(
FlagManager flagManager,
@@ -128,10 +142,11 @@
ServerFlagReader serverFlagReader,
@Named(ALL_FLAGS) Map<String, Flag<?>> allFlags,
Restarter restarter,
- UserContextProvider userContextProvider) {
+ UserTracker userTracker,
+ @Main Executor executor) {
mFlagManager = flagManager;
if (classicFlagsMultiUser()) {
- mContext = userContextProvider.createCurrentUserContext(context);
+ mContext = userTracker.createCurrentUserContext(context);
} else {
mContext = context;
}
@@ -141,19 +156,28 @@
mServerFlagReader = serverFlagReader;
mAllFlags = allFlags;
mRestarter = restarter;
+ mUserTracker = userTracker;
+ mMainExecutor = executor;
}
/** Call after construction to setup listeners. */
void init() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_SET_FLAG);
- filter.addAction(ACTION_GET_FLAGS);
mFlagManager.setOnSettingsChangedAction(
suppressRestart -> restartSystemUI(suppressRestart, "Settings changed"));
mFlagManager.setClearCacheAction(this::removeFromCache);
+ registerReceiver();
+ if (classicFlagsMultiUser()) {
+ mUserTracker.addCallback(mUserChangedCallback, mMainExecutor);
+ }
+ mServerFlagReader.listenForChanges(mAllFlags.values(), mOnPropertiesChanged);
+ }
+
+ void registerReceiver() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_SET_FLAG);
+ filter.addAction(ACTION_GET_FLAGS);
mContext.registerReceiver(mReceiver, filter, null, null,
Context.RECEIVER_EXPORTED_UNAUDITED);
- mServerFlagReader.listenForChanges(mAllFlags.values(), mOnPropertiesChanged);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index b431636..fe9c9cb 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -15,7 +15,6 @@
*/
package com.android.systemui.flags
-import android.provider.DeviceConfig
import com.android.internal.annotations.Keep
import com.android.systemui.flags.FlagsFactory.releasedFlag
import com.android.systemui.flags.FlagsFactory.resourceBooleanFlag
@@ -78,12 +77,6 @@
resourceBooleanFlag(R.bool.config_enableLockScreenCustomClocks, "lockscreen_custom_clocks")
/**
- * Whether the clock on a wide lock screen should use the new "stepping" animation for moving
- * the digits when the clock moves.
- */
- @JvmField val STEP_CLOCK_ANIMATION = releasedFlag("step_clock_animation")
-
- /**
* Migration from the legacy isDozing/dozeAmount paths to the new KeyguardTransitionRepository
* will occur in stages. This is one stage of many to come.
*/
@@ -220,10 +213,6 @@
// TODO(b/293380347): Tracking Bug
@JvmField val COLOR_FIDELITY = unreleasedFlag("color_fidelity")
- // 900 - media
- // TODO(b/254512697): Tracking Bug
- val MEDIA_TAP_TO_TRANSFER = releasedFlag("media_tap_to_transfer")
-
// TODO(b/254512654): Tracking Bug
@JvmField val DREAM_MEDIA_COMPLICATION = unreleasedFlag("dream_media_complication")
@@ -255,15 +244,6 @@
val WM_ENABLE_SHELL_TRANSITIONS =
sysPropBooleanFlag("persist.wm.debug.shell_transit", default = true)
- // TODO(b/254513207): Tracking Bug to delete
- @Keep
- @JvmField
- val WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES =
- releasedFlag(
- name = "enable_screen_record_enterprise_policies",
- namespace = DeviceConfig.NAMESPACE_WINDOW_MANAGER,
- )
-
// TODO(b/293252410) : Tracking Bug
@JvmField val LOCKSCREEN_ENABLE_LANDSCAPE = unreleasedFlag("lockscreen.enable_landscape")
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index 162047b..91b44e7 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -36,7 +36,6 @@
import android.app.IActivityManager;
import android.app.StatusBarManager;
import android.app.WallpaperManager;
-import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -138,6 +137,7 @@
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
+import com.android.systemui.user.domain.interactor.UserLogoutInteractor;
import com.android.systemui.util.EmergencyDialerConstants;
import com.android.systemui.util.RingerModeTracker;
import com.android.systemui.util.settings.GlobalSettings;
@@ -197,7 +197,6 @@
private final Context mContext;
private final GlobalActionsManager mWindowManagerFuncs;
private final AudioManager mAudioManager;
- private final DevicePolicyManager mDevicePolicyManager;
private final LockPatternUtils mLockPatternUtils;
private final SelectedUserInteractor mSelectedUserInteractor;
private final TelephonyListenerManager mTelephonyListenerManager;
@@ -260,6 +259,7 @@
private final ShadeController mShadeController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final DialogTransitionAnimator mDialogTransitionAnimator;
+ private final UserLogoutInteractor mLogoutInteractor;
private final GlobalActionsInteractor mInteractor;
@VisibleForTesting
@@ -344,7 +344,6 @@
Context context,
GlobalActionsManager windowManagerFuncs,
AudioManager audioManager,
- DevicePolicyManager devicePolicyManager,
LockPatternUtils lockPatternUtils,
BroadcastDispatcher broadcastDispatcher,
TelephonyListenerManager telephonyListenerManager,
@@ -376,11 +375,11 @@
KeyguardUpdateMonitor keyguardUpdateMonitor,
DialogTransitionAnimator dialogTransitionAnimator,
SelectedUserInteractor selectedUserInteractor,
+ UserLogoutInteractor logoutInteractor,
GlobalActionsInteractor interactor) {
mContext = context;
mWindowManagerFuncs = windowManagerFuncs;
mAudioManager = audioManager;
- mDevicePolicyManager = devicePolicyManager;
mLockPatternUtils = lockPatternUtils;
mTelephonyListenerManager = telephonyListenerManager;
mKeyguardStateController = keyguardStateController;
@@ -412,6 +411,7 @@
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mDialogTransitionAnimator = dialogTransitionAnimator;
mSelectedUserInteractor = selectedUserInteractor;
+ mLogoutInteractor = logoutInteractor;
mInteractor = interactor;
// receive broadcasts
@@ -639,12 +639,7 @@
} else if (GLOBAL_ACTION_KEY_SCREENSHOT.equals(actionKey)) {
addIfShouldShowAction(tempActions, new ScreenshotAction());
} else if (GLOBAL_ACTION_KEY_LOGOUT.equals(actionKey)) {
- // TODO(b/206032495): should call mDevicePolicyManager.getLogoutUserId() instead of
- // hardcode it to USER_SYSTEM so it properly supports headless system user mode
- // (and then call mDevicePolicyManager.clearLogoutUser() after switched)
- if (mDevicePolicyManager.isLogoutEnabled()
- && currentUser.get() != null
- && currentUser.get().id != UserHandle.USER_SYSTEM) {
+ if (mLogoutInteractor.isLogoutEnabled().getValue()) {
addIfShouldShowAction(tempActions, new LogoutAction());
}
} else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) {
@@ -1134,7 +1129,7 @@
// Add a little delay before executing, to give the dialog a chance to go away before
// switching user
mHandler.postDelayed(() -> {
- mDevicePolicyManager.logoutUser();
+ mLogoutInteractor.logOut();
}, mDialogPressDelay);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt
index f0b2b86..38fc2a8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt
@@ -19,17 +19,18 @@
import android.content.Context
import android.view.Surface
import android.view.WindowManager
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.settingslib.Utils
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyboard.docking.domain.interactor.KeyboardDockingIndicationInteractor
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.surfaceeffects.glowboxeffect.GlowBoxConfig
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
-import com.android.app.tracing.coroutines.launchTraced as launch
@SysUISingleton
class KeyboardDockingIndicationViewModel
@@ -38,7 +39,7 @@
private val windowManager: WindowManager,
private val context: Context,
keyboardDockingIndicationInteractor: KeyboardDockingIndicationInteractor,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
@Background private val backgroundScope: CoroutineScope,
) {
@@ -128,7 +129,7 @@
blurAmount = BLUR_AMOUNT,
duration = DURATION,
easeInDuration = EASE_DURATION,
- easeOutDuration = EASE_DURATION
+ easeOutDuration = EASE_DURATION,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
index 05ff0cc..0201f40 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyboard.shortcut.data.source
import android.content.res.Resources
+import android.view.KeyEvent.KEYCODE_D
import android.view.KeyEvent.KEYCODE_DPAD_LEFT
import android.view.KeyEvent.KEYCODE_DPAD_RIGHT
import android.view.KeyEvent.KEYCODE_DPAD_UP
@@ -29,6 +30,7 @@
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
import com.android.systemui.res.R
+import com.android.window.flags.Flags.enableMoveToNextDisplayShortcut
import javax.inject.Inject
class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) :
@@ -38,42 +40,62 @@
listOf(
KeyboardShortcutGroup(
resources.getString(R.string.shortcutHelper_category_recent_apps),
- recentsShortcuts()
+ recentsShortcuts(),
),
KeyboardShortcutGroup(
resources.getString(R.string.shortcutHelper_category_split_screen),
- splitScreenShortcuts()
- )
+ splitScreenShortcuts(),
+ ),
)
- private fun splitScreenShortcuts() =
- listOf(
- // Enter Split screen with current app to RHS:
- // - Meta + Ctrl + Right arrow
+ private fun splitScreenShortcuts() = buildList {
+ // Enter Split screen with current app to RHS:
+ // - Meta + Ctrl + Right arrow
+ add(
shortcutInfo(resources.getString(R.string.system_multitasking_rhs)) {
command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_RIGHT)
- },
- // Enter Split screen with current app to LHS:
- // - Meta + Ctrl + Left arrow
+ }
+ )
+ // Enter Split screen with current app to LHS:
+ // - Meta + Ctrl + Left arrow
+ add(
shortcutInfo(resources.getString(R.string.system_multitasking_lhs)) {
command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_LEFT)
- },
- // Switch from Split screen to full screen:
- // - Meta + Ctrl + Up arrow
+ }
+ )
+ // Switch from Split screen to full screen:
+ // - Meta + Ctrl + Up arrow
+ add(
shortcutInfo(resources.getString(R.string.system_multitasking_full_screen)) {
command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_UP)
- },
- // Change split screen focus to RHS:
- // - Meta + Alt + Right arrow
+ }
+ )
+ // Change split screen focus to RHS:
+ // - Meta + Alt + Right arrow
+ add(
shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_RIGHT)
- },
- // Change split screen focus to LHS:
- // - Meta + Alt + Left arrow
+ }
+ )
+ // Change split screen focus to LHS:
+ // - Meta + Alt + Left arrow
+ add(
shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_lhs)) {
command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_LEFT)
- },
+ }
)
+ if (enableMoveToNextDisplayShortcut()) {
+ // Move a window to the next display:
+ // - Meta + Ctrl + D
+ add(
+ shortcutInfo(
+ resources.getString(R.string.system_multitasking_move_to_next_display)
+ ) {
+ command(META_META_ON or META_CTRL_ON, KEYCODE_D)
+ }
+ )
+ }
+ }
private fun recentsShortcuts() =
listOf(
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
new file mode 100644
index 0000000..85d2214
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyboard.shortcut.domain.interactor
+
+import android.view.KeyEvent.META_META_ON
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
+import javax.inject.Inject
+
+class ShortcutCustomizationInteractor @Inject constructor() {
+ fun getDefaultCustomShortcutModifierKey(): ShortcutKey.Icon.ResIdIcon {
+ return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.keyIcons[META_META_ON]!!)
+ }
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutInfo.kt
similarity index 76%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutInfo.kt
index e21bf8f..e4ccc2c 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutInfo.kt
@@ -14,6 +14,10 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package com.android.systemui.keyboard.shortcut.shared.model
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+data class ShortcutInfo(
+ val label: String,
+ val categoryType: ShortcutCategoryType,
+ val subCategoryLabel: String,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogDelegate.kt
new file mode 100644
index 0000000..c98472e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogDelegate.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyboard.shortcut.ui
+
+import android.os.Bundle
+import android.view.Gravity
+import android.view.WindowManager
+import com.android.systemui.statusbar.phone.DialogDelegate
+import com.android.systemui.statusbar.phone.SystemUIDialog
+
+class ShortcutCustomizationDialogDelegate : DialogDelegate<SystemUIDialog> {
+
+ override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+ super.onCreate(dialog, savedInstanceState)
+ dialog.window?.apply { setGravity(Gravity.CENTER) }
+ }
+
+ override fun getWidth(dialog: SystemUIDialog): Int {
+ return WindowManager.LayoutParams.WRAP_CONTENT
+ }
+
+ override fun getHeight(dialog: SystemUIDialog): Int {
+ return WindowManager.LayoutParams.WRAP_CONTENT
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
new file mode 100644
index 0000000..02e206e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyboard.shortcut.ui
+
+import android.app.Dialog
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutInfo
+import com.android.systemui.keyboard.shortcut.ui.composable.AssignNewShortcutDialog
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
+import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutCustomizationViewModel
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.statusbar.phone.SystemUIDialogFactory
+import com.android.systemui.statusbar.phone.create
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+class ShortcutCustomizationDialogStarter
+@AssistedInject
+constructor(
+ viewModelFactory: ShortcutCustomizationViewModel.Factory,
+ private val dialogFactory: SystemUIDialogFactory,
+) : ExclusiveActivatable() {
+
+ private var dialog: Dialog? = null
+ private val viewModel = viewModelFactory.create()
+
+ override suspend fun onActivated(): Nothing {
+ viewModel.shortcutCustomizationUiState.collect { uiState ->
+ if (
+ uiState is ShortcutCustomizationUiState.AddShortcutDialog &&
+ !uiState.isDialogShowing
+ ) {
+ dialog = createAddShortcutDialog().also { it.show() }
+ viewModel.onAddShortcutDialogShown()
+ } else if (uiState is ShortcutCustomizationUiState.Inactive) {
+ dialog?.dismiss()
+ dialog = null
+ }
+ }
+ }
+
+ fun onAddShortcutDialogRequested(shortcutBeingCustomized: ShortcutInfo) {
+ viewModel.onAddShortcutDialogRequested(shortcutBeingCustomized)
+ }
+
+ private fun createAddShortcutDialog(): Dialog {
+ return dialogFactory.create(dialogDelegate = ShortcutCustomizationDialogDelegate()) { dialog
+ ->
+ val uiState by viewModel.shortcutCustomizationUiState.collectAsStateWithLifecycle()
+ AssignNewShortcutDialog(
+ uiState = uiState,
+ modifier = Modifier.width(364.dp).wrapContentHeight().padding(vertical = 24.dp),
+ onKeyPress = { viewModel.onKeyPressed(it) },
+ onCancel = { dialog.dismiss() },
+ )
+ dialog.setOnDismissListener { viewModel.onAddShortcutDialogDismissed() }
+ }
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): ShortcutCustomizationDialogStarter
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarter.kt
index d33ab2a..807c70b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarter.kt
@@ -24,6 +24,7 @@
import android.provider.Settings
import androidx.annotation.VisibleForTesting
import androidx.compose.foundation.layout.width
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -47,15 +48,18 @@
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
- private val viewModel: ShortcutHelperViewModel,
+ private val shortcutHelperViewModel: ShortcutHelperViewModel,
+ shortcutCustomizationDialogStarterFactory: ShortcutCustomizationDialogStarter.Factory,
private val dialogFactory: SystemUIDialogFactory,
private val activityStarter: ActivityStarter,
) : CoreStartable {
@VisibleForTesting var dialog: Dialog? = null
+ private val shortcutCustomizationDialogStarter =
+ shortcutCustomizationDialogStarterFactory.create()
override fun start() {
- viewModel.shouldShow
+ shortcutHelperViewModel.shouldShow
.map { shouldShow ->
if (shouldShow) {
dialog = createShortcutHelperDialog().also { it.show() }
@@ -69,16 +73,21 @@
private fun createShortcutHelperDialog(): Dialog {
return dialogFactory.createBottomSheet(
content = { dialog ->
- val shortcutsUiState by viewModel.shortcutsUiState.collectAsStateWithLifecycle()
+ val shortcutsUiState by
+ shortcutHelperViewModel.shortcutsUiState.collectAsStateWithLifecycle()
+ LaunchedEffect(Unit) { shortcutCustomizationDialogStarter.activate() }
ShortcutHelper(
modifier = Modifier.width(getWidth()),
shortcutsUiState = shortcutsUiState,
onKeyboardSettingsClicked = { onKeyboardSettingsClicked(dialog) },
- onSearchQueryChanged = { viewModel.onSearchQueryChanged(it) },
+ onSearchQueryChanged = { shortcutHelperViewModel.onSearchQueryChanged(it) },
+ onCustomizationRequested = {
+ shortcutCustomizationDialogStarter.onAddShortcutDialogRequested(it)
+ },
)
- dialog.setOnDismissListener { viewModel.onViewClosed() }
+ dialog.setOnDismissListener { shortcutHelperViewModel.onViewClosed() }
},
- maxWidth = ShortcutHelperBottomSheet.LargeScreenWidthLandscape
+ maxWidth = ShortcutHelperBottomSheet.LargeScreenWidthLandscape,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
new file mode 100644
index 0000000..43f0f20
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyboard.shortcut.ui.composable
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.collectIsFocusedAsState
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.sizeIn
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Add
+import androidx.compose.material.icons.filled.ErrorOutline
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.key.KeyEvent
+import androidx.compose.ui.input.key.onPreviewKeyEvent
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
+import com.android.systemui.res.R
+
+@Composable
+fun AssignNewShortcutDialog(
+ uiState: ShortcutCustomizationUiState,
+ modifier: Modifier = Modifier,
+ onKeyPress: (KeyEvent) -> Boolean,
+ onCancel: () -> Unit,
+) {
+ if (uiState is ShortcutCustomizationUiState.AddShortcutDialog) {
+ Column(modifier = modifier) {
+ Title(
+ uiState.shortcutLabel,
+ modifier = Modifier.padding(horizontal = 24.dp).width(316.dp),
+ )
+ Description(
+ modifier = Modifier.padding(top = 24.dp, start = 24.dp, end = 24.dp).width(316.dp)
+ )
+ PromptShortcutModifier(
+ modifier =
+ Modifier.padding(top = 24.dp, start = 116.5.dp, end = 116.5.dp)
+ .width(131.dp)
+ .height(48.dp),
+ defaultModifierKey = uiState.defaultCustomShortcutModifierKey,
+ )
+ SelectedKeyCombinationContainer(
+ shouldShowErrorMessage = uiState.shouldShowErrorMessage,
+ onKeyPress = onKeyPress,
+ )
+ KeyCombinationAlreadyInUseErrorMessage(uiState.shouldShowErrorMessage)
+ DialogButtons(onCancel, isValidKeyCombination = uiState.isValidKeyCombination)
+ }
+ }
+}
+
+@Composable
+fun DialogButtons(onCancel: () -> Unit, isValidKeyCombination: Boolean) {
+ Row(
+ modifier =
+ Modifier.padding(top = 24.dp, start = 24.dp, end = 24.dp)
+ .sizeIn(minWidth = 316.dp, minHeight = 48.dp),
+ verticalAlignment = Alignment.Bottom,
+ horizontalArrangement = Arrangement.End,
+ ) {
+ ShortcutHelperButton(
+ shape = RoundedCornerShape(50.dp),
+ onClick = onCancel,
+ color = Color.Transparent,
+ width = 80.dp,
+ contentColor = MaterialTheme.colorScheme.primary,
+ text = stringResource(R.string.shortcut_helper_customize_dialog_cancel_button_label),
+ )
+ Spacer(modifier = Modifier.width(8.dp))
+ ShortcutHelperButton(
+ onClick = {},
+ color = MaterialTheme.colorScheme.primary,
+ width = 116.dp,
+ contentColor = MaterialTheme.colorScheme.onPrimary,
+ text =
+ stringResource(R.string.shortcut_helper_customize_dialog_set_shortcut_button_label),
+ enabled = isValidKeyCombination,
+ )
+ }
+}
+
+@Composable
+fun KeyCombinationAlreadyInUseErrorMessage(shouldShowErrorMessage: Boolean) {
+ if (shouldShowErrorMessage) {
+ Box(modifier = Modifier.padding(horizontal = 16.dp).width(332.dp).height(40.dp)) {
+ Text(
+ text = stringResource(R.string.shortcut_helper_customize_dialog_error_message),
+ style = MaterialTheme.typography.bodyMedium,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ fontWeight = FontWeight.W500,
+ color = MaterialTheme.colorScheme.error,
+ modifier = Modifier.padding(start = 24.dp).width(252.dp),
+ )
+ }
+ }
+}
+
+@Composable
+fun SelectedKeyCombinationContainer(
+ keyCombination: String =
+ stringResource(R.string.shortcut_helper_add_shortcut_dialog_placeholder),
+ shouldShowErrorMessage: Boolean,
+ onKeyPress: (KeyEvent) -> Boolean,
+) {
+ val interactionSource = remember { MutableInteractionSource() }
+ val isFocused by interactionSource.collectIsFocusedAsState()
+ val outlineColor =
+ if (!isFocused) MaterialTheme.colorScheme.outline
+ else if (shouldShowErrorMessage) MaterialTheme.colorScheme.error
+ else MaterialTheme.colorScheme.primary
+
+ ClickableShortcutSurface(
+ onClick = {},
+ color = Color.Transparent,
+ shape = RoundedCornerShape(50.dp),
+ modifier =
+ Modifier.padding(all = 16.dp)
+ .sizeIn(minWidth = 332.dp, minHeight = 56.dp)
+ .border(width = 2.dp, color = outlineColor, shape = RoundedCornerShape(50.dp))
+ .onPreviewKeyEvent { onKeyPress(it) },
+ interactionSource = interactionSource,
+ ) {
+ Row(
+ modifier = Modifier.padding(start = 24.dp, top = 16.dp, end = 16.dp, bottom = 16.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Text(
+ text = keyCombination,
+ style = MaterialTheme.typography.headlineSmall,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ fontWeight = FontWeight.W500,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.width(252.dp),
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ if (shouldShowErrorMessage) {
+ Icon(
+ imageVector = Icons.Default.ErrorOutline,
+ contentDescription = null,
+ modifier = Modifier.size(20.dp),
+ tint = MaterialTheme.colorScheme.error,
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun Title(title: String, modifier: Modifier = Modifier) {
+ Text(
+ text = title,
+ style = MaterialTheme.typography.headlineSmall,
+ fontSize = 24.sp,
+ modifier = modifier.wrapContentSize(Alignment.Center),
+ color = MaterialTheme.colorScheme.onSurface,
+ lineHeight = 32.sp,
+ )
+}
+
+@Composable
+private fun Description(modifier: Modifier = Modifier) {
+ Text(
+ text = stringResource(id = R.string.shortcut_helper_customize_mode_sub_title),
+ style = MaterialTheme.typography.bodyMedium,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ modifier = modifier.wrapContentSize(Alignment.Center),
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+}
+
+@Composable
+private fun PromptShortcutModifier(
+ modifier: Modifier,
+ defaultModifierKey: ShortcutKey.Icon.ResIdIcon,
+) {
+ Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(2.dp)) {
+ ActionKeyContainer(defaultModifierKey)
+ PlusIconContainer()
+ }
+}
+
+@Composable
+private fun ActionKeyContainer(defaultModifierKey: ShortcutKey.Icon.ResIdIcon) {
+ Row(
+ modifier =
+ Modifier.height(48.dp)
+ .width(105.dp)
+ .background(
+ color = MaterialTheme.colorScheme.surface,
+ shape = RoundedCornerShape(16.dp),
+ )
+ .padding(all = 12.dp),
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ ActionKeyIcon(defaultModifierKey)
+ ActionKeyText()
+ }
+}
+
+@Composable
+fun ActionKeyText() {
+ Text(
+ text = "Action",
+ style = MaterialTheme.typography.titleMedium,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ modifier = Modifier.wrapContentSize(Alignment.Center),
+ color = MaterialTheme.colorScheme.onSurface,
+ )
+}
+
+@Composable
+private fun ActionKeyIcon(defaultModifierKey: ShortcutKey.Icon.ResIdIcon) {
+ Icon(
+ painter = painterResource(id = defaultModifierKey.drawableResId),
+ contentDescription = stringResource(R.string.shortcut_helper_content_description_meta_key),
+ modifier = Modifier.size(24.dp).wrapContentSize(Alignment.Center),
+ )
+}
+
+@Composable
+private fun PlusIconContainer() {
+ Icon(
+ tint = MaterialTheme.colorScheme.onSurface,
+ imageVector = Icons.Default.Add,
+ contentDescription =
+ stringResource(id = R.string.shortcut_helper_content_description_plus_icon),
+ modifier = Modifier.padding(vertical = 12.dp).size(24.dp).wrapContentSize(Alignment.Center),
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index abddc70..13934ea 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -110,6 +110,7 @@
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import com.android.systemui.keyboard.shortcut.ui.model.IconSource
@@ -124,6 +125,7 @@
modifier: Modifier = Modifier,
shortcutsUiState: ShortcutsUiState,
useSinglePane: @Composable () -> Boolean = { shouldUseSinglePane() },
+ onCustomizationRequested: (ShortcutInfo) -> Unit = {},
) {
when (shortcutsUiState) {
is ShortcutsUiState.Active -> {
@@ -133,6 +135,7 @@
onSearchQueryChanged,
modifier,
onKeyboardSettingsClicked,
+ onCustomizationRequested,
)
}
else -> {
@@ -148,6 +151,7 @@
onSearchQueryChanged: (String) -> Unit,
modifier: Modifier,
onKeyboardSettingsClicked: () -> Unit,
+ onCustomizationRequested: (ShortcutInfo) -> Unit = {},
) {
var selectedCategoryType by
remember(shortcutsUiState.defaultSelectedCategory) {
@@ -173,6 +177,7 @@
onCategorySelected = { selectedCategoryType = it },
onKeyboardSettingsClicked,
shortcutsUiState.isShortcutCustomizerFlagEnabled,
+ onCustomizationRequested,
)
}
}
@@ -362,6 +367,7 @@
onCategorySelected: (ShortcutCategoryType?) -> Unit,
onKeyboardSettingsClicked: () -> Unit,
isShortcutCustomizerFlagEnabled: Boolean,
+ onCustomizationRequested: (ShortcutInfo) -> Unit = {},
) {
val selectedCategory = categories.fastFirstOrNull { it.type == selectedCategoryType }
var isCustomizeModeEntered by remember { mutableStateOf(false) }
@@ -400,6 +406,7 @@
Modifier.fillMaxSize().padding(top = 8.dp),
selectedCategory,
isCustomizing = isCustomizing,
+ onCustomizationRequested = onCustomizationRequested,
)
}
}
@@ -434,6 +441,7 @@
modifier: Modifier,
category: ShortcutCategoryUi?,
isCustomizing: Boolean,
+ onCustomizationRequested: (ShortcutInfo) -> Unit = {},
) {
val listState = rememberLazyListState()
LaunchedEffect(key1 = category) { if (category != null) listState.animateScrollToItem(0) }
@@ -447,6 +455,15 @@
searchQuery = searchQuery,
subCategory = subcategory,
isCustomizing = isCustomizing,
+ onCustomizationRequested = { label, subCategoryLabel ->
+ onCustomizationRequested(
+ ShortcutInfo(
+ label = label,
+ subCategoryLabel = subCategoryLabel,
+ categoryType = category.type,
+ )
+ )
+ },
)
Spacer(modifier = Modifier.height(8.dp))
}
@@ -476,6 +493,7 @@
searchQuery: String,
subCategory: ShortcutSubCategory,
isCustomizing: Boolean,
+ onCustomizationRequested: (String, String) -> Unit = { _: String, _: String -> },
) {
Surface(
modifier = Modifier.fillMaxWidth(),
@@ -497,6 +515,7 @@
searchQuery = searchQuery,
shortcut = shortcut,
isCustomizing = isCustomizing,
+ onCustomizationRequested = { onCustomizationRequested(it, subCategory.label) },
)
}
}
@@ -518,6 +537,7 @@
searchQuery: String,
shortcut: ShortcutModel,
isCustomizing: Boolean = false,
+ onCustomizationRequested: (String) -> Unit = {},
) {
val interactionSource = remember { MutableInteractionSource() }
val isFocused by interactionSource.collectIsFocusedAsState()
@@ -541,7 +561,12 @@
ShortcutDescriptionText(searchQuery = searchQuery, shortcut = shortcut)
}
Spacer(modifier = Modifier.width(24.dp))
- ShortcutKeyCombinations(modifier = Modifier.weight(1f), shortcut = shortcut, isCustomizing)
+ ShortcutKeyCombinations(
+ modifier = Modifier.weight(1f),
+ shortcut = shortcut,
+ isCustomizing = isCustomizing,
+ onAddShortcutClicked = { onCustomizationRequested(shortcut.label) },
+ )
}
}
@@ -569,6 +594,7 @@
modifier: Modifier = Modifier,
shortcut: ShortcutModel,
isCustomizing: Boolean = false,
+ onAddShortcutClicked: () -> Unit = {},
) {
FlowRow(
modifier = modifier,
@@ -590,7 +616,7 @@
color = MaterialTheme.colorScheme.outline,
shape = CircleShape,
),
- onClick = {},
+ onClick = { onAddShortcutClicked() },
color = Color.Transparent,
width = 32.dp,
height = 32.dp,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt
index 435968e..e761c73 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt
@@ -44,6 +44,7 @@
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTonalElevationEnabled
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor
import androidx.compose.material3.minimumInteractiveComponentSize
@@ -283,6 +284,108 @@
}
@Composable
+fun ShortcutHelperButton(
+ modifier: Modifier = Modifier,
+ onClick: () -> Unit,
+ shape: Shape = RoundedCornerShape(360.dp),
+ color: Color,
+ width: Dp,
+ height: Dp = 40.dp,
+ iconSource: IconSource = IconSource(),
+ text: String? = null,
+ contentColor: Color,
+ contentPaddingHorizontal: Dp = 16.dp,
+ contentPaddingVertical: Dp = 10.dp,
+ enabled: Boolean = true,
+) {
+ ShortcutHelperButtonSurface(
+ onClick = onClick,
+ shape = shape,
+ color = color,
+ modifier = modifier,
+ enabled = enabled,
+ width = width,
+ height = height,
+ ) {
+ Row(
+ modifier =
+ Modifier.padding(
+ horizontal = contentPaddingHorizontal,
+ vertical = contentPaddingVertical,
+ ),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.Center,
+ ) {
+ if (iconSource.imageVector != null) {
+ Icon(
+ tint = contentColor,
+ imageVector = iconSource.imageVector,
+ contentDescription =
+ null, // TODO this probably should not be null for accessibility.
+ modifier = Modifier.size(20.dp).wrapContentSize(Alignment.Center),
+ )
+ }
+
+ if (iconSource.imageVector != null && text != null)
+ Spacer(modifier = Modifier.weight(1f))
+
+ if (text != null) {
+ Text(
+ text,
+ color = contentColor,
+ fontSize = 14.sp,
+ style = MaterialTheme.typography.labelLarge,
+ modifier = Modifier.wrapContentSize(Alignment.Center),
+ )
+ }
+ }
+ }
+}
+
+@Composable
+fun ShortcutHelperButtonSurface(
+ onClick: () -> Unit,
+ shape: Shape,
+ color: Color,
+ modifier: Modifier = Modifier,
+ enabled: Boolean,
+ width: Dp,
+ height: Dp,
+ content: @Composable () -> Unit,
+) {
+ if (enabled) {
+ ClickableShortcutSurface(
+ onClick = onClick,
+ shape = shape,
+ color = color,
+ modifier = modifier.semantics { role = Role.Button }.width(width).height(height),
+ interactionsConfig =
+ InteractionsConfig(
+ hoverOverlayColor = MaterialTheme.colorScheme.onSurface,
+ hoverOverlayAlpha = 0.11f,
+ pressedOverlayColor = MaterialTheme.colorScheme.onSurface,
+ pressedOverlayAlpha = 0.15f,
+ focusOutlineColor = MaterialTheme.colorScheme.secondary,
+ focusOutlineStrokeWidth = 3.dp,
+ focusOutlinePadding = 2.dp,
+ surfaceCornerRadius = 28.dp,
+ focusOutlineCornerRadius = 33.dp,
+ ),
+ ) {
+ content()
+ }
+ } else {
+ Surface(
+ shape = shape,
+ color = color.copy(0.38f),
+ modifier = modifier.semantics { role = Role.Button }.width(width).height(height),
+ ) {
+ content()
+ }
+ }
+}
+
+@Composable
private fun surfaceColorAtElevation(color: Color, elevation: Dp): Color {
return MaterialTheme.colorScheme.applyTonalElevation(color, elevation)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
new file mode 100644
index 0000000..e9f2a3b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyboard.shortcut.ui.model
+
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
+
+sealed interface ShortcutCustomizationUiState {
+ data class AddShortcutDialog(
+ val shortcutLabel: String,
+ val shouldShowErrorMessage: Boolean,
+ val isValidKeyCombination: Boolean,
+ val defaultCustomShortcutModifierKey: ShortcutKey.Icon.ResIdIcon,
+ val isDialogShowing: Boolean,
+ ) : ShortcutCustomizationUiState
+
+ data object Inactive : ShortcutCustomizationUiState
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
new file mode 100644
index 0000000..b925387
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyboard.shortcut.ui.viewmodel
+
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.ui.input.key.KeyEvent
+import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutCustomizationInteractor
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutInfo
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.update
+
+class ShortcutCustomizationViewModel
+@AssistedInject
+constructor(private val shortcutCustomizationInteractor: ShortcutCustomizationInteractor) {
+ private val _shortcutBeingCustomized = mutableStateOf<ShortcutInfo?>(null)
+
+ private val _shortcutCustomizationUiState =
+ MutableStateFlow<ShortcutCustomizationUiState>(ShortcutCustomizationUiState.Inactive)
+
+ val shortcutCustomizationUiState = _shortcutCustomizationUiState.asStateFlow()
+
+ fun onAddShortcutDialogRequested(shortcutBeingCustomized: ShortcutInfo) {
+ _shortcutCustomizationUiState.value =
+ ShortcutCustomizationUiState.AddShortcutDialog(
+ shortcutLabel = shortcutBeingCustomized.label,
+ shouldShowErrorMessage = false,
+ isValidKeyCombination = false,
+ defaultCustomShortcutModifierKey =
+ shortcutCustomizationInteractor.getDefaultCustomShortcutModifierKey(),
+ isDialogShowing = false,
+ )
+
+ _shortcutBeingCustomized.value = shortcutBeingCustomized
+ }
+
+ fun onAddShortcutDialogShown() {
+ _shortcutCustomizationUiState.update { uiState ->
+ (uiState as? ShortcutCustomizationUiState.AddShortcutDialog)
+ ?.let { it.copy(isDialogShowing = true) }
+ ?: uiState
+ }
+ }
+
+ fun onAddShortcutDialogDismissed() {
+ _shortcutBeingCustomized.value = null
+ _shortcutCustomizationUiState.value = ShortcutCustomizationUiState.Inactive
+ }
+
+ fun onKeyPressed(keyEvent: KeyEvent): Boolean {
+ // TODO Not yet implemented b/373638584
+ return false
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): ShortcutCustomizationViewModel
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/data/repository/StickyKeysRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/data/repository/StickyKeysRepository.kt
index 585f7ed..922bc15 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/data/repository/StickyKeysRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/data/repository/StickyKeysRepository.kt
@@ -52,6 +52,7 @@
constructor(
private val inputManager: InputManager,
@Background private val backgroundDispatcher: CoroutineDispatcher,
+ // TODO: b/377244768 - Change to inject SecureSettingsRepository
secureSettingsRepository: UserAwareSecureSettingsRepository,
private val stickyKeysLogger: StickyKeysLogger,
) : StickyKeysRepository {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index e79f590..2d05600 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -60,6 +60,7 @@
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.NotificationShadeWindowView
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.KeyguardIndicationController
import com.android.systemui.statusbar.LightRevealScrim
@@ -93,7 +94,7 @@
private val chipbarCoordinator: ChipbarCoordinator,
private val keyguardBlueprintViewModel: KeyguardBlueprintViewModel,
private val keyguardStatusViewComponentFactory: KeyguardStatusViewComponent.Factory,
- private val configuration: ConfigurationState,
+ @ShadeDisplayAware private val configuration: ConfigurationState,
private val context: Context,
private val keyguardIndicationController: KeyguardIndicationController,
private val shadeInteractor: ShadeInteractor,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
index ca86289..73a4cc3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt
@@ -25,6 +25,7 @@
import com.android.systemui.doze.util.BurnInHelperWrapper
import com.android.systemui.keyguard.shared.model.BurnInModel
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -47,7 +48,7 @@
private val context: Context,
private val burnInHelperWrapper: BurnInHelperWrapper,
@Application private val scope: CoroutineScope,
- private val configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
private val keyguardInteractor: KeyguardInteractor,
) {
val deviceEntryIconXOffset: StateFlow<Int> =
@@ -62,7 +63,7 @@
.stateIn(
scope,
SharingStarted.WhileSubscribed(),
- burnInHelperWrapper.burnInProgressOffset()
+ burnInHelperWrapper.burnInProgressOffset(),
)
/** Given the max x,y dimens, determine the current translation shifts. */
@@ -71,7 +72,7 @@
burnInOffset(xDimenResourceId, isXAxis = true),
burnInOffset(yDimenResourceId, isXAxis = false).map {
it * 2 - context.resources.getDimensionPixelSize(yDimenResourceId)
- }
+ },
) { translationX, translationY ->
BurnInModel(translationX, translationY, burnInHelperWrapper.burnInScale())
}
@@ -117,7 +118,7 @@
private fun calculateOffset(
maxBurnInOffsetPixels: Int,
isXAxis: Boolean,
- scale: Float = 1f
+ scale: Float = 1f,
): Int {
return (burnInHelperWrapper.burnInOffset(maxBurnInOffsetPixels, isXAxis) * scale).toInt()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index 6ac0a3f..021cce6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -20,6 +20,7 @@
import android.annotation.SuppressLint
import android.app.DreamManager
import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.Flags.communalSceneKtfRefactor
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
@@ -41,7 +42,6 @@
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.debounce
-import com.android.app.tracing.coroutines.launchTraced as launch
@SysUISingleton
class FromDozingTransitionInteractor
@@ -135,11 +135,22 @@
if (!deviceEntryInteractor.isLockscreenEnabled()) {
if (!SceneContainerFlag.isEnabled) {
- startTransitionTo(KeyguardState.GONE)
+ startTransitionTo(
+ KeyguardState.GONE,
+ ownerReason = "lockscreen not enabled",
+ )
}
} else if (canDismissLockscreen() || isKeyguardGoingAway) {
if (!SceneContainerFlag.isEnabled) {
- startTransitionTo(KeyguardState.GONE)
+ startTransitionTo(
+ KeyguardState.GONE,
+ ownerReason =
+ if (canDismissLockscreen()) {
+ "canDismissLockscreen()"
+ } else {
+ "isKeyguardGoingAway"
+ },
+ )
}
} else if (primaryBouncerShowing) {
if (!SceneContainerFlag.isEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
index 6385b3c..2aaec87 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
@@ -19,6 +19,7 @@
package com.android.systemui.keyguard.domain.interactor
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.CoreStartable
import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
@@ -32,6 +33,7 @@
import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Type
import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -39,7 +41,6 @@
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
-import com.android.app.tracing.coroutines.launchTraced as launch
@SysUISingleton
class KeyguardBlueprintInteractor
@@ -48,7 +49,7 @@
private val keyguardBlueprintRepository: KeyguardBlueprintRepository,
@Application private val applicationScope: CoroutineScope,
shadeInteractor: ShadeInteractor,
- private val configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
private val fingerprintPropertyInteractor: FingerprintPropertyInteractor,
private val smartspaceSection: SmartspaceSection,
) : CoreStartable {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 2e0a160..26c286d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -49,6 +49,7 @@
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
import com.android.systemui.util.kotlin.sample
@@ -85,7 +86,7 @@
private val repository: KeyguardRepository,
powerInteractor: PowerInteractor,
bouncerRepository: KeyguardBouncerRepository,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
shadeRepository: ShadeRepository,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
sceneInteractorProvider: Provider<SceneInteractor>,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
index 0dae17c..cd62d5f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
@@ -16,9 +16,11 @@
package com.android.systemui.keyguard.domain.interactor
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.keyguard.logging.KeyguardLogger
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.log.core.LogLevel.VERBOSE
@@ -29,7 +31,6 @@
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.debounce
-import com.android.app.tracing.coroutines.launchTraced as launch
private val TAG = KeyguardTransitionAuditLogger::class.simpleName!!
@@ -48,6 +49,7 @@
private val aodBurnInViewModel: AodBurnInViewModel,
private val shadeInteractor: ShadeInteractor,
private val keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
+ private val deviceEntryInteractor: DeviceEntryInteractor,
) {
fun start() {
@@ -84,6 +86,18 @@
}
scope.launch {
+ deviceEntryInteractor.isUnlocked.collect {
+ logger.log(TAG, VERBOSE, "DeviceEntry isUnlocked", it)
+ }
+ }
+
+ scope.launch {
+ deviceEntryInteractor.isLockscreenEnabled.collect {
+ logger.log(TAG, VERBOSE, "DeviceEntry isLockscreenEnabled", it)
+ }
+ }
+
+ scope.launch {
keyguardInteractor.primaryBouncerShowing.collect {
logger.log(TAG, VERBOSE, "Primary bouncer showing", it)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
index abd7f90..7d4d377 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
@@ -18,6 +18,7 @@
import android.animation.ValueAnimator
import android.util.Log
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -33,7 +34,6 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
-import com.android.app.tracing.coroutines.launchTraced as launch
/**
* Each TransitionInteractor is responsible for determining under which conditions to notify
@@ -201,9 +201,18 @@
scope.launch {
keyguardInteractor.onCameraLaunchDetected.filterRelevantKeyguardState().collect {
if (!maybeHandleInsecurePowerGesture()) {
+ val lastStep = transitionInteractor.transitionState.value
+ val modeOnCanceled =
+ if (lastStep.to == KeyguardState.AOD) {
+ // Enabled smooth transition when double-tap camera cancels
+ // transition to AOD
+ TransitionModeOnCanceled.REVERSE
+ } else {
+ TransitionModeOnCanceled.RESET
+ }
startTransitionTo(
toState = KeyguardState.OCCLUDED,
- modeOnCanceled = TransitionModeOnCanceled.RESET,
+ modeOnCanceled = modeOnCanceled,
ownerReason = "keyguardInteractor.onCameraLaunchDetected",
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index 2c9884a..f473a82 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -126,14 +126,7 @@
sceneInteractor.get().transitionState.flatMapLatestConflated { state ->
when {
state.isTransitioning(from = Scenes.Lockscreen, to = Scenes.Gone) ->
- (state as Transition).isUserInputOngoing.flatMapLatestConflated {
- isUserInputOngoing ->
- if (isUserInputOngoing) {
- isDeviceEntered
- } else {
- flowOf(true)
- }
- }
+ isDeviceEntered
state.isTransitioning(from = Scenes.Bouncer, to = Scenes.Gone) ->
(state as Transition).progress.map { progress ->
progress >
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt
index 36ef78e..faa4978 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt
@@ -33,6 +33,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.AlwaysOnDisplayNotificationIconViewStore
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.StatusBarIconViewBindingFailureTracker
@@ -47,7 +48,7 @@
@Inject
constructor(
private val context: Context,
- private val configurationState: ConfigurationState,
+ @ShadeDisplayAware private val configurationState: ConfigurationState,
private val iconBindingFailureTracker: StatusBarIconViewBindingFailureTracker,
private val nicAodViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
private val nicAodIconViewStore: AlwaysOnDisplayNotificationIconViewStore,
@@ -70,7 +71,7 @@
resources.getDimensionPixelSize(R.dimen.below_clock_padding_start_icons),
0,
0,
- 0
+ 0,
)
setVisibility(View.INVISIBLE)
}
@@ -113,18 +114,18 @@
START,
PARENT_ID,
START,
- context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
+ context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal),
)
connect(
nicId,
END,
PARENT_ID,
END,
- context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
+ context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal),
)
constrainHeight(
nicId,
- context.resources.getDimensionPixelSize(R.dimen.notification_shelf_height)
+ context.resources.getDimensionPixelSize(R.dimen.notification_shelf_height),
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
index 4908dbd..56e3125 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
@@ -24,6 +24,7 @@
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
import com.android.systemui.keyguard.ui.view.DeviceEntryIconView
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shared.recents.utilities.Utilities.clamp
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -41,7 +42,7 @@
@Inject
constructor(
val context: Context,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
deviceEntryBackgroundViewModel: DeviceEntryBackgroundViewModel,
fingerprintPropertyInteractor: FingerprintPropertyInteractor,
@@ -85,10 +86,7 @@
}
private val fgIconPadding: Flow<Int> = udfpsOverlayInteractor.iconPadding
val fgViewModel: Flow<DeviceEntryForegroundViewModel.ForegroundIconViewModel> =
- combine(
- fgIconColor,
- fgIconPadding,
- ) { color, padding ->
+ combine(fgIconColor, fgIconPadding) { color, padding ->
DeviceEntryForegroundViewModel.ForegroundIconViewModel(
type = DeviceEntryIconView.IconType.FINGERPRINT,
useAodVariant = false,
@@ -100,12 +98,7 @@
val bgColor: Flow<Int> = deviceEntryBackgroundViewModel.color
val bgAlpha: Flow<Float> = flowOf(1f)
- data class IconLocation(
- val left: Int,
- val top: Int,
- val right: Int,
- val bottom: Int,
- ) {
+ data class IconLocation(val left: Int, val top: Int, val right: Int, val bottom: Int) {
val width = right - left
val height = bottom - top
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
index c78e0c9..1c89723 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
@@ -30,9 +30,11 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.BurnInModel
import com.android.systemui.keyguard.shared.model.ClockSize
+import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.StateToValue
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlin.math.max
import kotlinx.coroutines.CoroutineScope
@@ -42,8 +44,10 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
@@ -57,7 +61,7 @@
constructor(
@Application private val applicationScope: CoroutineScope,
private val burnInInteractor: BurnInInteractor,
- private val configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
private val keyguardInteractor: KeyguardInteractor,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val goneToAodTransitionViewModel: GoneToAodTransitionViewModel,
@@ -164,9 +168,17 @@
private fun burnIn(params: BurnInParameters): Flow<BurnInModel> {
return combine(
- keyguardTransitionInteractor.transitionValue(KeyguardState.AOD).map {
- Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it)
- },
+ merge(
+ keyguardTransitionInteractor.transition(Edge.create(to = KeyguardState.AOD)),
+ keyguardTransitionInteractor
+ .transition(Edge.create(from = KeyguardState.AOD))
+ .map { it.copy(value = 1f - it.value) },
+ keyguardTransitionInteractor
+ .transition(Edge.create(to = KeyguardState.LOCKSCREEN))
+ .filter { it.from != KeyguardState.AOD }
+ .map { it.copy(value = 0f) },
+ )
+ .map { Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it.value) },
burnInInteractor.burnIn(
xDimenResourceId = R.dimen.burn_in_prevention_offset_x,
yDimenResourceId = R.dimen.burn_in_prevention_offset_y,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
index 4c667c1..12f9467 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
@@ -23,6 +23,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -42,7 +43,7 @@
val context: Context,
val deviceEntryIconViewModel: DeviceEntryIconViewModel,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
alternateBouncerToAodTransitionViewModel: AlternateBouncerToAodTransitionViewModel,
alternateBouncerToDozingTransitionViewModel: AlternateBouncerToDozingTransitionViewModel,
aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt
index 87c32a5..749f193 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt
@@ -27,6 +27,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.view.DeviceEntryIconView
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlin.math.roundToInt
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -45,7 +46,7 @@
@Inject
constructor(
val context: Context,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
transitionInteractor: KeyguardTransitionInteractor,
deviceEntryIconViewModel: DeviceEntryIconViewModel,
@@ -106,12 +107,11 @@
}
val viewModel: Flow<ForegroundIconViewModel> =
- combine(
- deviceEntryIconViewModel.iconType,
- useAodIconVariant,
+ combine(deviceEntryIconViewModel.iconType, useAodIconVariant, color, padding) {
+ iconType,
+ useAodVariant,
color,
- padding,
- ) { iconType, useAodVariant, color, padding ->
+ padding ->
ForegroundIconViewModel(
type = iconType,
useAodVariant = useAodVariant,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt
index 11ed52a..c9fdf7a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt
@@ -27,6 +27,7 @@
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
@@ -41,7 +42,7 @@
@Inject
constructor(
animationFlow: KeyguardTransitionAnimationFlow,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
) : DeviceEntryIconTransition {
private val transitionAnimation =
animationFlow
@@ -49,15 +50,13 @@
duration = TO_GLANCEABLE_HUB_DURATION,
edge = Edge.create(from = DREAMING, to = Scenes.Communal),
)
- .setupWithoutSceneContainer(
- edge = Edge.create(from = DREAMING, to = GLANCEABLE_HUB),
- )
+ .setupWithoutSceneContainer(edge = Edge.create(from = DREAMING, to = GLANCEABLE_HUB))
val dreamOverlayTranslationX: Flow<Float> =
configurationInteractor
.directionalDimensionPixelSize(
LayoutDirection.LTR,
- R.dimen.dreaming_to_hub_transition_dream_overlay_translation_x
+ R.dimen.dreaming_to_hub_transition_dream_overlay_translation_x,
)
.flatMapLatest { translatePx ->
transitionAnimation.sharedFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt
index f69f996..723fba6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt
@@ -27,6 +27,7 @@
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
@@ -41,7 +42,7 @@
@Inject
constructor(
animationFlow: KeyguardTransitionAnimationFlow,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
) : DeviceEntryIconTransition {
private val transitionAnimation =
@@ -50,9 +51,7 @@
duration = FROM_GLANCEABLE_HUB_DURATION,
edge = Edge.create(from = Scenes.Communal, to = DREAMING),
)
- .setupWithoutSceneContainer(
- edge = Edge.create(from = GLANCEABLE_HUB, to = DREAMING),
- )
+ .setupWithoutSceneContainer(edge = Edge.create(from = GLANCEABLE_HUB, to = DREAMING))
val dreamOverlayAlpha: Flow<Float> =
transitionAnimation.sharedFlow(
@@ -66,7 +65,7 @@
configurationInteractor
.directionalDimensionPixelSize(
LayoutDirection.LTR,
- R.dimen.hub_to_dreaming_transition_dream_overlay_translation_x
+ R.dimen.hub_to_dreaming_transition_dream_overlay_translation_x,
)
.flatMapLatest { translatePx: Int ->
transitionAnimation.sharedFlow(
@@ -74,7 +73,7 @@
onStep = { value -> -translatePx + value * translatePx },
interpolator = Interpolators.EMPHASIZED,
onCancel = { -translatePx.toFloat() },
- name = "GLANCEABLE_HUB->LOCKSCREEN: dreamOverlayTranslationX"
+ name = "GLANCEABLE_HUB->LOCKSCREEN: dreamOverlayTranslationX",
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt
index 7f3ef61..5a4d0689 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt
@@ -28,6 +28,7 @@
import com.android.systemui.keyguard.ui.StateToValue
import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -45,7 +46,7 @@
class GlanceableHubToLockscreenTransitionViewModel
@Inject
constructor(
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
animationFlow: KeyguardTransitionAnimationFlow,
) {
private val transitionAnimation =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index 36f684e..5c79c0b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -29,6 +29,7 @@
import com.android.systemui.keyguard.shared.model.ClockSizeSetting
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
import com.android.systemui.statusbar.ui.SystemBarUtilsProxy
@@ -50,7 +51,8 @@
aodNotificationIconViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
@get:VisibleForTesting val shadeInteractor: ShadeInteractor,
private val systemBarUtils: SystemBarUtilsProxy,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
+ // TODO: b/374267505 - Use ShadeDisplayAware resources here.
@Main private val resources: Resources,
) {
var burnInLayer: Layer? = null
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
index ceae1b5..bc3ef02 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
@@ -31,6 +31,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
import javax.inject.Inject
import javax.inject.Named
@@ -53,7 +54,7 @@
burnInInteractor: BurnInInteractor,
@Named(KeyguardQuickAffordancesCombinedViewModelModule.Companion.LOCKSCREEN_INSTANCE)
shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
communalSceneInteractor: CommunalSceneInteractor,
@Background private val backgroundDispatcher: CoroutineDispatcher,
@@ -70,7 +71,7 @@
val visible: Flow<Boolean> =
anyOf(
keyguardInteractor.statusBarState.map { state -> state == StatusBarState.KEYGUARD },
- communalSceneInteractor.isCommunalVisible
+ communalSceneInteractor.isCommunalVisible,
)
/** An observable for whether the indication area should be padded. */
@@ -85,7 +86,7 @@
} else {
combine(
keyguardBottomAreaViewModel.startButton,
- keyguardBottomAreaViewModel.endButton
+ keyguardBottomAreaViewModel.endButton,
) { startButtonModel, endButtonModel ->
startButtonModel.isVisible || endButtonModel.isVisible
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt
index dd8ff8c..acaa9b9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt
@@ -28,6 +28,7 @@
import com.android.systemui.keyguard.ui.StateToValue
import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -45,7 +46,7 @@
class LockscreenToGlanceableHubTransitionViewModel
@Inject
constructor(
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
animationFlow: KeyguardTransitionAnimationFlow,
) {
private val transitionAnimation =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
index 88e8968..6565e31 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
@@ -26,6 +26,7 @@
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
@@ -40,7 +41,7 @@
@Inject
constructor(
shadeDependentFlows: ShadeDependentFlows,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
animationFlow: KeyguardTransitionAnimationFlow,
) : DeviceEntryIconTransition {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
index 737bd7a..d10970f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
@@ -29,6 +29,7 @@
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.util.kotlin.pairwise
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
@@ -49,7 +50,7 @@
@Inject
constructor(
deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
animationFlow: KeyguardTransitionAnimationFlow,
keyguardInteractor: KeyguardInteractor,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
@@ -104,7 +105,7 @@
!isOccluded &&
keyguardTransitionInteractor.getCurrentState() == OCCLUDED
}
- .map { 0f }
+ .map { 0f },
)
val deviceEntryBackgroundViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt
index a33685b..d38e507 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt
@@ -28,6 +28,7 @@
import androidx.media.utils.MediaConstants
import androidx.media3.common.Player
import androidx.media3.session.CommandButton
+import androidx.media3.session.MediaController as Media3Controller
import androidx.media3.session.SessionCommand
import androidx.media3.session.SessionToken
import com.android.systemui.dagger.SysUISingleton
@@ -82,10 +83,19 @@
// Build button info
val buttons = suspendCancellableCoroutine { continuation ->
// Media3Controller methods must always be called from a specific looper
- handler.post {
- val result = getMedia3Actions(packageName, m3controller, token)
- m3controller.release()
- continuation.resumeWith(Result.success(result))
+ val runnable = Runnable {
+ try {
+ val result = getMedia3Actions(packageName, m3controller, token)
+ continuation.resumeWith(Result.success(result))
+ } finally {
+ m3controller.release()
+ }
+ }
+ handler.post(runnable)
+ continuation.invokeOnCancellation {
+ // Ensure controller is released, even if loading was cancelled partway through
+ handler.post(m3controller::release)
+ handler.removeCallbacks(runnable)
}
}
return buttons
@@ -95,7 +105,7 @@
@WorkerThread
private fun getMedia3Actions(
packageName: String,
- m3controller: androidx.media3.session.MediaController,
+ m3controller: Media3Controller,
token: SessionToken,
): MediaButton? {
Assert.isNotMainThread()
@@ -197,7 +207,7 @@
* @return A [MediaAction] representing the first supported command, or null if not supported
*/
private fun getStandardAction(
- controller: androidx.media3.session.MediaController,
+ controller: Media3Controller,
token: SessionToken,
vararg commands: @Player.Command Int,
): MediaAction? {
@@ -304,37 +314,40 @@
bgScope.launch {
val controller = controllerFactory.create(token, looper)
handler.post {
- when (command) {
- Player.COMMAND_PLAY_PAUSE -> {
- if (controller.isPlaying) controller.pause() else controller.play()
- }
-
- Player.COMMAND_SEEK_TO_PREVIOUS -> controller.seekToPrevious()
- Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM ->
- controller.seekToPreviousMediaItem()
-
- Player.COMMAND_SEEK_TO_NEXT -> controller.seekToNext()
- Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM -> controller.seekToNextMediaItem()
- Player.COMMAND_INVALID -> {
- if (
- customAction != null &&
- customAction!!.sessionCommand != null &&
- controller.isSessionCommandAvailable(
- customAction!!.sessionCommand!!
- )
- ) {
- controller.sendCustomCommand(
- customAction!!.sessionCommand!!,
- customAction!!.extras,
- )
- } else {
- logger.logMedia3UnsupportedCommand("$command, action $customAction")
+ try {
+ when (command) {
+ Player.COMMAND_PLAY_PAUSE -> {
+ if (controller.isPlaying) controller.pause() else controller.play()
}
- }
- else -> logger.logMedia3UnsupportedCommand(command.toString())
+ Player.COMMAND_SEEK_TO_PREVIOUS -> controller.seekToPrevious()
+ Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM ->
+ controller.seekToPreviousMediaItem()
+
+ Player.COMMAND_SEEK_TO_NEXT -> controller.seekToNext()
+ Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM -> controller.seekToNextMediaItem()
+ Player.COMMAND_INVALID -> {
+ if (customAction?.sessionCommand != null) {
+ val sessionCommand = customAction.sessionCommand!!
+ if (controller.isSessionCommandAvailable(sessionCommand)) {
+ controller.sendCustomCommand(
+ sessionCommand,
+ customAction.extras,
+ )
+ } else {
+ logger.logMedia3UnsupportedCommand(
+ "$sessionCommand, action $customAction"
+ )
+ }
+ } else {
+ logger.logMedia3UnsupportedCommand("$command, action $customAction")
+ }
+ }
+ else -> logger.logMedia3UnsupportedCommand(command.toString())
+ }
+ } finally {
+ controller.release()
}
- controller.release()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControllerFactory.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControllerFactory.kt
index 741f529..d815852 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControllerFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControllerFactory.kt
@@ -35,7 +35,12 @@
return MediaController(context, token)
}
- /** Creates a new [Media3Controller] from a [SessionToken] */
+ /**
+ * Creates a new [Media3Controller] from the media3 [SessionToken].
+ *
+ * @param token The token for the session
+ * @param looper The looper that will be used for this controller's operations
+ */
open suspend fun create(token: SessionToken, looper: Looper): Media3Controller {
return Media3Controller.Builder(context, token)
.setApplicationLooper(looper)
diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
index 36a9fb3..45a3a8c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
@@ -27,17 +27,12 @@
import com.android.systemui.media.controls.ui.controller.MediaHostStatesManager;
import com.android.systemui.media.controls.ui.view.MediaHost;
import com.android.systemui.media.dream.dagger.MediaComplicationComponent;
-import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
-import com.android.systemui.media.taptotransfer.MediaTttFlags;
import com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogBuffer;
import com.android.systemui.media.taptotransfer.sender.MediaTttSenderLogBuffer;
-import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
-import java.util.Optional;
-
import javax.inject.Named;
/** Dagger module for the media package. */
@@ -132,16 +127,4 @@
static LogBuffer provideMediaTttReceiverLogBuffer(LogBufferFactory factory) {
return factory.create("MediaTttReceiver", 20);
}
-
- /** */
- @Provides
- @SysUISingleton
- static Optional<MediaTttCommandLineHelper> providesMediaTttCommandLineHelper(
- MediaTttFlags mediaTttFlags,
- Lazy<MediaTttCommandLineHelper> helperLazy) {
- if (!mediaTttFlags.isMediaTttEnabled()) {
- return Optional.empty();
- }
- return Optional.of(helperLazy.get());
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt
deleted file mode 100644
index 03bc935..0000000
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.media.taptotransfer
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import javax.inject.Inject
-
-/** Flags related to media tap-to-transfer. */
-@SysUISingleton
-class MediaTttFlags @Inject constructor(private val featureFlags: FeatureFlags) {
- /** */
- fun isMediaTttEnabled(): Boolean = featureFlags.isEnabled(Flags.MEDIA_TAP_TO_TRANSFER)
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 92db804..1204cde 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -43,7 +43,6 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
-import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.media.taptotransfer.common.MediaTttIcon
import com.android.systemui.media.taptotransfer.common.MediaTttUtils
import com.android.systemui.res.R
@@ -68,25 +67,27 @@
* TODO(b/245610654): Re-name this to be MediaTttReceiverCoordinator.
*/
@SysUISingleton
-open class MediaTttChipControllerReceiver @Inject constructor(
- private val commandQueue: CommandQueue,
- context: Context,
- logger: MediaTttReceiverLogger,
- viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager,
- @Main mainExecutor: DelayableExecutor,
- accessibilityManager: AccessibilityManager,
- configurationController: ConfigurationController,
- dumpManager: DumpManager,
- powerManager: PowerManager,
- @Main private val mainHandler: Handler,
- private val mediaTttFlags: MediaTttFlags,
- private val uiEventLogger: MediaTttReceiverUiEventLogger,
- private val viewUtil: ViewUtil,
- wakeLockBuilder: WakeLock.Builder,
- systemClock: SystemClock,
- private val rippleController: MediaTttReceiverRippleController,
- private val temporaryViewUiEventLogger: TemporaryViewUiEventLogger,
-) : TemporaryViewDisplayController<ChipReceiverInfo, MediaTttReceiverLogger>(
+open class MediaTttChipControllerReceiver
+@Inject
+constructor(
+ private val commandQueue: CommandQueue,
+ context: Context,
+ logger: MediaTttReceiverLogger,
+ viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager,
+ @Main mainExecutor: DelayableExecutor,
+ accessibilityManager: AccessibilityManager,
+ configurationController: ConfigurationController,
+ dumpManager: DumpManager,
+ powerManager: PowerManager,
+ @Main private val mainHandler: Handler,
+ private val uiEventLogger: MediaTttReceiverUiEventLogger,
+ private val viewUtil: ViewUtil,
+ wakeLockBuilder: WakeLock.Builder,
+ systemClock: SystemClock,
+ private val rippleController: MediaTttReceiverRippleController,
+ private val temporaryViewUiEventLogger: TemporaryViewUiEventLogger,
+) :
+ TemporaryViewDisplayController<ChipReceiverInfo, MediaTttReceiverLogger>(
context,
logger,
viewCaptureAwareWindowManager,
@@ -99,36 +100,43 @@
wakeLockBuilder,
systemClock,
temporaryViewUiEventLogger,
-) {
+ ) {
@SuppressLint("WrongConstant") // We're allowed to use LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
- override val windowLayoutParams = commonWindowLayoutParams.apply {
- gravity = Gravity.BOTTOM.or(Gravity.CENTER_HORIZONTAL)
- // Params below are needed for the ripple to work correctly
- width = WindowManager.LayoutParams.MATCH_PARENT
- height = WindowManager.LayoutParams.MATCH_PARENT
- layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
- fitInsetsTypes = 0 // Ignore insets from all system bars
- }
+ override val windowLayoutParams =
+ commonWindowLayoutParams.apply {
+ gravity = Gravity.BOTTOM.or(Gravity.CENTER_HORIZONTAL)
+ // Params below are needed for the ripple to work correctly
+ width = WindowManager.LayoutParams.MATCH_PARENT
+ height = WindowManager.LayoutParams.MATCH_PARENT
+ layoutInDisplayCutoutMode =
+ WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+ fitInsetsTypes = 0 // Ignore insets from all system bars
+ }
// Value animator that controls the bouncing animation of views.
- private val bounceAnimator = ValueAnimator.ofFloat(0f, 1f).apply {
- repeatCount = ValueAnimator.INFINITE
- repeatMode = ValueAnimator.REVERSE
- duration = ICON_BOUNCE_ANIM_DURATION
- }
-
- private val commandQueueCallbacks = object : CommandQueue.Callbacks {
- override fun updateMediaTapToTransferReceiverDisplay(
- @StatusBarManager.MediaTransferReceiverState displayState: Int,
- routeInfo: MediaRoute2Info,
- appIcon: Icon?,
- appName: CharSequence?
- ) {
- this@MediaTttChipControllerReceiver.updateMediaTapToTransferReceiverDisplay(
- displayState, routeInfo, appIcon, appName
- )
+ private val bounceAnimator =
+ ValueAnimator.ofFloat(0f, 1f).apply {
+ repeatCount = ValueAnimator.INFINITE
+ repeatMode = ValueAnimator.REVERSE
+ duration = ICON_BOUNCE_ANIM_DURATION
}
- }
+
+ private val commandQueueCallbacks =
+ object : CommandQueue.Callbacks {
+ override fun updateMediaTapToTransferReceiverDisplay(
+ @StatusBarManager.MediaTransferReceiverState displayState: Int,
+ routeInfo: MediaRoute2Info,
+ appIcon: Icon?,
+ appName: CharSequence?,
+ ) {
+ this@MediaTttChipControllerReceiver.updateMediaTapToTransferReceiverDisplay(
+ displayState,
+ routeInfo,
+ appIcon,
+ appName,
+ )
+ }
+ }
// A map to store instance id per route info id.
private var instanceMap: MutableMap<String, InstanceId> = mutableMapOf()
@@ -139,7 +147,7 @@
@StatusBarManager.MediaTransferReceiverState displayState: Int,
routeInfo: MediaRoute2Info,
appIcon: Icon?,
- appName: CharSequence?
+ appName: CharSequence?,
) {
val chipState: ChipStateReceiver? = ChipStateReceiver.getReceiverStateFromId(displayState)
val stateName = chipState?.name ?: "Invalid"
@@ -150,8 +158,8 @@
return
}
- val instanceId: InstanceId = instanceMap[routeInfo.id]
- ?: temporaryViewUiEventLogger.getNewInstanceId()
+ val instanceId: InstanceId =
+ instanceMap[routeInfo.id] ?: temporaryViewUiEventLogger.getNewInstanceId()
uiEventLogger.logReceiverStateChange(chipState, instanceId)
if (chipState != ChipStateReceiver.CLOSE_TO_SENDER) {
@@ -175,53 +183,51 @@
}
appIcon.loadDrawableAsync(
- context,
- Icon.OnDrawableLoadedListener { drawable ->
- displayView(
- ChipReceiverInfo(
- routeInfo,
- drawable,
- appName,
- id = routeInfo.id,
- instanceId = instanceId,
- )
+ context,
+ Icon.OnDrawableLoadedListener { drawable ->
+ displayView(
+ ChipReceiverInfo(
+ routeInfo,
+ drawable,
+ appName,
+ id = routeInfo.id,
+ instanceId = instanceId,
)
- },
- // Notify the listener on the main handler since the listener will update
- // the UI.
- mainHandler
+ )
+ },
+ // Notify the listener on the main handler since the listener will update
+ // the UI.
+ mainHandler,
)
}
override fun start() {
super.start()
- if (mediaTttFlags.isMediaTttEnabled()) {
- commandQueue.addCallback(commandQueueCallbacks)
- }
+ commandQueue.addCallback(commandQueueCallbacks)
registerListener(displayListener)
}
override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) {
val packageName: String? = newInfo.routeInfo.clientPackageName
- var iconInfo = MediaTttUtils.getIconInfoFromPackageName(
- context,
- packageName,
- isReceiver = true,
- ) {
- packageName?.let { logger.logPackageNotFound(it) }
- }
+ var iconInfo =
+ MediaTttUtils.getIconInfoFromPackageName(context, packageName, isReceiver = true) {
+ packageName?.let { logger.logPackageNotFound(it) }
+ }
if (newInfo.appNameOverride != null) {
- iconInfo = iconInfo.copy(
- contentDescription = ContentDescription.Loaded(newInfo.appNameOverride.toString())
- )
+ iconInfo =
+ iconInfo.copy(
+ contentDescription =
+ ContentDescription.Loaded(newInfo.appNameOverride.toString())
+ )
}
if (newInfo.appIconDrawableOverride != null) {
- iconInfo = iconInfo.copy(
- icon = MediaTttIcon.Loaded(newInfo.appIconDrawableOverride),
- isAppIcon = true,
- )
+ iconInfo =
+ iconInfo.copy(
+ icon = MediaTttIcon.Loaded(newInfo.appIconDrawableOverride),
+ isAppIcon = true,
+ )
}
val iconPadding =
@@ -298,16 +304,14 @@
alphaDuration: Long = ICON_ALPHA_ANIM_DURATION,
onAnimationEnd: Runnable? = null,
) {
- view.animate()
+ view
+ .animate()
.translationYBy(translationYBy)
.setInterpolator(interpolator)
.setDuration(translationDuration)
.withEndAction { onAnimationEnd?.run() }
.start()
- view.animate()
- .alpha(alphaEndValue)
- .setDuration(alphaDuration)
- .start()
+ view.animate().alpha(alphaEndValue).setDuration(alphaDuration).start()
}
/** Returns the amount that the chip will be translated by in its intro animation. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
index 3e6d46c..6ca0471 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
@@ -28,7 +28,6 @@
import com.android.systemui.common.shared.model.Text
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
-import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.media.taptotransfer.common.MediaTttUtils
import com.android.systemui.res.R
import com.android.systemui.statusbar.CommandQueue
@@ -53,7 +52,6 @@
private val context: Context,
private val dumpManager: DumpManager,
private val logger: MediaTttSenderLogger,
- private val mediaTttFlags: MediaTttFlags,
private val uiEventLogger: MediaTttSenderUiEventLogger,
) : CoreStartable, Dumpable {
@@ -68,27 +66,25 @@
override fun updateMediaTapToTransferSenderDisplay(
@StatusBarManager.MediaTransferSenderState displayState: Int,
routeInfo: MediaRoute2Info,
- undoCallback: IUndoMediaTransferCallback?
+ undoCallback: IUndoMediaTransferCallback?,
) {
this@MediaTttSenderCoordinator.updateMediaTapToTransferSenderDisplay(
displayState,
routeInfo,
- undoCallback
+ undoCallback,
)
}
}
override fun start() {
- if (mediaTttFlags.isMediaTttEnabled()) {
- commandQueue.addCallback(commandQueueCallbacks)
- dumpManager.registerNormalDumpable(this)
- }
+ commandQueue.addCallback(commandQueueCallbacks)
+ dumpManager.registerNormalDumpable(this)
}
private fun updateMediaTapToTransferSenderDisplay(
@StatusBarManager.MediaTransferSenderState displayState: Int,
routeInfo: MediaRoute2Info,
- undoCallback: IUndoMediaTransferCallback?
+ undoCallback: IUndoMediaTransferCallback?,
) {
val chipState: ChipStateSender? = ChipStateSender.getSenderStateFromId(displayState)
val stateName = chipState?.name ?: "Invalid"
@@ -107,7 +103,7 @@
// ChipStateSender.FAR_FROM_RECEIVER is the default state when there is no state.
logger.logInvalidStateTransitionError(
currentState = currentStateForId?.name ?: ChipStateSender.FAR_FROM_RECEIVER.name,
- chipState.name
+ chipState.name,
)
return
}
@@ -126,7 +122,7 @@
// still be able to see the status of the transfer.
logger.logRemovalBypass(
removalReason,
- bypassReason = "transferStatus=${currentStateForId.transferStatus.name}"
+ bypassReason = "transferStatus=${currentStateForId.transferStatus.name}",
)
return
}
@@ -139,14 +135,7 @@
logger.logStateMap(stateMap)
chipbarCoordinator.registerListener(displayListener)
chipbarCoordinator.displayView(
- createChipbarInfo(
- chipState,
- routeInfo,
- undoCallback,
- context,
- logger,
- instanceId,
- )
+ createChipbarInfo(chipState, routeInfo, undoCallback, context, logger, instanceId)
)
}
}
@@ -245,10 +234,7 @@
)
}
- return ChipbarEndItem.Button(
- Text.Resource(R.string.media_transfer_undo),
- onClickListener,
- )
+ return ChipbarEndItem.Button(Text.Resource(R.string.media_transfer_undo), onClickListener)
}
private val displayListener =
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt
index bf2aa7e..56885c3 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt
@@ -18,7 +18,7 @@
import android.annotation.ColorInt
import android.annotation.UserIdInt
-import android.app.ActivityManager.RecentTaskInfo
+import android.app.TaskInfo
import android.content.ComponentName
import com.android.wm.shell.shared.split.SplitBounds
@@ -34,7 +34,7 @@
val splitBounds: SplitBounds?,
) {
constructor(
- taskInfo: RecentTaskInfo,
+ taskInfo: TaskInfo,
isForegroundTask: Boolean,
userType: UserType,
splitBounds: SplitBounds? = null
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt
index 82e58cc..d94424c 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt
@@ -23,7 +23,7 @@
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.kotlin.getOrNull
import com.android.wm.shell.recents.RecentTasks
-import com.android.wm.shell.shared.GroupedRecentTaskInfo
+import com.android.wm.shell.shared.GroupedTaskInfo
import java.util.Optional
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -51,7 +51,7 @@
override suspend fun loadRecentTasks(): List<RecentTask> =
withContext(coroutineDispatcher) {
- val groupedTasks: List<GroupedRecentTaskInfo> = recents?.getTasks() ?: emptyList()
+ val groupedTasks: List<GroupedTaskInfo> = recents?.getTasks() ?: emptyList()
// Note: the returned task list is from the most-recent to least-recent order.
// When opening the app selector in full screen, index 0 will be just the app selector
// activity and a null second task, so the foreground task will be index 1, but when
@@ -86,7 +86,7 @@
}
}
- private suspend fun RecentTasks.getTasks(): List<GroupedRecentTaskInfo> =
+ private suspend fun RecentTasks.getTasks(): List<GroupedTaskInfo> =
suspendCoroutine { continuation ->
getRecentTasks(
Integer.MAX_VALUE,
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
index 47dacae..2fda201 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -57,7 +57,6 @@
import android.view.Window;
import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger;
import com.android.systemui.mediaprojection.MediaProjectionServiceHelper;
import com.android.systemui.mediaprojection.MediaProjectionUtils;
@@ -187,11 +186,9 @@
return;
}
- if (mFeatureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)) {
- if (showScreenCaptureDisabledDialogIfNeeded()) {
- finishAsCancelled();
- return;
- }
+ if (showScreenCaptureDisabledDialogIfNeeded()) {
+ finishAsCancelled();
+ return;
}
final String appName = extractAppName(aInfo, packageManager);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index b019c13..a3b7590 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -406,7 +406,7 @@
if (navBar != null) {
navBar.checkNavBarModes();
} else {
- mTaskbarDelegate.checkNavBarModes();
+ mTaskbarDelegate.checkNavBarModes(displayId);
}
}
@@ -416,7 +416,7 @@
if (navBar != null) {
navBar.finishBarAnimations();
} else {
- mTaskbarDelegate.finishBarAnimations();
+ mTaskbarDelegate.finishBarAnimations(displayId);
}
}
@@ -426,7 +426,7 @@
if (navBar != null) {
navBar.touchAutoDim();
} else {
- mTaskbarDelegate.touchAutoDim();
+ mTaskbarDelegate.touchAutoDim(displayId);
}
}
@@ -436,7 +436,7 @@
if (navBar != null) {
navBar.transitionTo(barMode, animate);
} else {
- mTaskbarDelegate.transitionTo(barMode, animate);
+ mTaskbarDelegate.transitionTo(displayId, barMode, animate);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index 1216a88..2a3aeae 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -159,7 +159,7 @@
private final AutoHideUiElement mAutoHideUiElement = new AutoHideUiElement() {
@Override
public void synchronizeState() {
- checkNavBarModes();
+ checkNavBarModes(mDisplayId);
}
@Override
@@ -220,6 +220,16 @@
mEdgeBackGestureHandler = navBarHelper.getEdgeBackGestureHandler();
}
+ @Override
+ public void onDisplayReady(int displayId) {
+ CommandQueue.Callbacks.super.onDisplayReady(displayId);
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ CommandQueue.Callbacks.super.onDisplayRemoved(displayId);
+ }
+
// Separated into a method to keep setDependencies() clean/readable.
private LightBarTransitionsController createLightBarTransitionsController() {
@@ -349,31 +359,31 @@
}
}
- void checkNavBarModes() {
+ void checkNavBarModes(int displayId) {
if (mOverviewProxyService.getProxy() == null) {
return;
}
try {
- mOverviewProxyService.getProxy().checkNavBarModes();
+ mOverviewProxyService.getProxy().checkNavBarModes(displayId);
} catch (RemoteException e) {
Log.e(TAG, "checkNavBarModes() failed", e);
}
}
- void finishBarAnimations() {
+ void finishBarAnimations(int displayId) {
if (mOverviewProxyService.getProxy() == null) {
return;
}
try {
- mOverviewProxyService.getProxy().finishBarAnimations();
+ mOverviewProxyService.getProxy().finishBarAnimations(displayId);
} catch (RemoteException e) {
Log.e(TAG, "finishBarAnimations() failed", e);
}
}
- void touchAutoDim() {
+ void touchAutoDim(int displayId) {
if (mOverviewProxyService.getProxy() == null) {
return;
}
@@ -382,19 +392,19 @@
int state = mStatusBarStateController.getState();
boolean shouldReset =
state != StatusBarState.KEYGUARD && state != StatusBarState.SHADE_LOCKED;
- mOverviewProxyService.getProxy().touchAutoDim(shouldReset);
+ mOverviewProxyService.getProxy().touchAutoDim(displayId, shouldReset);
} catch (RemoteException e) {
Log.e(TAG, "touchAutoDim() failed", e);
}
}
- void transitionTo(@BarTransitions.TransitionMode int barMode, boolean animate) {
+ void transitionTo(int displayId, @BarTransitions.TransitionMode int barMode, boolean animate) {
if (mOverviewProxyService.getProxy() == null) {
return;
}
try {
- mOverviewProxyService.getProxy().transitionTo(barMode, animate);
+ mOverviewProxyService.getProxy().transitionTo(displayId, barMode, animate);
} catch (RemoteException e) {
Log.e(TAG, "transitionTo() failed, barMode: " + barMode, e);
}
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 53177de..f49693a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -1191,11 +1191,13 @@
}
private void pilferPointers() {
- // Capture inputs
- mInputMonitor.pilferPointers();
- // Notify FalsingManager that an intentional gesture has occurred.
- mFalsingManager.isFalseTouch(BACK_GESTURE);
- mInputEventReceiver.setBatchingEnabled(true);
+ if (mInputMonitor != null) {
+ // Capture inputs
+ mInputMonitor.pilferPointers();
+ // Notify FalsingManager that an intentional gesture has occurred.
+ mFalsingManager.isFalseTouch(BACK_GESTURE);
+ mInputEventReceiver.setBatchingEnabled(true);
+ }
}
private boolean isButtonPressFromTrackpad(MotionEvent ev) {
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index d0f6f79..1fa5baa 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -118,9 +118,7 @@
getUserForHandlingNotesTaking(entryPoint)
}
activityContext.startActivityAsUser(
- Intent(Intent.ACTION_MANAGE_DEFAULT_APP).apply {
- putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NOTES)
- },
+ createNotesRoleHolderSettingsIntent(),
user
)
}
@@ -399,6 +397,10 @@
* @see com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
*/
const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package"
+
+ /** Returns notes role holder settings intent. */
+ fun createNotesRoleHolderSettingsIntent() = Intent(Intent.ACTION_MANAGE_DEFAULT_APP).
+ putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NOTES)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEntryPoint.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEntryPoint.kt
index 4420002..2d62c10 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEntryPoint.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEntryPoint.kt
@@ -44,4 +44,7 @@
/** @see [NoteTaskInitializer.callbacks] */
KEYBOARD_SHORTCUT,
+
+ /** @see [NotesTile] */
+ QS_NOTES_TILE,
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEventLogger.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEventLogger.kt
index a79057e..f152b01 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEventLogger.kt
@@ -19,6 +19,7 @@
import com.android.internal.logging.UiEventLogger
import com.android.systemui.notetask.NoteTaskEntryPoint.APP_CLIPS
import com.android.systemui.notetask.NoteTaskEntryPoint.KEYBOARD_SHORTCUT
+import com.android.systemui.notetask.NoteTaskEntryPoint.QS_NOTES_TILE
import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
import com.android.systemui.notetask.NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT
@@ -43,45 +44,47 @@
/** Logs a [NoteTaskInfo] as an **open** [NoteTaskUiEvent], including package name and uid. */
fun logNoteTaskOpened(info: NoteTaskInfo) {
val event =
- when (info.entryPoint) {
- TAIL_BUTTON -> {
- if (info.isKeyguardLocked) {
- NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED
- } else {
- NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON
- }
+ when (info.entryPoint) {
+ TAIL_BUTTON -> {
+ if (info.isKeyguardLocked) {
+ NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED
+ } else {
+ NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON
}
-
- WIDGET_PICKER_SHORTCUT,
- WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE -> NOTE_OPENED_VIA_SHORTCUT
-
- QUICK_AFFORDANCE -> NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE
- APP_CLIPS,
- KEYBOARD_SHORTCUT,
- null -> return
}
+
+ WIDGET_PICKER_SHORTCUT,
+ WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE -> NOTE_OPENED_VIA_SHORTCUT
+
+ QUICK_AFFORDANCE -> NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE
+ APP_CLIPS,
+ KEYBOARD_SHORTCUT,
+ QS_NOTES_TILE, // TODO(b/376640872): Add logging for QS Tile entry point.
+ null -> return
+ }
uiEventLogger.log(event, info.uid, info.packageName)
}
/** Logs a [NoteTaskInfo] as a **closed** [NoteTaskUiEvent], including package name and uid. */
fun logNoteTaskClosed(info: NoteTaskInfo) {
val event =
- when (info.entryPoint) {
- TAIL_BUTTON -> {
- if (info.isKeyguardLocked) {
- NoteTaskUiEvent.NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON_LOCKED
- } else {
- NoteTaskUiEvent.NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON
- }
+ when (info.entryPoint) {
+ TAIL_BUTTON -> {
+ if (info.isKeyguardLocked) {
+ NoteTaskUiEvent.NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON_LOCKED
+ } else {
+ NoteTaskUiEvent.NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON
}
-
- WIDGET_PICKER_SHORTCUT,
- WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE,
- QUICK_AFFORDANCE,
- APP_CLIPS,
- KEYBOARD_SHORTCUT,
- null -> return
}
+
+ WIDGET_PICKER_SHORTCUT,
+ WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE,
+ QUICK_AFFORDANCE,
+ APP_CLIPS,
+ KEYBOARD_SHORTCUT,
+ QS_NOTES_TILE,
+ null -> return
+ }
uiEventLogger.log(event, info.uid, info.packageName)
}
@@ -90,19 +93,20 @@
@UiEvent(doc = "User opened a note by tapping on the lockscreen shortcut.")
NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE(1294),
-
- @UiEvent(doc = "User opened a note by pressing the stylus tail button while the screen was unlocked.") // ktlint-disable max-line-length
+ @UiEvent(
+ doc =
+ "User opened a note by pressing the stylus tail button while the screen was unlocked."
+ )
NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON(1295),
-
- @UiEvent(doc = "User opened a note by pressing the stylus tail button while the screen was locked.") // ktlint-disable max-line-length
+ @UiEvent(
+ doc =
+ "User opened a note by pressing the stylus tail button while the screen was locked."
+ )
NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED(1296),
-
@UiEvent(doc = "User opened a note by tapping on an app shortcut.")
NOTE_OPENED_VIA_SHORTCUT(1297),
-
@UiEvent(doc = "Note closed via a tail button while device is unlocked")
NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON(1311),
-
@UiEvent(doc = "Note closed via a tail button while device is locked")
NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON_LOCKED(1312);
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
index c7aae3c..a1c5c9c 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
@@ -27,11 +27,27 @@
import com.android.systemui.notetask.quickaffordance.NoteTaskQuickAffordanceModule
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tiles.NotesTile
+import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.impl.notes.domain.NotesTileMapper
+import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileDataInteractor
+import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.res.R
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
+import dagger.multibindings.StringKey
/** Compose all dependencies required by Note Task feature. */
@Module(includes = [NoteTaskQuickAffordanceModule::class])
@@ -54,8 +70,22 @@
@[Binds IntoMap ClassKey(CreateNoteTaskShortcutActivity::class)]
fun bindNoteTaskShortcutActivity(activity: CreateNoteTaskShortcutActivity): Activity
+ @Binds
+ @IntoMap
+ @StringKey(NOTES_TILE_SPEC)
+ fun provideNotesAvailabilityInteractor(
+ impl: NotesTileDataInteractor
+ ): QSTileAvailabilityInteractor
+
+ @Binds
+ @IntoMap
+ @StringKey(NotesTile.TILE_SPEC)
+ fun bindNotesTile(notesTile: NotesTile): QSTileImpl<*>
+
companion object {
+ const val NOTES_TILE_SPEC = "notes"
+
@[Provides NoteTaskEnabledKey]
fun provideIsNoteTaskEnabled(
featureFlags: FeatureFlags,
@@ -65,5 +95,37 @@
val isFeatureEnabled = featureFlags.isEnabled(Flags.NOTE_TASKS)
return isRoleAvailable && isFeatureEnabled
}
+
+ /** Inject NotesTile into tileViewModelMap in QSModule */
+ @Provides
+ @IntoMap
+ @StringKey(NOTES_TILE_SPEC)
+ fun provideNotesTileViewModel(
+ factory: QSTileViewModelFactory.Static<NotesTileModel>,
+ mapper: NotesTileMapper,
+ stateInteractor: NotesTileDataInteractor,
+ userActionInteractor: NotesTileUserActionInteractor,
+ ): QSTileViewModel =
+ factory.create(
+ TileSpec.create(NOTES_TILE_SPEC),
+ userActionInteractor,
+ stateInteractor,
+ mapper,
+ )
+
+ @Provides
+ @IntoMap
+ @StringKey(NOTES_TILE_SPEC)
+ fun provideNotesTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(NOTES_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.ic_qs_notes,
+ labelRes = R.string.quick_settings_notes_label,
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModel.kt
index 63bfbd1..195b0ce 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayActionsViewModel.kt
@@ -18,7 +18,6 @@
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.UserActionResult.HideOverlay
@@ -38,7 +37,7 @@
mapOf(
Swipe.Up to HideOverlay(Overlays.NotificationsShade),
Back to HideOverlay(Overlays.NotificationsShade),
- Swipe(direction = SwipeDirection.Down, fromSource = SceneContainerEdge.TopRight) to
+ Swipe.Down(fromSource = SceneContainerEdge.TopRight) to
ReplaceByOverlay(Overlays.QuickSettingsShade),
)
)
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
index 7178d09..4fe6337 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
@@ -16,19 +16,23 @@
package com.android.systemui.notifications.ui.viewmodel
+import androidx.compose.runtime.getValue
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
+import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
-import com.android.app.tracing.coroutines.launchTraced as launch
/**
* Models UI state used to render the content of the notifications shade overlay.
@@ -43,10 +47,32 @@
val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
val sceneInteractor: SceneInteractor,
private val shadeInteractor: ShadeInteractor,
+ activeNotificationsInteractor: ActiveNotificationsInteractor,
) : ExclusiveActivatable() {
+ private val hydrator = Hydrator("NotificationsShadeOverlayContentViewModel.hydrator")
+
+ val showHeader: Boolean by
+ hydrator.hydratedStateOf(
+ traceName = "showHeader",
+ initialValue =
+ shouldShowHeader(
+ isShadeLayoutWide = shadeInteractor.isShadeLayoutWide.value,
+ areAnyNotificationsPresent =
+ activeNotificationsInteractor.areAnyNotificationsPresentValue,
+ ),
+ source =
+ combine(
+ shadeInteractor.isShadeLayoutWide,
+ activeNotificationsInteractor.areAnyNotificationsPresent,
+ this::shouldShowHeader,
+ ),
+ )
+
override suspend fun onActivated(): Nothing {
coroutineScope {
+ launch { hydrator.activate() }
+
launch {
sceneInteractor.currentScene.collect { currentScene ->
when (currentScene) {
@@ -77,6 +103,13 @@
shadeInteractor.collapseNotificationsShade(loggingReason = "shade scrim clicked")
}
+ private fun shouldShowHeader(
+ isShadeLayoutWide: Boolean,
+ areAnyNotificationsPresent: Boolean,
+ ): Boolean {
+ return !isShadeLayoutWide && areAnyNotificationsPresent
+ }
+
@AssistedFactory
interface Factory {
fun create(): NotificationsShadeOverlayContentViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModel.kt
index 11854d9..398ace4 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeUserActionsViewModel.kt
@@ -18,7 +18,6 @@
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.UserActionResult.ReplaceByOverlay
@@ -40,7 +39,7 @@
mapOf(
Back to SceneFamilies.Home,
Swipe.Up to SceneFamilies.Home,
- Swipe(direction = SwipeDirection.Down, fromSource = SceneContainerEdge.TopRight) to
+ Swipe.Down(fromSource = SceneContainerEdge.TopRight) to
ReplaceByOverlay(Overlays.QuickSettingsShade),
)
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index a1071907..2a5ffc6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -27,6 +27,7 @@
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.content.pm.UserInfo
+import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.os.IBinder
import android.os.PowerExemptionManager
@@ -54,6 +55,7 @@
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.Dumpable
+import com.android.systemui.Flags;
import com.android.systemui.res.R
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogTransitionAnimator
@@ -137,7 +139,7 @@
@SysUISingleton
class FgsManagerControllerImpl @Inject constructor(
- private val context: Context,
+ @Main private val resources: Resources,
@Main private val mainExecutor: Executor,
@Background private val backgroundExecutor: Executor,
private val systemClock: SystemClock,
@@ -223,6 +225,14 @@
private val userVisibleJobObserver = UserVisibleJobObserver()
+ private val stoppableApps by lazy { resources
+ .getStringArray(com.android.internal.R.array.stoppable_fgs_system_apps)
+ }
+
+ private val vendorStoppableApps by lazy { resources
+ .getStringArray(com.android.internal.R.array.vendor_stoppable_fgs_system_apps)
+ }
+
override fun init() {
synchronized(lock) {
if (initialized) {
@@ -725,9 +735,22 @@
}
else -> UIControl.NORMAL
}
+ // If the app wants to be a good citizen by being stoppable, even if the category it
+ // belongs to is exempted for background restriction, let it be stoppable by user.
+ if (Flags.stoppableFgsSystemApp()) {
+ if (isStoppableApp(packageName)) {
+ uiControl = UIControl.NORMAL
+ }
+ }
+
uiControlInitialized = true
}
+ fun isStoppableApp(packageName: String): Boolean {
+ return stoppableApps.contains(packageName) ||
+ vendorStoppableApps.contains(packageName)
+ }
+
override fun equals(other: Any?): Boolean {
if (other !is UserPackage) {
return false
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index bacff99..51ff598 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -31,6 +31,7 @@
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
+import androidx.annotation.VisibleForTesting
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
@@ -41,14 +42,14 @@
import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.navigationBars
+import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.offset
-import androidx.compose.foundation.layout.windowInsetsPadding
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
@@ -59,6 +60,7 @@
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.PointerEventPass
@@ -75,7 +77,6 @@
import androidx.compose.ui.semantics.customActions
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.IntOffset
-import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round
import androidx.compose.ui.util.fastRoundToInt
import androidx.compose.ui.viewinterop.AndroidView
@@ -97,6 +98,7 @@
import com.android.compose.modifiers.thenIf
import com.android.compose.theme.PlatformTheme
import com.android.systemui.Dumpable
+import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.dump.DumpManager
import com.android.systemui.lifecycle.repeatWhenAttached
@@ -107,6 +109,7 @@
import com.android.systemui.qs.composefragment.SceneKeys.QuickQuickSettings
import com.android.systemui.qs.composefragment.SceneKeys.QuickSettings
import com.android.systemui.qs.composefragment.SceneKeys.toIdleSceneKey
+import com.android.systemui.qs.composefragment.ui.GridAnchor
import com.android.systemui.qs.composefragment.ui.NotificationScrimClipParams
import com.android.systemui.qs.composefragment.ui.notificationScrimClip
import com.android.systemui.qs.composefragment.ui.quickQuickSettingsToQuickSettings
@@ -115,8 +118,8 @@
import com.android.systemui.qs.footer.ui.compose.FooterActions
import com.android.systemui.qs.panels.ui.compose.EditMode
import com.android.systemui.qs.panels.ui.compose.QuickQuickSettings
+import com.android.systemui.qs.panels.ui.compose.TileGrid
import com.android.systemui.qs.shared.ui.ElementKeys
-import com.android.systemui.qs.ui.composable.QuickSettingsLayout
import com.android.systemui.qs.ui.composable.QuickSettingsShade
import com.android.systemui.qs.ui.composable.QuickSettingsTheme
import com.android.systemui.res.R
@@ -195,6 +198,7 @@
val context = inflater.context
val composeView =
ComposeView(context).apply {
+ id = R.id.quick_settings_container
repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.CREATED) {
setViewTreeOnBackPressedDispatcherOwner(
@@ -239,7 +243,6 @@
visible = viewModel.isQsVisible,
modifier =
Modifier.graphicsLayer { alpha = viewModel.viewAlpha }
- .windowInsetsPadding(WindowInsets.navigationBars)
// Clipping before translation to match QSContainerImpl.onDraw
.offset {
IntOffset(x = 0, y = viewModel.viewTranslationY.fastRoundToInt())
@@ -299,7 +302,7 @@
transitions =
transitions {
from(QuickQuickSettings, QuickSettings) {
- quickQuickSettingsToQuickSettings(viewModel::inFirstPage::get)
+ quickQuickSettingsToQuickSettings(viewModel::animateTilesExpansion::get)
}
},
)
@@ -596,8 +599,21 @@
}
.padding(top = { qqsPadding }, bottom = { bottomPadding })
) {
+ val Tiles =
+ @Composable {
+ QuickQuickSettings(
+ viewModel = viewModel.containerViewModel.quickQuickSettingsViewModel
+ )
+ }
+ val Media =
+ @Composable {
+ if (viewModel.qqsMediaVisible) {
+ MediaObject(mediaHost = viewModel.qqsMediaHost)
+ }
+ }
+
if (viewModel.isQsEnabled) {
- Column(
+ Box(
modifier =
Modifier.collapseExpandSemanticAction(
stringResource(
@@ -608,16 +624,13 @@
horizontal = {
QuickSettingsShade.Dimensions.Padding.roundToPx()
}
- ),
- verticalArrangement =
- spacedBy(dimensionResource(R.dimen.qs_tile_margin_vertical)),
+ )
) {
- QuickQuickSettings(
- viewModel = viewModel.containerViewModel.quickQuickSettingsViewModel
+ QuickQuickSettingsLayout(
+ tiles = Tiles,
+ media = Media,
+ mediaInRow = viewModel.qqsMediaInRow,
)
- if (viewModel.qqsMediaVisible) {
- MediaObject(mediaHost = viewModel.qqsMediaHost)
- }
}
}
}
@@ -657,23 +670,58 @@
.verticalScroll(scrollState)
.sysuiResTag(ResIdTags.qsScroll)
) {
+ val containerViewModel = viewModel.containerViewModel
Spacer(
modifier = Modifier.height { qqsPadding + qsExtraPadding.roundToPx() }
)
- QuickSettingsLayout(
- viewModel = viewModel.containerViewModel,
- modifier = Modifier.sysuiResTag(ResIdTags.quickSettingsPanel),
- )
- Spacer(modifier = Modifier.height(8.dp))
- if (viewModel.qsMediaVisible) {
- MediaObject(
- mediaHost = viewModel.qsMediaHost,
- modifier =
- Modifier.padding(
- horizontal = {
- QuickSettingsShade.Dimensions.Padding.roundToPx()
- }
- ),
+ val BrightnessSlider =
+ @Composable {
+ BrightnessSliderContainer(
+ viewModel = containerViewModel.brightnessSliderViewModel,
+ modifier =
+ Modifier.fillMaxWidth()
+ .height(
+ QuickSettingsShade.Dimensions.BrightnessSliderHeight
+ ),
+ )
+ }
+ val TileGrid =
+ @Composable {
+ Box {
+ GridAnchor()
+ TileGrid(
+ viewModel = containerViewModel.tileGridViewModel,
+ modifier =
+ Modifier.fillMaxWidth()
+ .heightIn(
+ max =
+ QuickSettingsShade.Dimensions.GridMaxHeight
+ ),
+ containerViewModel.editModeViewModel::startEditing,
+ )
+ }
+ }
+ val Media =
+ @Composable {
+ if (viewModel.qsMediaVisible) {
+ MediaObject(mediaHost = viewModel.qsMediaHost)
+ }
+ }
+ Box(
+ modifier =
+ Modifier.fillMaxWidth()
+ .sysuiResTag(ResIdTags.quickSettingsPanel)
+ .padding(
+ top = QuickSettingsShade.Dimensions.Padding,
+ start = QuickSettingsShade.Dimensions.Padding,
+ end = QuickSettingsShade.Dimensions.Padding,
+ )
+ ) {
+ QuickSettingsLayout(
+ brightness = BrightnessSlider,
+ tiles = TileGrid,
+ media = Media,
+ mediaInRow = viewModel.qsMediaInRow,
)
}
}
@@ -957,6 +1005,63 @@
}
}
+@Composable
+@VisibleForTesting
+fun QuickQuickSettingsLayout(
+ tiles: @Composable () -> Unit,
+ media: @Composable () -> Unit,
+ mediaInRow: Boolean,
+) {
+ if (mediaInRow) {
+ Row(
+ horizontalArrangement = spacedBy(dimensionResource(R.dimen.qs_tile_margin_vertical)),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Box(modifier = Modifier.weight(1f)) { tiles() }
+ Box(modifier = Modifier.weight(1f)) { media() }
+ }
+ } else {
+ Column(verticalArrangement = spacedBy(dimensionResource(R.dimen.qs_tile_margin_vertical))) {
+ tiles()
+ media()
+ }
+ }
+}
+
+@Composable
+@VisibleForTesting
+fun QuickSettingsLayout(
+ brightness: @Composable () -> Unit,
+ tiles: @Composable () -> Unit,
+ media: @Composable () -> Unit,
+ mediaInRow: Boolean,
+) {
+ if (mediaInRow) {
+ Column(
+ verticalArrangement = spacedBy(QuickSettingsShade.Dimensions.Padding),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ brightness()
+ Row(
+ horizontalArrangement = spacedBy(QuickSettingsShade.Dimensions.Padding),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Box(modifier = Modifier.weight(1f)) { tiles() }
+ Box(modifier = Modifier.weight(1f)) { media() }
+ }
+ }
+ } else {
+ Column(
+ verticalArrangement = spacedBy(QuickSettingsShade.Dimensions.Padding),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ brightness()
+ tiles()
+ media()
+ }
+ }
+}
+
private object ResIdTags {
const val quickSettingsPanel = "quick_settings_panel"
const val quickQsPanel = "quick_qs_panel"
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
index 5127320..676f6a4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
@@ -19,6 +19,7 @@
import android.content.Context
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.util.Utils
import dagger.Module
import dagger.Provides
@@ -34,7 +35,7 @@
@SysUISingleton
@Named(QS_USING_MEDIA_PLAYER)
fun providesUsingMedia(@Application context: Context): Boolean {
- return Utils.useQsMediaPlayer(context)
+ return QSComposeFragment.isEnabled && Utils.useQsMediaPlayer(context)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/ui/FromQuickQuickSettingsToQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/ui/FromQuickQuickSettingsToQuickSettings.kt
index 9e3945e..c1a4174 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/ui/FromQuickQuickSettingsToQuickSettings.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/ui/FromQuickQuickSettingsToQuickSettings.kt
@@ -20,7 +20,9 @@
import com.android.systemui.qs.composefragment.SceneKeys
import com.android.systemui.qs.shared.ui.ElementKeys
-fun TransitionBuilder.quickQuickSettingsToQuickSettings(inFirstPage: () -> Boolean = { true }) {
+fun TransitionBuilder.quickQuickSettingsToQuickSettings(
+ animateTilesExpansion: () -> Boolean = { true }
+) {
fractionRange(start = 0.5f) { fade(ElementKeys.QuickSettingsContent) }
@@ -28,7 +30,7 @@
anchoredTranslate(ElementKeys.QuickSettingsContent, ElementKeys.GridAnchor)
- sharedElement(ElementKeys.TileElementMatcher, enabled = inFirstPage())
+ sharedElement(ElementKeys.TileElementMatcher, enabled = animateTilesExpansion())
// This will animate between 0f (QQS) and 0.6, fading in the QQS tiles when coming back
// from non first page QS. The QS content ends fading out at 0.5f, so there's a brief
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
index 0ca621d..624cf30 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
@@ -39,6 +39,8 @@
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QQS
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.dagger.MediaModule.QS_PANEL
@@ -49,10 +51,12 @@
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.panels.domain.interactor.TileSquishinessInteractor
import com.android.systemui.qs.panels.ui.viewmodel.InFirstPageViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.MediaInRowInLandscapeViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.LargeScreenHeaderHelper
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
@@ -90,10 +94,11 @@
disableFlagsRepository: DisableFlagsRepository,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val largeScreenShadeInterpolator: LargeScreenShadeInterpolator,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
private val largeScreenHeaderHelper: LargeScreenHeaderHelper,
private val squishinessInteractor: TileSquishinessInteractor,
private val inFirstPageViewModel: InFirstPageViewModel,
+ mediaInRowInLandscapeViewModelFactory: MediaInRowInLandscapeViewModel.Factory,
@Named(QUICK_QS_PANEL) val qqsMediaHost: MediaHost,
@Named(QS_PANEL) val qsMediaHost: MediaHost,
@Named(QSFragmentComposeModule.QS_USING_MEDIA_PLAYER) private val usingMedia: Boolean,
@@ -101,6 +106,8 @@
) : Dumpable, ExclusiveActivatable() {
val containerViewModel = containerViewModelFactory.create(true)
+ private val qqsMediaInRowViewModel = mediaInRowInLandscapeViewModelFactory.create(LOCATION_QQS)
+ private val qsMediaInRowViewModel = mediaInRowInLandscapeViewModelFactory.create(LOCATION_QS)
private val hydrator = Hydrator("QSFragmentComposeViewModel.hydrator")
@@ -195,7 +202,7 @@
}
}
- val isQsFullyExpanded by derivedStateOf { expansionState.progress >= 1f }
+ val isQsFullyExpanded by derivedStateOf { expansionState.progress >= 1f && isQsExpanded }
/**
* Accessibility action for collapsing/expanding QS. The provided runnable is responsible for
@@ -203,9 +210,6 @@
*/
var collapseExpandAccessibilityAction: Runnable? = null
- val inFirstPage: Boolean
- get() = inFirstPageViewModel.inFirstPage
-
var overScrollAmount by mutableStateOf(0)
val viewTranslationY by derivedStateOf {
@@ -252,6 +256,9 @@
},
)
+ val qqsMediaInRow: Boolean
+ get() = qqsMediaInRowViewModel.shouldMediaShowInRow
+
val qsMediaVisible by
hydrator.hydratedStateOf(
traceName = "qsMediaVisible",
@@ -259,6 +266,18 @@
source = if (usingMedia) mediaHostVisible(qsMediaHost) else flowOf(false),
)
+ val qsMediaInRow: Boolean
+ get() = qsMediaInRowViewModel.shouldMediaShowInRow
+
+ val animateTilesExpansion: Boolean
+ get() = inFirstPage && !mediaSuddenlyAppearingInLandscape
+
+ private val inFirstPage: Boolean
+ get() = inFirstPageViewModel.inFirstPage
+
+ private val mediaSuddenlyAppearingInLandscape: Boolean
+ get() = !qqsMediaInRow && qsMediaInRow
+
private var qsBounds by mutableStateOf(Rect())
private val constrainedSquishinessFraction: Float
@@ -362,6 +381,8 @@
launch { hydrateSquishinessInteractor() }
launch { hydrator.activate() }
launch { containerViewModel.activate() }
+ launch { qqsMediaInRowViewModel.activate() }
+ launch { qsMediaInRowViewModel.activate() }
awaitCancellation()
}
}
@@ -391,6 +412,7 @@
println("isQSVisible", isQsVisible)
println("isQSEnabled", isQsEnabled)
println("isCustomizing", containerViewModel.editModeViewModel.isEditing.value)
+ println("inFirstPage", inFirstPage)
}
printSection("Expansion state") {
println("qsExpansion", qsExpansion)
@@ -423,7 +445,9 @@
}
printSection("Media") {
println("qqsMediaVisible", qqsMediaVisible)
+ println("qqsMediaInRow", qqsMediaInRow)
println("qsMediaVisible", qsMediaVisible)
+ println("qsMediaInRow", qsMediaInRow)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
index 43fd0f5..1f55ac7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
@@ -35,8 +35,6 @@
import com.android.systemui.qs.panels.ui.compose.infinitegrid.InfiniteGridLayout
import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModelImpl
-import com.android.systemui.qs.panels.ui.viewmodel.QSColumnsSizeViewModelImpl
-import com.android.systemui.qs.panels.ui.viewmodel.QSColumnsViewModel
import dagger.Binds
import dagger.Module
import dagger.Provides
@@ -58,8 +56,6 @@
@Binds fun bindIconTilesViewModel(impl: IconTilesViewModelImpl): IconTilesViewModel
- @Binds fun bindQSColumnsViewModel(impl: QSColumnsSizeViewModelImpl): QSColumnsViewModel
-
@Binds
@PaginatedBaseLayoutType
fun bindPaginatedBaseGridLayout(impl: InfiniteGridLayout): PaginatableGridLayout
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
index 6cc2cbc..2efe500 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
@@ -73,7 +73,7 @@
tiles.forEach { it.startListening(token) }
onDispose { tiles.forEach { it.stopListening(token) } }
}
- val columns by viewModel.columns
+ val columns = viewModel.columns
val rows = viewModel.rows
val pages =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
index 19ab29e..5ac2ad0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
@@ -30,6 +30,7 @@
import com.android.systemui.grid.ui.compose.VerticalSpannedGrid
import com.android.systemui.haptics.msdl.qs.TileHapticsViewModelFactoryProvider
import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.ui.compose.PaginatableGridLayout
import com.android.systemui.qs.panels.ui.compose.bounceableInfo
@@ -72,7 +73,12 @@
rememberViewModel(traceName = "InfiniteGridLayout.TileGrid") {
viewModel.dynamicIconTilesViewModelFactory.create()
}
- val columns by viewModel.gridSizeViewModel.columns
+ val columnsWithMediaViewModel =
+ rememberViewModel(traceName = "InfiniteGridLAyout.TileGrid") {
+ viewModel.columnsWithMediaViewModelFactory.create(LOCATION_QS)
+ }
+
+ val columns = columnsWithMediaViewModel.columns
val sizedTiles = tiles.map { SizedTileImpl(it, it.spec.width()) }
val bounceables =
remember(sizedTiles) { List(sizedTiles.size) { BounceableTileViewModel() } }
@@ -118,7 +124,11 @@
rememberViewModel(traceName = "InfiniteGridLayout.EditTileGrid") {
viewModel.dynamicIconTilesViewModelFactory.create()
}
- val columns by viewModel.gridSizeViewModel.columns
+ val columnsViewModel =
+ rememberViewModel(traceName = "InfiniteGridLayout.EditTileGrid") {
+ viewModel.columnsWithMediaViewModelFactory.createWithoutMediaTracking()
+ }
+ val columns = columnsViewModel.columns
val largeTiles by iconTilesViewModel.largeTiles.collectAsStateWithLifecycle()
// Non-current tiles should always be displayed as icon tiles.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
index 7fe856b..4e34e73 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
@@ -30,6 +30,7 @@
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor.Companion.POSITION_AT_END
import com.android.systemui.qs.pipeline.domain.interactor.MinimumTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.util.kotlin.emitOnStart
import javax.inject.Inject
import javax.inject.Named
@@ -54,7 +55,7 @@
private val currentTilesInteractor: CurrentTilesInteractor,
private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
private val minTilesInteractor: MinimumTilesInteractor,
- private val configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
@Application private val applicationContext: Context,
@Named("Default") private val defaultGridLayout: GridLayout,
@Application private val applicationScope: CoroutineScope,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt
index d687100..3327141 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt
@@ -16,7 +16,6 @@
package com.android.systemui.qs.panels.ui.viewmodel
-import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.qs.panels.ui.dialog.QSResetDialogDelegate
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -25,19 +24,15 @@
@AssistedInject
constructor(
val dynamicIconTilesViewModelFactory: DynamicIconTilesViewModel.Factory,
- val gridSizeViewModel: QSColumnsViewModel,
+ val columnsWithMediaViewModelFactory: QSColumnsViewModel.Factory,
val squishinessViewModel: TileSquishinessViewModel,
private val resetDialogDelegate: QSResetDialogDelegate,
-) : ExclusiveActivatable() {
+) {
fun showResetDialog() {
resetDialogDelegate.showDialog()
}
- override suspend fun onActivated(): Nothing {
- gridSizeViewModel.activate()
- }
-
@AssistedFactory
interface Factory {
fun create(): InfiniteGridViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModel.kt
new file mode 100644
index 0000000..2ed8fd2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModel.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.panels.ui.viewmodel
+
+import android.content.res.Configuration
+import android.content.res.Resources
+import androidx.compose.runtime.getValue
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.media.controls.ui.controller.MediaHostStatesManager
+import com.android.systemui.media.controls.ui.controller.MediaLocation
+import com.android.systemui.media.controls.ui.view.MediaHostState
+import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
+import com.android.systemui.shade.shared.model.ShadeMode
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import javax.inject.Named
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+
+/**
+ * Indicates whether a particular UMO in [LOCATION_QQS] or [LOCATION_QS] should currently show in a
+ * row with the tiles, based on its visibility and device configuration. If the player is not
+ * visible, it will never indicate that media should show in row.
+ */
+class MediaInRowInLandscapeViewModel
+@AssistedInject
+constructor(
+ @Main resources: Resources,
+ configurationInteractor: ConfigurationInteractor,
+ shadeModeInteractor: ShadeModeInteractor,
+ private val mediaHostStatesManager: MediaHostStatesManager,
+ @Named(QSFragmentComposeModule.QS_USING_MEDIA_PLAYER) private val usingMedia: Boolean,
+ @Assisted @MediaLocation private val inLocation: Int,
+) : ExclusiveActivatable() {
+
+ private val hydrator = Hydrator("MediaInRowInLanscapeViewModel - $inLocation")
+
+ val shouldMediaShowInRow: Boolean
+ get() = usingMedia && inSingleShade && isLandscapeAndLong && isMediaVisible
+
+ private val inSingleShade: Boolean by
+ hydrator.hydratedStateOf(
+ traceName = "inSingleShade",
+ initialValue = shadeModeInteractor.shadeMode.value == ShadeMode.Single,
+ source = shadeModeInteractor.shadeMode.map { it == ShadeMode.Single },
+ )
+
+ private val isLandscapeAndLong: Boolean by
+ hydrator.hydratedStateOf(
+ traceName = "isLandscapeAndLong",
+ initialValue = resources.configuration.isLandscapeAndLong,
+ source = configurationInteractor.configurationValues.map { it.isLandscapeAndLong },
+ )
+
+ private val isMediaVisible by
+ hydrator.hydratedStateOf(
+ traceName = "isMediaVisible",
+ initialValue = false,
+ source =
+ conflatedCallbackFlow {
+ val callback =
+ object : MediaHostStatesManager.Callback {
+ override fun onHostStateChanged(
+ location: Int,
+ mediaHostState: MediaHostState,
+ ) {
+ if (location == inLocation) {
+ trySend(mediaHostState.visible)
+ }
+ }
+ }
+ mediaHostStatesManager.addCallback(callback)
+
+ awaitClose { mediaHostStatesManager.removeCallback(callback) }
+ }
+ .onStart {
+ emit(
+ mediaHostStatesManager.mediaHostStates.get(inLocation)?.visible ?: false
+ )
+ },
+ )
+
+ override suspend fun onActivated(): Nothing {
+ hydrator.activate()
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(@MediaLocation inLocation: Int): MediaInRowInLandscapeViewModel
+ }
+}
+
+private val Configuration.isLandscapeAndLong: Boolean
+ get() =
+ orientation == Configuration.ORIENTATION_LANDSCAPE &&
+ (screenLayout and Configuration.SCREENLAYOUT_LONG_MASK) ==
+ Configuration.SCREENLAYOUT_LONG_YES
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
index 8bd9ed0..e5607eb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
@@ -16,10 +16,10 @@
package com.android.systemui.qs.panels.ui.viewmodel
-import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
import com.android.systemui.qs.panels.domain.interactor.PaginatedGridInteractor
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -31,12 +31,13 @@
@AssistedInject
constructor(
iconTilesViewModel: IconTilesViewModel,
- private val gridSizeViewModel: QSColumnsViewModel,
+ columnsWithMediaViewModelFactory: QSColumnsViewModel.Factory,
paginatedGridInteractor: PaginatedGridInteractor,
inFirstPageViewModel: InFirstPageViewModel,
) : IconTilesViewModel by iconTilesViewModel, ExclusiveActivatable() {
private val hydrator = Hydrator("PaginatedGridViewModel")
+ private val columnsWithMediaViewModel = columnsWithMediaViewModelFactory.create(LOCATION_QS)
val rows by
hydrator.hydratedStateOf(
@@ -47,13 +48,13 @@
var inFirstPage by inFirstPageViewModel::inFirstPage
- val columns: State<Int>
- get() = gridSizeViewModel.columns
+ val columns: Int
+ get() = columnsWithMediaViewModel.columns
override suspend fun onActivated(): Nothing {
coroutineScope {
launch { hydrator.activate() }
- launch { gridSizeViewModel.activate() }
+ launch { columnsWithMediaViewModel.activate() }
awaitCancellation()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModel.kt
index 8926d2f..85b7831 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModel.kt
@@ -16,25 +16,61 @@
package com.android.systemui.qs.panels.ui.viewmodel
-import androidx.compose.runtime.State
-import com.android.systemui.lifecycle.Activatable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.media.controls.ui.controller.MediaLocation
import com.android.systemui.qs.panels.domain.interactor.QSColumnsInteractor
-import javax.inject.Inject
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
-interface QSColumnsViewModel : Activatable {
- val columns: State<Int>
-}
+/**
+ * View model for the number of columns that should be shown in a QS grid.
+ * * Create it with a [MediaLocation] to halve the number of columns when media should show in a row
+ * with the tiles.
+ * * Create it with a `null` [MediaLocation] to ignore media visibility (useful for edit mode).
+ */
+class QSColumnsViewModel
+@AssistedInject
+constructor(
+ interactor: QSColumnsInteractor,
+ mediaInRowInLandscapeViewModelFactory: MediaInRowInLandscapeViewModel.Factory,
+ @Assisted @MediaLocation mediaLocation: Int?,
+) : ExclusiveActivatable() {
-class QSColumnsSizeViewModelImpl @Inject constructor(interactor: QSColumnsInteractor) :
- QSColumnsViewModel, ExclusiveActivatable() {
- private val hydrator = Hydrator("QSColumnsSizeViewModelImpl")
+ private val hydrator = Hydrator("QSColumnsViewModelWithMedia")
- override val columns =
- hydrator.hydratedStateOf(traceName = "columns", source = interactor.columns)
+ val columns by derivedStateOf {
+ if (mediaInRowInLandscapeViewModel?.shouldMediaShowInRow == true) {
+ columnsWithoutMedia / 2
+ } else {
+ columnsWithoutMedia
+ }
+ }
+
+ private val mediaInRowInLandscapeViewModel =
+ mediaLocation?.let { mediaInRowInLandscapeViewModelFactory.create(it) }
+
+ private val columnsWithoutMedia by
+ hydrator.hydratedStateOf(traceName = "columnsWithoutMedia", source = interactor.columns)
override suspend fun onActivated(): Nothing {
- hydrator.activate()
+ coroutineScope {
+ launch { hydrator.activate() }
+ launch { mediaInRowInLandscapeViewModel?.activate() }
+ awaitCancellation()
+ }
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(mediaLocation: Int?): QSColumnsViewModel
+
+ fun createWithoutMediaTracking() = create(null)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
index 0859c86..33ce551 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
@@ -21,6 +21,7 @@
import com.android.systemui.haptics.msdl.qs.TileHapticsViewModelFactoryProvider
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QQS
import com.android.systemui.qs.panels.domain.interactor.QuickQuickSettingsRowInteractor
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.shared.model.splitInRowsSequence
@@ -36,23 +37,35 @@
@AssistedInject
constructor(
tilesInteractor: CurrentTilesInteractor,
- private val qsColumnsViewModel: QSColumnsViewModel,
+ qsColumnsViewModelFactory: QSColumnsViewModel.Factory,
quickQuickSettingsRowInteractor: QuickQuickSettingsRowInteractor,
+ mediaInRowInLandscapeViewModelFactory: MediaInRowInLandscapeViewModel.Factory,
val squishinessViewModel: TileSquishinessViewModel,
iconTilesViewModel: IconTilesViewModel,
val tileHapticsViewModelFactoryProvider: TileHapticsViewModelFactoryProvider,
) : ExclusiveActivatable() {
private val hydrator = Hydrator("QuickQuickSettingsViewModel")
+ private val qsColumnsViewModel = qsColumnsViewModelFactory.create(LOCATION_QQS)
+ private val mediaInRowViewModel = mediaInRowInLandscapeViewModelFactory.create(LOCATION_QQS)
- val columns by qsColumnsViewModel.columns
+ val columns: Int
+ get() = qsColumnsViewModel.columns
private val largeTiles by
hydrator.hydratedStateOf(traceName = "largeTiles", source = iconTilesViewModel.largeTiles)
- private val rows by
+ private val rows: Int
+ get() =
+ if (mediaInRowViewModel.shouldMediaShowInRow) {
+ rowsWithoutMedia * 2
+ } else {
+ rowsWithoutMedia
+ }
+
+ private val rowsWithoutMedia by
hydrator.hydratedStateOf(
- traceName = "rows",
+ traceName = "rowsWithoutMedia",
initialValue = quickQuickSettingsRowInteractor.defaultRows,
source = quickQuickSettingsRowInteractor.rows,
)
@@ -73,6 +86,7 @@
coroutineScope {
launch { hydrator.activate() }
launch { qsColumnsViewModel.activate() }
+ launch { mediaInRowViewModel.activate() }
awaitCancellation()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
index f702da4..c9a0635 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt
@@ -54,6 +54,7 @@
subtitleIdsMap["dream"] = R.array.tile_states_dream
subtitleIdsMap["font_scaling"] = R.array.tile_states_font_scaling
subtitleIdsMap["hearing_devices"] = R.array.tile_states_hearing_devices
+ subtitleIdsMap["notes"] = R.array.tile_states_notes
}
/** Get the subtitle resource id of the given tile */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt
new file mode 100644
index 0000000..69df096
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.tiles
+
+import android.content.Intent
+import android.os.Handler
+import android.os.Looper
+import android.service.quicksettings.Tile
+import com.android.internal.logging.MetricsLogger
+import com.android.systemui.animation.Expandable
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tiles.impl.notes.domain.NotesTileMapper
+import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileDataInteractor
+import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import javax.inject.Inject
+import kotlinx.coroutines.runBlocking
+
+/** Quick settings tile: Notes */
+class NotesTile
+@Inject constructor(
+ private val host: QSHost,
+ private val uiEventLogger: QsEventLogger,
+ @Background private val backgroundLooper: Looper,
+ @Main private val mainHandler: Handler,
+ private val falsingManager: FalsingManager,
+ private val metricsLogger: MetricsLogger,
+ private val statusBarStateController: StatusBarStateController,
+ private val activityStarter: ActivityStarter,
+ private val qsLogger: QSLogger,
+ private val qsTileConfigProvider: QSTileConfigProvider,
+ private val dataInteractor: NotesTileDataInteractor,
+ private val tileMapper: NotesTileMapper,
+ private val userActionInteractor: NotesTileUserActionInteractor,
+) :
+ QSTileImpl<QSTile.State?>(
+ host,
+ uiEventLogger,
+ backgroundLooper,
+ mainHandler,
+ falsingManager,
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ ) {
+
+ private lateinit var tileState: QSTileState
+ private val config = qsTileConfigProvider.getConfig(TILE_SPEC)
+
+ override fun getTileLabel(): CharSequence =
+ mContext.getString(config.uiConfig.labelRes)
+
+ override fun newTileState(): QSTile.State? {
+ return QSTile.State().apply { state = Tile.STATE_INACTIVE }
+ }
+
+ override fun handleClick(expandable: Expandable?) {
+ userActionInteractor.handleClick()
+ }
+
+ override fun getLongClickIntent(): Intent = userActionInteractor.longClickIntent
+
+ override fun handleUpdateState(state: QSTile.State?, arg: Any?) {
+ val model =
+ if (arg is NotesTileModel) arg else dataInteractor.getCurrentTileModel()
+ tileState = tileMapper.map(config, model)
+
+ state?.apply {
+ this.state = tileState.activationState.legacyState
+ icon = ResourceIcon.get(tileState.iconRes ?: R.drawable.ic_qs_notes)
+ label = tileState.label
+ contentDescription = tileState.contentDescription
+ expandedAccessibilityClassName = tileState.expandedAccessibilityClassName
+ }
+ }
+
+ override fun isAvailable(): Boolean {
+ return dataInteractor.isAvailable()
+ }
+
+ companion object {
+ const val TILE_SPEC = "notes"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 284239a..f3be340 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -191,8 +191,7 @@
mPanelInteractor.collapsePanels();
};
- final Dialog dialog = mController.createScreenRecordDialog(mContext, mFlags,
- mDialogTransitionAnimator, mActivityStarter, onStartRecordingClicked);
+ final Dialog dialog = mController.createScreenRecordDialog(onStartRecordingClicked);
ActivityStarter.OnDismissAction dismissAction = () -> {
if (shouldAnimateFromExpandable) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapper.kt
new file mode 100644
index 0000000..ee1b9e5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapper.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.tiles.impl.notes.domain
+
+import android.content.res.Resources
+import android.widget.Button
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+class NotesTileMapper
+@Inject
+constructor(@Main private val resources: Resources, private val theme: Resources.Theme) :
+ QSTileDataToStateMapper<NotesTileModel> {
+ override fun map(config: QSTileConfig, data: NotesTileModel): QSTileState =
+ QSTileState.build(resources, theme, config.uiConfig) {
+ iconRes = R.drawable.ic_qs_notes
+ icon =
+ Icon.Loaded(
+ resources.getDrawable(
+ iconRes!!,
+ theme),
+ contentDescription = null
+ )
+ contentDescription = label
+ activationState = QSTileState.ActivationState.INACTIVE
+ sideViewIcon = QSTileState.SideViewIcon.Chevron
+ supportedActions =
+ setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK)
+ expandedAccessibilityClass = Button::class
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt
new file mode 100644
index 0000000..a501b85
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.tiles.impl.notes.domain.interactor
+
+import android.os.UserHandle
+import com.android.systemui.Flags
+import com.android.systemui.notetask.NoteTaskEnabledKey
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+
+class NotesTileDataInteractor
+@Inject
+constructor(@NoteTaskEnabledKey private val isNoteTaskEnabled: Boolean) :
+ QSTileDataInteractor<NotesTileModel> {
+ override fun tileData(
+ user: UserHandle,
+ triggers: Flow<DataUpdateTrigger>,
+ ): Flow<NotesTileModel> = flowOf(NotesTileModel)
+
+ override fun availability(user: UserHandle): Flow<Boolean> = flowOf(isAvailable())
+
+ fun isAvailable(): Boolean {
+ return Flags.notesRoleQsTile() && isNoteTaskEnabled
+ }
+
+ fun getCurrentTileModel(): NotesTileModel {
+ return NotesTileModel
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt
new file mode 100644
index 0000000..df01d99
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.tiles.impl.notes.domain.interactor
+
+import com.android.systemui.animation.Expandable
+import com.android.systemui.notetask.NoteTaskController
+import com.android.systemui.notetask.NoteTaskEntryPoint
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
+import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.interactor.QSTileInput
+import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import javax.inject.Inject
+
+class NotesTileUserActionInteractor
+@Inject constructor(
+ private val qsTileIntentUserInputHandler: QSTileIntentUserInputHandler,
+ private val panelInteractor: PanelInteractor,
+ private val noteTaskController: NoteTaskController,
+) : QSTileUserActionInteractor<NotesTileModel> {
+ val longClickIntent = NoteTaskController.createNotesRoleHolderSettingsIntent()
+
+ override suspend fun handleInput(input: QSTileInput<NotesTileModel>) {
+ when (input.action) {
+ is QSTileUserAction.Click -> handleClick()
+ is QSTileUserAction.LongClick -> handleLongClick(input.action.expandable)
+ is QSTileUserAction.ToggleClick -> {}
+ }
+ }
+
+ fun handleClick() {
+ noteTaskController.showNoteTask(NoteTaskEntryPoint.QS_NOTES_TILE)
+ panelInteractor.collapsePanels()
+ }
+
+ fun handleLongClick(expandable: Expandable?) {
+ qsTileIntentUserInputHandler.handle(expandable, longClickIntent)
+ }
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/model/NotesTileModel.kt
similarity index 82%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/model/NotesTileModel.kt
index e21bf8f..b72aa60 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/model/NotesTileModel.kt
@@ -14,6 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package com.android.systemui.qs.tiles.impl.notes.domain.model
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+/** NotesTileModel tile model. */
+data object NotesTileModel
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
index 48b39ed..85aa674 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
@@ -16,16 +16,13 @@
package com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor
-import android.content.Context
import android.util.Log
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.animation.Expandable
-import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
import com.android.systemui.plugins.ActivityStarter
@@ -45,7 +42,6 @@
class ScreenRecordTileUserActionInteractor
@Inject
constructor(
- @Application private val context: Context,
@Main private val mainContext: CoroutineContext,
@Background private val backgroundContext: CoroutineContext,
private val screenRecordRepository: ScreenRecordRepository,
@@ -55,8 +51,6 @@
private val dialogTransitionAnimator: DialogTransitionAnimator,
private val panelInteractor: PanelInteractor,
private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
- private val featureFlags: FeatureFlagsClassic,
- private val activityStarter: ActivityStarter,
) : QSTileUserActionInteractor<ScreenRecordModel> {
override suspend fun handleInput(input: QSTileInput<ScreenRecordModel>): Unit =
with(input) {
@@ -89,14 +83,7 @@
panelInteractor.collapsePanels()
}
- val dialog =
- recordingController.createScreenRecordDialog(
- context,
- featureFlags,
- dialogTransitionAnimator,
- activityStarter,
- onStartRecordingClicked
- )
+ val dialog = recordingController.createScreenRecordDialog(onStartRecordingClicked)
if (dialog == null) {
Log.w(TAG, "showPrompt: dialog was null")
@@ -115,7 +102,7 @@
expandable?.dialogTransitionController(
DialogCuj(
InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
- INTERACTION_JANK_TAG
+ INTERACTION_JANK_TAG,
)
)
controller?.let {
@@ -135,7 +122,7 @@
keyguardDismissUtil.executeWhenUnlocked(
dismissAction,
false /* requiresShadeOpen */,
- true /* afterKeyguardDone */
+ true, /* afterKeyguardDone */
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModel.kt
index 9a416d1..000f7f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayActionsViewModel.kt
@@ -18,7 +18,6 @@
import com.android.compose.animation.scene.Back
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.UserActionResult.HideOverlay
@@ -47,7 +46,7 @@
put(Back, HideOverlay(Overlays.QuickSettingsShade))
}
put(
- Swipe(SwipeDirection.Down, fromSource = SceneContainerEdge.TopLeft),
+ Swipe.Down(fromSource = SceneContainerEdge.TopLeft),
ReplaceByOverlay(Overlays.NotificationsShade),
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModel.kt
index 54e5cac..f595415 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsUserActionsViewModel.kt
@@ -20,7 +20,6 @@
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.qs.ui.adapter.QSSceneAdapter
@@ -44,10 +43,8 @@
*/
class QuickSettingsUserActionsViewModel
@AssistedInject
-constructor(
- private val qsSceneAdapter: QSSceneAdapter,
- sceneBackInteractor: SceneBackInteractor,
-) : UserActionsViewModel() {
+constructor(private val qsSceneAdapter: QSSceneAdapter, sceneBackInteractor: SceneBackInteractor) :
+ UserActionsViewModel() {
private val backScene: Flow<SceneKey> =
sceneBackInteractor.backScene
@@ -55,10 +52,7 @@
.map { it ?: Scenes.Shade }
override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
- combine(
- qsSceneAdapter.isCustomizerShowing,
- backScene,
- ) { isCustomizing, backScene ->
+ combine(qsSceneAdapter.isCustomizerShowing, backScene) { isCustomizing, backScene ->
buildMap<UserAction, UserActionResult> {
if (isCustomizing) {
// TODO(b/332749288) Empty map so there are no back handlers and back can
@@ -69,9 +63,9 @@
// while customizing
} else {
put(Back, UserActionResult(backScene))
- put(Swipe(SwipeDirection.Up), UserActionResult(backScene))
+ put(Swipe.Up, UserActionResult(backScene))
put(
- Swipe(fromSource = Edge.Bottom, direction = SwipeDirection.Up),
+ Swipe.Up(fromSource = Edge.Bottom),
UserActionResult(SceneFamilies.Home),
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index ce9c441..a5eb92b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -24,7 +24,10 @@
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+import static android.window.BackEvent.EDGE_NONE;
+import static com.android.window.flags.Flags.predictiveBackSwipeEdgeNoneApi;
+import static com.android.window.flags.Flags.predictiveBackThreeButtonNav;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER;
@@ -41,6 +44,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_WAKEFULNESS_TRANSITION;
import android.annotation.FloatRange;
+import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -114,6 +118,7 @@
import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
import com.android.systemui.statusbar.policy.CallbackController;
import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder;
+import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInterface;
@@ -174,6 +179,7 @@
private Region mActiveNavBarRegion;
private final BroadcastDispatcher mBroadcastDispatcher;
+ private final BackAnimation mBackAnimation;
private IOverviewProxy mOverviewProxy;
private int mConnectionBackoffAttempts;
@@ -287,11 +293,18 @@
}
@Override
- public void onBackPressed() {
- verifyCallerAndClearCallingIdentityPostMain("onBackPressed", () -> {
- sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
- sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
- });
+ public void onBackEvent(@Nullable KeyEvent keyEvent) throws RemoteException {
+ if (predictiveBackThreeButtonNav() && predictiveBackSwipeEdgeNoneApi()
+ && mBackAnimation != null && keyEvent != null) {
+ mBackAnimation.setTriggerBack(!keyEvent.isCanceled());
+ mBackAnimation.onBackMotion(/* touchX */ 0, /* touchY */ 0, keyEvent.getAction(),
+ EDGE_NONE);
+ } else {
+ verifyCallerAndClearCallingIdentityPostMain("onBackPressed", () -> {
+ sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
+ sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
+ });
+ }
}
@Override
@@ -657,7 +670,8 @@
AssistUtils assistUtils,
DumpManager dumpManager,
Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder,
- BroadcastDispatcher broadcastDispatcher
+ BroadcastDispatcher broadcastDispatcher,
+ Optional<BackAnimation> backAnimation
) {
// b/241601880: This component should only be running for primary users or
// secondaryUsers when visibleBackgroundUsers are supported.
@@ -695,6 +709,7 @@
mDisplayTracker = displayTracker;
mUnfoldTransitionProgressForwarder = unfoldTransitionProgressForwarder;
mBroadcastDispatcher = broadcastDispatcher;
+ mBackAnimation = backAnimation.orElse(null);
if (!KeyguardWmStateRefactor.isEnabled()) {
mSysuiUnlockAnimationController = sysuiUnlockAnimationController;
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
index 6758c3b..02b2bb1 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
@@ -35,7 +35,6 @@
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.FeatureFlagsClassic
-import com.android.systemui.flags.Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES
import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
import com.android.systemui.mediaprojection.SessionCreationSource
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
@@ -132,10 +131,9 @@
@WorkerThread
private fun onScreenRecordSwitchClicked() {
if (
- flags.isEnabled(WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES) &&
- devicePolicyResolver
- .get()
- .isScreenCaptureCompletelyDisabled(UserHandle.of(userTracker.userId))
+ devicePolicyResolver
+ .get()
+ .isScreenCaptureCompletelyDisabled(UserHandle.of(userTracker.userId))
) {
mainExecutor.execute {
screenCaptureDisabledDialogDelegate.createSysUIDialog().show()
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 1fbe8e2..580a51a 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -46,7 +46,6 @@
import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor
import com.android.systemui.model.SceneContainerPlugin
import com.android.systemui.model.SysUiState
import com.android.systemui.model.updateFlags
@@ -97,7 +96,6 @@
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.filterNot
import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
@@ -138,7 +136,6 @@
private val uiEventLogger: UiEventLogger,
private val sceneBackInteractor: SceneBackInteractor,
private val shadeSessionStorage: SessionStorage,
- private val windowMgrLockscreenVisInteractor: WindowManagerLockscreenVisibilityInteractor,
private val keyguardEnabledInteractor: KeyguardEnabledInteractor,
private val dismissCallbackRegistry: DismissCallbackRegistry,
private val statusBarStateController: SysuiStatusBarStateController,
@@ -270,27 +267,6 @@
handleDeviceUnlockStatus()
handlePowerState()
handleShadeTouchability()
- handleSurfaceBehindKeyguardVisibility()
- }
-
- private fun handleSurfaceBehindKeyguardVisibility() {
- applicationScope.launch {
- sceneInteractor.currentScene.collectLatest { currentScene ->
- if (currentScene == Scenes.Lockscreen) {
- // Wait for the screen to be on
- powerInteractor.isAwake.first { it }
- // Wait for surface to become visible
- windowMgrLockscreenVisInteractor.surfaceBehindVisibility.first { it }
- // Make sure the device is actually unlocked before force-changing the scene
- deviceUnlockedInteractor.deviceUnlockStatus.first { it.isUnlocked }
- // Override the current transition, if any, by forcing the scene to Gone
- sceneInteractor.changeScene(
- toScene = Scenes.Gone,
- loggingReason = "surface behind keyguard is visible",
- )
- }
- }
- }
}
private fun handleBouncerImeVisibility() {
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
index a8a78a9..d7463f8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
@@ -32,17 +32,13 @@
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.animation.DialogTransitionAnimator;
import com.android.systemui.broadcast.BroadcastDispatcher;
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.mediaprojection.MediaProjectionMetricsLogger;
import com.android.systemui.mediaprojection.SessionCreationSource;
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver;
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialogDelegate;
-import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.policy.CallbackController;
@@ -66,12 +62,10 @@
private CountDownTimer mCountDownTimer = null;
private final Executor mMainExecutor;
private final BroadcastDispatcher mBroadcastDispatcher;
- private final FeatureFlags mFlags;
private final UserTracker mUserTracker;
private final RecordingControllerLogger mRecordingControllerLogger;
private final MediaProjectionMetricsLogger mMediaProjectionMetricsLogger;
private final ScreenCaptureDisabledDialogDelegate mScreenCaptureDisabledDialogDelegate;
- private final ScreenRecordDialogDelegate.Factory mScreenRecordDialogFactory;
private final ScreenRecordPermissionDialogDelegate.Factory
mScreenRecordPermissionDialogDelegateFactory;
@@ -116,24 +110,20 @@
public RecordingController(
@Main Executor mainExecutor,
BroadcastDispatcher broadcastDispatcher,
- FeatureFlags flags,
Lazy<ScreenCaptureDevicePolicyResolver> devicePolicyResolver,
UserTracker userTracker,
RecordingControllerLogger recordingControllerLogger,
MediaProjectionMetricsLogger mediaProjectionMetricsLogger,
ScreenCaptureDisabledDialogDelegate screenCaptureDisabledDialogDelegate,
- ScreenRecordDialogDelegate.Factory screenRecordDialogFactory,
ScreenRecordPermissionDialogDelegate.Factory
screenRecordPermissionDialogDelegateFactory) {
mMainExecutor = mainExecutor;
- mFlags = flags;
mDevicePolicyResolver = devicePolicyResolver;
mBroadcastDispatcher = broadcastDispatcher;
mUserTracker = userTracker;
mRecordingControllerLogger = recordingControllerLogger;
mMediaProjectionMetricsLogger = mediaProjectionMetricsLogger;
mScreenCaptureDisabledDialogDelegate = screenCaptureDisabledDialogDelegate;
- mScreenRecordDialogFactory = screenRecordDialogFactory;
mScreenRecordPermissionDialogDelegateFactory = screenRecordPermissionDialogDelegateFactory;
BroadcastOptions options = BroadcastOptions.makeBasic();
@@ -158,12 +148,8 @@
/** Create a dialog to show screen recording options to the user.
* If screen capturing is currently not allowed it will return a dialog
* that warns users about it. */
- public Dialog createScreenRecordDialog(Context context, FeatureFlags flags,
- DialogTransitionAnimator dialogTransitionAnimator,
- ActivityStarter activityStarter,
- @Nullable Runnable onStartRecordingClicked) {
- if (mFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)
- && mDevicePolicyResolver.get()
+ public Dialog createScreenRecordDialog(@Nullable Runnable onStartRecordingClicked) {
+ if (mDevicePolicyResolver.get()
.isScreenCaptureCompletelyDisabled(getHostUserHandle())) {
return mScreenCaptureDisabledDialogDelegate.createSysUIDialog();
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialogDelegate.java
deleted file mode 100644
index 9f1447b..0000000
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialogDelegate.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.screenrecord;
-
-import static android.app.Activity.RESULT_OK;
-
-import static com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorActivity.KEY_CAPTURE_TARGET;
-import static com.android.systemui.screenrecord.ScreenRecordingAudioSource.INTERNAL;
-import static com.android.systemui.screenrecord.ScreenRecordingAudioSource.MIC;
-import static com.android.systemui.screenrecord.ScreenRecordingAudioSource.MIC_AND_INTERNAL;
-import static com.android.systemui.screenrecord.ScreenRecordingAudioSource.NONE;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ResultReceiver;
-import android.view.Gravity;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.ArrayAdapter;
-import android.widget.Spinner;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget;
-import com.android.systemui.res.R;
-import com.android.systemui.settings.UserContextProvider;
-import com.android.systemui.statusbar.phone.SystemUIDialog;
-
-import dagger.assisted.Assisted;
-import dagger.assisted.AssistedFactory;
-import dagger.assisted.AssistedInject;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Dialog to select screen recording options
- */
-public class ScreenRecordDialogDelegate implements SystemUIDialog.Delegate {
- private static final List<ScreenRecordingAudioSource> MODES = Arrays.asList(INTERNAL, MIC,
- MIC_AND_INTERNAL);
- private static final long DELAY_MS = 3000;
- private static final long INTERVAL_MS = 1000;
-
- private final SystemUIDialog.Factory mSystemUIDialogFactory;
- private final UserContextProvider mUserContextProvider;
- private final RecordingController mController;
- private final Runnable mOnStartRecordingClicked;
- private Switch mTapsSwitch;
- private Switch mAudioSwitch;
- private Spinner mOptions;
-
- @AssistedFactory
- public interface Factory {
- ScreenRecordDialogDelegate create(
- RecordingController recordingController,
- @Nullable Runnable onStartRecordingClicked
- );
- }
-
- @AssistedInject
- public ScreenRecordDialogDelegate(
- SystemUIDialog.Factory systemUIDialogFactory,
- UserContextProvider userContextProvider,
- @Assisted RecordingController controller,
- @Assisted @Nullable Runnable onStartRecordingClicked) {
- mSystemUIDialogFactory = systemUIDialogFactory;
- mUserContextProvider = userContextProvider;
- mController = controller;
- mOnStartRecordingClicked = onStartRecordingClicked;
- }
-
- @Override
- public SystemUIDialog createDialog() {
- return mSystemUIDialogFactory.create(this);
- }
-
- @Override
- public void onCreate(SystemUIDialog dialog, Bundle savedInstanceState) {
- Window window = dialog.getWindow();
-
- window.addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
-
- window.setGravity(Gravity.CENTER);
- dialog.setTitle(R.string.screenrecord_title);
-
- dialog.setContentView(R.layout.screen_record_dialog);
-
- TextView cancelBtn = dialog.findViewById(R.id.button_cancel);
- cancelBtn.setOnClickListener(v -> dialog.dismiss());
- TextView startBtn = dialog.findViewById(R.id.button_start);
- startBtn.setOnClickListener(v -> {
- if (mOnStartRecordingClicked != null) {
- // Note that it is important to run this callback before dismissing, so that the
- // callback can disable the dialog exit animation if it wants to.
- mOnStartRecordingClicked.run();
- }
-
- // Start full-screen recording
- requestScreenCapture(/* captureTarget= */ null);
- dialog.dismiss();
- });
-
- mAudioSwitch = dialog.findViewById(R.id.screenrecord_audio_switch);
- mTapsSwitch = dialog.findViewById(R.id.screenrecord_taps_switch);
- mOptions = dialog.findViewById(R.id.screen_recording_options);
- ArrayAdapter a = new ScreenRecordingAdapter(dialog.getContext().getApplicationContext(),
- android.R.layout.simple_spinner_dropdown_item,
- MODES);
- a.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mOptions.setAdapter(a);
- mOptions.setOnItemClickListenerInt((parent, view, position, id) -> {
- mAudioSwitch.setChecked(true);
- });
-
- // disable redundant Touch & Hold accessibility action for Switch Access
- mOptions.setAccessibilityDelegate(new View.AccessibilityDelegate() {
- @Override
- public void onInitializeAccessibilityNodeInfo(@NonNull View host,
- @NonNull AccessibilityNodeInfo info) {
- info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
- super.onInitializeAccessibilityNodeInfo(host, info);
- }
- });
- mOptions.setLongClickable(false);
- }
-
- /**
- * Starts screen capture after some countdown
- * @param captureTarget target to capture (could be e.g. a task) or
- * null to record the whole screen
- */
- private void requestScreenCapture(@Nullable MediaProjectionCaptureTarget captureTarget) {
- Context userContext = mUserContextProvider.getUserContext();
- boolean showTaps = mTapsSwitch.isChecked();
- ScreenRecordingAudioSource audioMode = mAudioSwitch.isChecked()
- ? (ScreenRecordingAudioSource) mOptions.getSelectedItem()
- : NONE;
- PendingIntent startIntent = PendingIntent.getForegroundService(userContext,
- RecordingService.REQUEST_CODE,
- RecordingService.getStartIntent(
- userContext, Activity.RESULT_OK,
- audioMode.ordinal(), showTaps, captureTarget),
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- PendingIntent stopIntent = PendingIntent.getService(userContext,
- RecordingService.REQUEST_CODE,
- RecordingService.getStopIntent(userContext),
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- mController.startCountdown(DELAY_MS, INTERVAL_MS, startIntent, stopIntent);
- }
-
- private class CaptureTargetResultReceiver extends ResultReceiver {
-
- CaptureTargetResultReceiver() {
- super(new Handler(Looper.getMainLooper()));
- }
-
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (resultCode == RESULT_OK) {
- MediaProjectionCaptureTarget captureTarget = resultData
- .getParcelable(KEY_CAPTURE_TARGET, MediaProjectionCaptureTarget.class);
-
- // Start recording of the selected target
- requestScreenCapture(captureTarget);
- }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt
index 2ef27a8..60ed2de 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt
@@ -17,7 +17,7 @@
package com.android.systemui.settings
import android.hardware.display.DisplayManager
-import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+import android.hardware.display.DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS
import android.os.Handler
import android.view.Display
import androidx.annotation.GuardedBy
@@ -32,7 +32,7 @@
class DisplayTrackerImpl
internal constructor(
val displayManager: DisplayManager,
- @Background val backgroundHandler: Handler
+ @Background val backgroundHandler: Handler,
) : DisplayTracker {
override val defaultDisplayId: Int = Display.DEFAULT_DISPLAY
override val allDisplays: Array<Display>
@@ -47,27 +47,21 @@
val displayChangedListener: DisplayManager.DisplayListener =
object : DisplayManager.DisplayListener {
override fun onDisplayAdded(displayId: Int) {
- traceSection(
- "DisplayTrackerImpl.displayChangedDisplayListener#onDisplayAdded",
- ) {
+ traceSection("DisplayTrackerImpl.displayChangedDisplayListener#onDisplayAdded") {
val list = synchronized(displayCallbacks) { displayCallbacks.toList() }
onDisplayAdded(displayId, list)
}
}
override fun onDisplayRemoved(displayId: Int) {
- traceSection(
- "DisplayTrackerImpl.displayChangedDisplayListener#onDisplayRemoved",
- ) {
+ traceSection("DisplayTrackerImpl.displayChangedDisplayListener#onDisplayRemoved") {
val list = synchronized(displayCallbacks) { displayCallbacks.toList() }
onDisplayRemoved(displayId, list)
}
}
override fun onDisplayChanged(displayId: Int) {
- traceSection(
- "DisplayTrackerImpl.displayChangedDisplayListener#onDisplayChanged",
- ) {
+ traceSection("DisplayTrackerImpl.displayChangedDisplayListener#onDisplayChanged") {
val list = synchronized(displayCallbacks) { displayCallbacks.toList() }
onDisplayChanged(displayId, list)
}
@@ -83,7 +77,7 @@
override fun onDisplayChanged(displayId: Int) {
traceSection(
- "DisplayTrackerImpl.displayBrightnessChangedDisplayListener#onDisplayChanged",
+ "DisplayTrackerImpl.displayBrightnessChangedDisplayListener#onDisplayChanged"
) {
val list = synchronized(brightnessCallbacks) { brightnessCallbacks.toList() }
onDisplayChanged(displayId, list)
@@ -102,14 +96,15 @@
override fun addBrightnessChangeCallback(
callback: DisplayTracker.Callback,
- executor: Executor
+ executor: Executor,
) {
synchronized(brightnessCallbacks) {
if (brightnessCallbacks.isEmpty()) {
displayManager.registerDisplayListener(
displayBrightnessChangedListener,
backgroundHandler,
- EVENT_FLAG_DISPLAY_BRIGHTNESS
+ /* eventFlags */ 0,
+ PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS,
)
}
brightnessCallbacks.add(DisplayTrackerDataItem(WeakReference(callback), executor))
@@ -159,7 +154,7 @@
private inline fun notifySubscribers(
crossinline action: DisplayTracker.Callback.() -> Unit,
- list: List<DisplayTrackerDataItem>
+ list: List<DisplayTrackerDataItem>,
) {
list.forEach {
if (it.callback.get() != null) {
@@ -170,7 +165,7 @@
private data class DisplayTrackerDataItem(
val callback: WeakReference<DisplayTracker.Callback>,
- val executor: Executor
+ val executor: Executor,
) {
fun sameOrEmpty(other: DisplayTracker.Callback): Boolean {
return callback.get()?.equals(other) ?: true
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
index 649f8db..90d27f4 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
@@ -44,6 +44,7 @@
import androidx.annotation.Nullable;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -56,6 +57,7 @@
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.core.LogLevel;
import com.android.systemui.log.core.LogMessage;
+import com.android.systemui.res.R;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.util.settings.SecureSettings;
@@ -111,6 +113,7 @@
private boolean mControlValueInitialized;
private float mBrightnessMin = PowerManager.BRIGHTNESS_MIN;
private float mBrightnessMax = PowerManager.BRIGHTNESS_MAX;
+ private boolean mIsBrightnessOverriddenByWindow = false;
private ValueAnimator mSliderAnimator;
@@ -246,12 +249,14 @@
@Override
public void run() {
final boolean inVrMode = mIsVrModeEnabled;
- final BrightnessInfo info = mContext.getDisplay().getBrightnessInfo();
+ final BrightnessInfo info = getBrightnessInfo();
if (info == null) {
return;
}
mBrightnessMax = info.brightnessMaximum;
mBrightnessMin = info.brightnessMinimum;
+ mIsBrightnessOverriddenByWindow = info.isBrightnessOverrideByWindow;
+
// Value is passed as intbits, since this is what the message takes.
final int valueAsIntBits = Float.floatToIntBits(info.brightness);
mMainHandler.obtainMessage(MSG_UPDATE_SLIDER, valueAsIntBits,
@@ -353,7 +358,19 @@
public void onChanged(boolean tracking, int value, boolean stopTracking) {
boolean starting = !mTrackingTouch && tracking;
mTrackingTouch = tracking;
- if (mExternalChange) return;
+ if (starting) {
+ if (Flags.showToastWhenAppControlBrightness()) {
+ // Showing the warning toast if the current running app window has
+ // controlled the brightness value.
+ if (mIsBrightnessOverriddenByWindow) {
+ mControl.showToast(R.string.quick_settings_brightness_unable_adjust_msg);
+ }
+ }
+ }
+ if (mExternalChange
+ || (Flags.showToastWhenAppControlBrightness() && mIsBrightnessOverriddenByWindow)) {
+ return;
+ }
if (mSliderAnimator != null) {
mSliderAnimator.cancel();
@@ -424,6 +441,11 @@
mDisplayManager.setTemporaryBrightness(mDisplayId, brightness);
}
+ @VisibleForTesting
+ BrightnessInfo getBrightnessInfo() {
+ return mContext.getDisplay().getBrightnessInfo();
+ }
+
private void updateVrMode(boolean isEnabled) {
if (mIsVrModeEnabled != isEnabled) {
mIsVrModeEnabled = isEnabled;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
index 2f7df21..3a90d2b 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java
@@ -16,6 +16,7 @@
package com.android.systemui.settings.brightness;
+import android.annotation.StringRes;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
@@ -36,6 +37,7 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.res.R;
+import com.android.systemui.settings.brightness.ui.BrightnessWarningToast;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.util.ViewController;
@@ -68,6 +70,8 @@
private final HapticSliderPlugin mBrightnessSliderHapticPlugin;
private final ActivityStarter mActivityStarter;
+ private final BrightnessWarningToast mBrightnessWarningToast;
+
private final Gefingerpoken mOnInterceptListener = new Gefingerpoken() {
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
@@ -90,12 +94,14 @@
FalsingManager falsingManager,
UiEventLogger uiEventLogger,
HapticSliderPlugin brightnessSliderHapticPlugin,
- ActivityStarter activityStarter) {
+ ActivityStarter activityStarter,
+ BrightnessWarningToast brightnessWarningToast) {
super(brightnessSliderView);
mFalsingManager = falsingManager;
mUiEventLogger = uiEventLogger;
mBrightnessSliderHapticPlugin = brightnessSliderHapticPlugin;
mActivityStarter = activityStarter;
+ mBrightnessWarningToast = brightnessWarningToast;
}
/**
@@ -225,6 +231,15 @@
}
@Override
+ public void showToast(@StringRes int resId) {
+ if (mBrightnessWarningToast.isToastActive()) {
+ return;
+ }
+ mBrightnessWarningToast.show(mView.getContext(),
+ R.string.quick_settings_brightness_unable_adjust_msg);
+ }
+
+ @Override
public boolean isVisible() {
// this should be called rarely - once or twice per slider's value change, but not for
// every value change when user slides finger - only the final one.
@@ -286,6 +301,7 @@
private final SystemClock mSystemClock;
private final ActivityStarter mActivityStarter;
private final MSDLPlayer mMSDLPlayer;
+ private final BrightnessWarningToast mBrightnessWarningToast;
@Inject
public Factory(
@@ -294,7 +310,8 @@
VibratorHelper vibratorHelper,
MSDLPlayer msdlPlayer,
SystemClock clock,
- ActivityStarter activityStarter
+ ActivityStarter activityStarter,
+ BrightnessWarningToast brightnessWarningToast
) {
mFalsingManager = falsingManager;
mUiEventLogger = uiEventLogger;
@@ -302,6 +319,7 @@
mSystemClock = clock;
mActivityStarter = activityStarter;
mMSDLPlayer = msdlPlayer;
+ mBrightnessWarningToast = brightnessWarningToast;
}
/**
@@ -323,8 +341,8 @@
mSystemClock,
new HapticSlider.SeekBar(root.requireViewById(R.id.slider)));
HapticSliderViewBinder.bind(viewRoot, plugin);
- return new BrightnessSliderController(
- root, mFalsingManager, mUiEventLogger, plugin, mActivityStarter);
+ return new BrightnessSliderController(root, mFalsingManager, mUiEventLogger, plugin,
+ mActivityStarter, mBrightnessWarningToast);
}
/** Get the layout to inflate based on what slider to use */
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java
index 24bc670..ed69d35 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ToggleSlider.java
@@ -16,6 +16,7 @@
package com.android.systemui.settings.brightness;
+import android.annotation.StringRes;
import android.view.MotionEvent;
import com.android.settingslib.RestrictedLockUtils;
@@ -37,5 +38,6 @@
void showView();
void hideView();
+ void showToast(@StringRes int resId);
boolean isVisible();
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/BrightnessWarningToast.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/BrightnessWarningToast.kt
new file mode 100644
index 0000000..dfbdaa6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/BrightnessWarningToast.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.settings.brightness.ui
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.annotation.StringRes
+import android.content.Context
+import android.graphics.PixelFormat
+import android.view.Gravity
+import android.view.View
+import android.view.WindowManager
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.toast.ToastFactory
+import javax.inject.Inject
+
+@SysUISingleton
+class BrightnessWarningToast
+@Inject
+constructor(
+ private val toastFactory: ToastFactory,
+ private val windowManager: WindowManager,
+) {
+ private var toastView: View? = null
+
+ fun show(viewContext: Context, @StringRes resId: Int) {
+ val res = viewContext.resources
+ // Show the brightness warning toast with passing the toast inflation required context,
+ // userId and resId from SystemUI package.
+ val systemUIToast = toastFactory.createToast(
+ viewContext,
+ res.getString(resId), viewContext.packageName, viewContext.getUserId(),
+ res.configuration.orientation
+ )
+ if (systemUIToast == null) {
+ return
+ }
+
+ toastView = systemUIToast.view
+
+ val params = WindowManager.LayoutParams()
+ params.height = WindowManager.LayoutParams.WRAP_CONTENT
+ params.width = WindowManager.LayoutParams.WRAP_CONTENT
+ params.format = PixelFormat.TRANSLUCENT
+ params.title = "Brightness warning toast"
+ params.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL
+ params.flags = (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+ or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
+ params.y = systemUIToast.yOffset
+
+ val absGravity = Gravity.getAbsoluteGravity(
+ systemUIToast.gravity,
+ res.configuration.layoutDirection
+ )
+ params.gravity = absGravity
+ if ((absGravity and Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
+ params.horizontalWeight = TOAST_PARAMS_HORIZONTAL_WEIGHT
+ }
+ if ((absGravity and Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
+ params.verticalWeight = TOAST_PARAMS_VERTICAL_WEIGHT
+ }
+
+ windowManager.addView(toastView, params)
+
+ val inAnimator = systemUIToast.inAnimation
+ inAnimator?.start()
+
+ toastView!!.postDelayed({
+ val outAnimator = systemUIToast.outAnimation
+ if (outAnimator != null) {
+ outAnimator.start()
+ outAnimator.addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animator: Animator) {
+ windowManager.removeViewImmediate(toastView)
+ toastView = null
+ }
+ })
+ }
+ }, TOAST_DURATION_MS)
+ }
+
+ fun isToastActive(): Boolean {
+ return toastView != null && toastView!!.isAttachedToWindow
+ }
+
+ companion object {
+ private const val TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f
+ private const val TOAST_PARAMS_VERTICAL_WEIGHT = 1.0f
+ private const val TOAST_DURATION_MS: Long = 3000
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt
index e5f6846..b0777c9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt
@@ -18,7 +18,6 @@
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.scene.shared.model.Overlays
@@ -35,7 +34,7 @@
return arrayOf(
// Swiping down, not from the edge, always goes to shade.
Swipe.Down to shadeUserActionResult,
- swipeDown(pointerCount = 2) to shadeUserActionResult,
+ Swipe.Down(pointerCount = 2) to shadeUserActionResult,
// Swiping down from the top edge.
swipeDownFromTop(pointerCount = 1) to
@@ -54,7 +53,7 @@
return arrayOf(
// Swiping down, not from the edge, always goes to shade.
Swipe.Down to shadeUserActionResult,
- swipeDown(pointerCount = 2) to shadeUserActionResult,
+ Swipe.Down(pointerCount = 2) to shadeUserActionResult,
// Swiping down from the top edge goes to QS.
swipeDownFromTop(pointerCount = 1) to shadeUserActionResult,
swipeDownFromTop(pointerCount = 2) to shadeUserActionResult,
@@ -69,15 +68,10 @@
UserActionResult.ShowOverlay(Overlays.QuickSettingsShade, isIrreversible = true)
return arrayOf(
Swipe.Down to notifShadeUserActionResult,
- Swipe(direction = SwipeDirection.Down, fromSource = SceneContainerEdge.TopRight) to
- qsShadeuserActionResult,
+ Swipe.Down(fromSource = SceneContainerEdge.TopRight) to qsShadeuserActionResult,
)
}
private fun swipeDownFromTop(pointerCount: Int): Swipe {
- return Swipe(SwipeDirection.Down, fromSource = Edge.Top, pointerCount = pointerCount)
-}
-
-private fun swipeDown(pointerCount: Int): Swipe {
- return Swipe(SwipeDirection.Down, pointerCount = pointerCount)
+ return Swipe.Down(fromSource = Edge.Top, pointerCount = pointerCount)
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt
index 4bdd367..7d6b1a3 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt
@@ -17,7 +17,6 @@
package com.android.systemui.shade.ui.viewmodel
import com.android.compose.animation.scene.Swipe
-import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.qs.ui.adapter.QSSceneAdapter
@@ -58,7 +57,7 @@
buildMap<UserAction, UserActionResult> {
if (!isCustomizerShowing) {
set(
- Swipe(SwipeDirection.Up),
+ Swipe.Up,
UserActionResult(
backScene,
ToSplitShade.takeIf { shadeMode is ShadeMode.Split },
@@ -69,7 +68,7 @@
// TODO(b/330200163) Add an else to be able to collapse the shade while
// customizing
if (shadeMode is ShadeMode.Single) {
- set(Swipe(SwipeDirection.Down), UserActionResult(Scenes.QuickSettings))
+ set(Swipe.Down, UserActionResult(Scenes.QuickSettings))
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 520cbf9..a5595ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -116,6 +116,7 @@
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.user.domain.interactor.UserLogoutInteractor;
import com.android.systemui.util.AlarmTimeout;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.wakelock.SettableWakeLock;
@@ -162,6 +163,7 @@
private final KeyguardLogger mKeyguardLogger;
private final UserTracker mUserTracker;
private final BouncerMessageInteractor mBouncerMessageInteractor;
+
private ViewGroup mIndicationArea;
private KeyguardIndicationTextView mTopIndicationView;
private KeyguardIndicationTextView mLockScreenIndicationView;
@@ -187,6 +189,7 @@
private final BiometricMessageInteractor mBiometricMessageInteractor;
private DeviceEntryFingerprintAuthInteractor mDeviceEntryFingerprintAuthInteractor;
private DeviceEntryFaceAuthInteractor mDeviceEntryFaceAuthInteractor;
+ private final UserLogoutInteractor mUserLogoutInteractor;
private String mPersistentUnlockMessage;
private String mAlignmentIndication;
private boolean mForceIsDismissible;
@@ -237,6 +240,13 @@
showTrustAgentErrorMessage(mTrustAgentErrorMessage);
}
};
+ @VisibleForTesting
+ final Consumer<Boolean> mIsLogoutEnabledCallback =
+ (Boolean isLogoutEnabled) -> {
+ if (mVisible) {
+ updateDeviceEntryIndication(false);
+ }
+ };
private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
@Override
public void onScreenTurnedOn() {
@@ -299,7 +309,8 @@
KeyguardInteractor keyguardInteractor,
BiometricMessageInteractor biometricMessageInteractor,
DeviceEntryFingerprintAuthInteractor deviceEntryFingerprintAuthInteractor,
- DeviceEntryFaceAuthInteractor deviceEntryFaceAuthInteractor
+ DeviceEntryFaceAuthInteractor deviceEntryFaceAuthInteractor,
+ UserLogoutInteractor userLogoutInteractor
) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
@@ -331,6 +342,8 @@
mBiometricMessageInteractor = biometricMessageInteractor;
mDeviceEntryFingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor;
mDeviceEntryFaceAuthInteractor = deviceEntryFaceAuthInteractor;
+ mUserLogoutInteractor = userLogoutInteractor;
+
mFaceAcquiredMessageDeferral = faceHelpMessageDeferral.create();
@@ -418,6 +431,9 @@
mCoExAcquisitionMsgIdsToShowCallback);
collectFlow(mIndicationArea, mDeviceEntryFingerprintAuthInteractor.isEngaged(),
mIsFingerprintEngagedCallback);
+ collectFlow(mIndicationArea,
+ mUserLogoutInteractor.isLogoutEnabled(),
+ mIsLogoutEnabledCallback);
}
/**
@@ -619,10 +635,11 @@
}
private void updateLockScreenUserLockedMsg(int userId) {
- boolean userUnlocked = mKeyguardUpdateMonitor.isUserUnlocked(userId);
+ boolean userStorageUnlocked = mKeyguardUpdateMonitor.isUserUnlocked(userId);
boolean encryptedOrLockdown = mKeyguardUpdateMonitor.isEncryptedOrLockdown(userId);
- mKeyguardLogger.logUpdateLockScreenUserLockedMsg(userId, userUnlocked, encryptedOrLockdown);
- if (!userUnlocked || encryptedOrLockdown) {
+ mKeyguardLogger.logUpdateLockScreenUserLockedMsg(userId, userStorageUnlocked,
+ encryptedOrLockdown);
+ if (!userStorageUnlocked || encryptedOrLockdown) {
mRotateTextViewController.updateIndication(
INDICATION_TYPE_USER_LOCKED,
new KeyguardIndication.Builder()
@@ -743,9 +760,7 @@
}
private void updateLockScreenLogoutView() {
- final boolean shouldShowLogout = mKeyguardUpdateMonitor.isLogoutEnabled()
- && getCurrentUser() != UserHandle.USER_SYSTEM;
- if (shouldShowLogout) {
+ if (mUserLogoutInteractor.isLogoutEnabled().getValue()) {
mRotateTextViewController.updateIndication(
INDICATION_TYPE_LOGOUT,
new KeyguardIndication.Builder()
@@ -759,7 +774,7 @@
if (mFalsingManager.isFalseTap(LOW_PENALTY)) {
return;
}
- mDevicePolicyManager.logoutUser();
+ mUserLogoutInteractor.logOut();
})
.build(),
false);
@@ -1514,13 +1529,6 @@
}
@Override
- public void onLogoutEnabledChanged() {
- if (mVisible) {
- updateDeviceEntryIndication(false);
- }
- }
-
- @Override
public void onRequireUnlockForNfc() {
showTransientIndication(mContext.getString(R.string.require_unlock_for_nfc));
hideTransientIndicationDelayed(DEFAULT_HIDE_DELAY_MS);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
index 3a24ec9..c1b8d9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
@@ -383,34 +383,20 @@
}
protected boolean hasSameIcon(Object parentData, Object childData) {
- Icon parentIcon = getIcon((Notification) parentData);
- Icon childIcon = getIcon((Notification) childData);
+ Icon parentIcon = ((Notification) parentData).getSmallIcon();
+ Icon childIcon = ((Notification) childData).getSmallIcon();
return parentIcon.sameAs(childIcon);
}
- private static Icon getIcon(Notification notification) {
- if (notification.shouldUseAppIcon()) {
- return notification.getAppIcon();
- }
- return notification.getSmallIcon();
- }
-
/**
* @return whether two ImageViews have the same colorFilterSet or none at all
*/
protected boolean hasSameColor(Object parentData, Object childData) {
- int parentColor = getColor((Notification) parentData);
- int childColor = getColor((Notification) childData);
+ int parentColor = ((Notification) parentData).color;
+ int childColor = ((Notification) childData).color;
return parentColor == childColor;
}
- private static int getColor(Notification notification) {
- if (notification.shouldUseAppIcon()) {
- return 0; // the color filter isn't applied if using the app icon
- }
- return notification.color;
- }
-
@Override
public boolean isEmpty(View view) {
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java
index 0d789c7..f5d4434 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java
@@ -119,7 +119,6 @@
/** Factory for constructing an {@link OperatorNameViewController}. */
public static class Factory {
- private final DarkIconDispatcher mDarkIconDispatcher;
private final TunerService mTunerService;
private final TelephonyManager mTelephonyManager;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -129,7 +128,7 @@
private final JavaAdapter mJavaAdapter;
@Inject
- public Factory(DarkIconDispatcher darkIconDispatcher,
+ public Factory(
TunerService tunerService,
TelephonyManager telephonyManager,
KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -137,7 +136,6 @@
AirplaneModeInteractor airplaneModeInteractor,
SubscriptionManagerProxy subscriptionManagerProxy,
JavaAdapter javaAdapter) {
- mDarkIconDispatcher = darkIconDispatcher;
mTunerService = tunerService;
mTelephonyManager = telephonyManager;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -148,9 +146,11 @@
}
/** Create an {@link OperatorNameViewController}. */
- public OperatorNameViewController create(OperatorNameView view) {
- return new OperatorNameViewController(view,
- mDarkIconDispatcher,
+ public OperatorNameViewController create(
+ OperatorNameView view, DarkIconDispatcher darkIconDispatcher) {
+ return new OperatorNameViewController(
+ view,
+ darkIconDispatcher,
mTunerService,
mTelephonyManager,
mKeyguardUpdateMonitor,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index ad3afd4..33f0c64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -27,7 +27,6 @@
import android.app.Notification;
import android.content.Context;
import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -36,7 +35,6 @@
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
-import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Trace;
@@ -520,36 +518,10 @@
userId = UserHandle.USER_SYSTEM;
}
- // Try to load the monochrome app icon if applicable
- Drawable icon = maybeGetMonochromeAppIcon(context, statusBarIcon);
- // Otherwise, just use the icon normally
- if (icon == null) {
- icon = statusBarIcon.icon.loadDrawableAsUser(context, userId);
- }
- return icon;
+ return statusBarIcon.icon.loadDrawableAsUser(context, userId);
}
}
- @Nullable
- private Drawable maybeGetMonochromeAppIcon(Context context,
- StatusBarIcon statusBarIcon) {
- if (android.app.Flags.notificationsUseMonochromeAppIcon()
- && statusBarIcon.type == StatusBarIcon.Type.MaybeMonochromeAppIcon) {
- // Check if we have a monochrome app icon
- PackageManager pm = context.getPackageManager();
- Drawable appIcon = context.getApplicationInfo().loadIcon(pm);
- if (appIcon instanceof AdaptiveIconDrawable) {
- Drawable monochrome = ((AdaptiveIconDrawable) appIcon).getMonochrome();
- if (monochrome != null) {
- setCropToPadding(true);
- setScaleType(ScaleType.CENTER);
- return new ScalingDrawableWrapper(monochrome, APP_ICON_SCALE);
- }
- }
- }
- return null;
- }
-
public StatusBarIcon getStatusBarIcon() {
return mIcon;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
index c8d3f33..7526748 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
@@ -68,13 +68,8 @@
notifChipsInteractor.onPromotedNotificationChipTapped(this@toChipModel.key)
}
}
- return OngoingActivityChipModel.Shown.ShortTimeDelta(
- icon,
- colors,
- time = this.whenTime,
- onClickListener,
- )
- // TODO(b/364653005): If Notification.showWhen = false, don't show the time delta.
+ return OngoingActivityChipModel.Shown.IconOnly(icon, colors, onClickListener)
+ // TODO(b/364653005): Use Notification.showWhen to determine if we should show the time.
// TODO(b/364653005): If Notification.whenTime is in the past, show "ago" in the text.
// TODO(b/364653005): If Notification.shortCriticalText is set, use that instead of `when`.
// TODO(b/364653005): If the app that posted the notification is in the foreground, don't
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
index 9c53cc1..e3dc70a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.chips.screenrecord.domain.interactor
+import com.android.systemui.Flags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.log.LogBuffer
@@ -28,14 +29,19 @@
import com.android.systemui.statusbar.chips.screenrecord.domain.model.ScreenRecordChipModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
+import kotlinx.coroutines.flow.transformLatest
+import kotlinx.coroutines.launch
/** Interactor for the screen recording chip shown in the status bar. */
@SysUISingleton
+@OptIn(ExperimentalCoroutinesApi::class)
class ScreenRecordChipInteractor
@Inject
constructor(
@@ -44,6 +50,32 @@
private val mediaProjectionRepository: MediaProjectionRepository,
@StatusBarChipsLog private val logger: LogBuffer,
) {
+ /**
+ * Emits true if we should assume that we're currently screen recording, even if
+ * [ScreenRecordRepository.screenRecordState] hasn't emitted [ScreenRecordModel.Recording] yet.
+ */
+ private val shouldAssumeIsRecording: Flow<Boolean> =
+ screenRecordRepository.screenRecordState
+ .transformLatest {
+ when (it) {
+ is ScreenRecordModel.DoingNothing -> {
+ emit(false)
+ }
+ is ScreenRecordModel.Starting -> {
+ // If we're told that the recording will start in [it.millisUntilStarted],
+ // optimistically assume the recording did indeed start after that time even
+ // if [ScreenRecordRepository.screenRecordState] hasn't emitted
+ // [ScreenRecordModel.Recording] yet. Start 50ms early so that the chip
+ // timer will definitely be showing by the time the recording actually
+ // starts - see b/366448907.
+ delay(it.millisUntilStarted - 50)
+ emit(true)
+ }
+ is ScreenRecordModel.Recording -> {}
+ }
+ }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
val screenRecordState: StateFlow<ScreenRecordChipModel> =
// ScreenRecordRepository has the main "is the screen being recorded?" state, and
// MediaProjectionRepository has information about what specifically is being recorded (a
@@ -51,37 +83,55 @@
combine(
screenRecordRepository.screenRecordState,
mediaProjectionRepository.mediaProjectionState,
- ) { screenRecordState, mediaProjectionState ->
- when (screenRecordState) {
- is ScreenRecordModel.DoingNothing -> {
- logger.log(TAG, LogLevel.INFO, {}, { "State: DoingNothing" })
- ScreenRecordChipModel.DoingNothing
- }
- is ScreenRecordModel.Starting -> {
- logger.log(
- TAG,
- LogLevel.INFO,
- { long1 = screenRecordState.millisUntilStarted },
- { "State: Starting($long1)" }
- )
- ScreenRecordChipModel.Starting(screenRecordState.millisUntilStarted)
- }
- is ScreenRecordModel.Recording -> {
- val recordedTask =
- if (
- mediaProjectionState is MediaProjectionState.Projecting.SingleTask
- ) {
- mediaProjectionState.task
- } else {
- null
- }
- logger.log(
- TAG,
- LogLevel.INFO,
- { str1 = recordedTask?.baseIntent?.component?.packageName },
- { "State: Recording(taskPackage=$str1)" }
- )
- ScreenRecordChipModel.Recording(recordedTask)
+ shouldAssumeIsRecording,
+ ) { screenRecordState, mediaProjectionState, shouldAssumeIsRecording ->
+ if (
+ Flags.statusBarAutoStartScreenRecordChip() &&
+ shouldAssumeIsRecording &&
+ screenRecordState is ScreenRecordModel.Starting
+ ) {
+ logger.log(
+ TAG,
+ LogLevel.INFO,
+ {},
+ { "State: Recording(taskPackage=null) due to force-start" },
+ )
+ ScreenRecordChipModel.Recording(recordedTask = null)
+ } else {
+ when (screenRecordState) {
+ is ScreenRecordModel.DoingNothing -> {
+ logger.log(TAG, LogLevel.INFO, {}, { "State: DoingNothing" })
+ ScreenRecordChipModel.DoingNothing
+ }
+
+ is ScreenRecordModel.Starting -> {
+ logger.log(
+ TAG,
+ LogLevel.INFO,
+ { long1 = screenRecordState.millisUntilStarted },
+ { "State: Starting($long1)" },
+ )
+ ScreenRecordChipModel.Starting(screenRecordState.millisUntilStarted)
+ }
+
+ is ScreenRecordModel.Recording -> {
+ val recordedTask =
+ if (
+ mediaProjectionState
+ is MediaProjectionState.Projecting.SingleTask
+ ) {
+ mediaProjectionState.task
+ } else {
+ null
+ }
+ logger.log(
+ TAG,
+ LogLevel.INFO,
+ { str1 = recordedTask?.baseIntent?.component?.packageName },
+ { "State: Recording(taskPackage=$str1)" },
+ )
+ ScreenRecordChipModel.Recording(recordedTask)
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
index 9b3513e..84c7ab2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
@@ -23,6 +23,7 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayScopeRepository
+import com.android.systemui.statusbar.data.repository.LightBarControllerStore
import com.android.systemui.statusbar.data.repository.PrivacyDotWindowControllerStore
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
@@ -50,6 +51,7 @@
private val statusBarWindowControllerStore: StatusBarWindowControllerStore,
private val statusBarInitializerStore: StatusBarInitializerStore,
private val privacyDotWindowControllerStore: PrivacyDotWindowControllerStore,
+ private val lightBarControllerStore: LightBarControllerStore,
) : CoreStartable {
init {
@@ -74,6 +76,14 @@
createAndStartOrchestratorForDisplay(displayId)
createAndStartInitializerForDisplay(displayId)
startPrivacyDotForDisplay(displayId)
+ createLightBarControllerForDisplay(displayId)
+ }
+
+ private fun createLightBarControllerForDisplay(displayId: Int) {
+ // Explicitly not calling `start()`, because the store is already calling `start()`.
+ // This is to maintain the legacy behavior with NavigationBar, that was already expecting
+ // LightBarController to start at construction time.
+ lightBarControllerStore.forDisplay(displayId)
}
private fun createAndStartOrchestratorForDisplay(displayId: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
index 39de28e..27d8151 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/StatusBarDataLayerModule.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.statusbar.data
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStoreModule
import com.android.systemui.statusbar.data.repository.KeyguardStatusBarRepositoryModule
import com.android.systemui.statusbar.data.repository.LightBarControllerStoreModule
import com.android.systemui.statusbar.data.repository.RemoteInputRepositoryModule
@@ -28,6 +29,7 @@
@Module(
includes =
[
+ DarkIconDispatcherStoreModule::class,
KeyguardStatusBarRepositoryModule::class,
LightBarControllerStoreModule::class,
RemoteInputRepositoryModule::class,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
new file mode 100644
index 0000000..8183a48
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.data.repository
+
+import android.content.Context
+import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.display.data.repository.DisplayRepository
+import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
+import com.android.systemui.display.data.repository.PerDisplayStore
+import com.android.systemui.display.data.repository.PerDisplayStoreImpl
+import com.android.systemui.display.data.repository.SingleDisplayStore
+import com.android.systemui.plugins.DarkIconDispatcher
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl
+import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
+import dagger.Binds
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/** Provides per display instances of [DarkIconDispatcher]. */
+interface DarkIconDispatcherStore : PerDisplayStore<DarkIconDispatcher>
+
+/** Provides per display instances of [SysuiDarkIconDispatcher]. */
+interface SysuiDarkIconDispatcherStore : PerDisplayStore<SysuiDarkIconDispatcher>
+
+/**
+ * Multi display implementation that should be used when the [StatusBarConnectedDisplays] flag is
+ * enabled.
+ */
+@SysUISingleton
+class MultiDisplayDarkIconDispatcherStore
+@Inject
+constructor(
+ @Background backgroundApplicationScope: CoroutineScope,
+ displayRepository: DisplayRepository,
+ private val factory: DarkIconDispatcherImpl.Factory,
+ private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
+) :
+ SysuiDarkIconDispatcherStore,
+ PerDisplayStoreImpl<SysuiDarkIconDispatcher>(backgroundApplicationScope, displayRepository) {
+
+ init {
+ StatusBarConnectedDisplays.assertInNewMode()
+ }
+
+ override fun createInstanceForDisplay(displayId: Int): SysuiDarkIconDispatcher {
+ val properties = displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+ return factory.create(displayId, properties.context)
+ }
+
+ override suspend fun onDisplayRemovalAction(instance: SysuiDarkIconDispatcher) {
+ instance.stop()
+ }
+
+ override val instanceClass = SysuiDarkIconDispatcher::class.java
+}
+
+/**
+ * Single display implementation that should be used when the [StatusBarConnectedDisplays] flag is
+ * disabled.
+ */
+@SysUISingleton
+class SingleDisplayDarkIconDispatcherStore
+@Inject
+constructor(factory: DarkIconDispatcherImpl.Factory, context: Context) :
+ SysuiDarkIconDispatcherStore,
+ PerDisplayStore<SysuiDarkIconDispatcher> by SingleDisplayStore(
+ defaultInstance = factory.create(context.displayId, context)
+ ) {
+
+ init {
+ StatusBarConnectedDisplays.assertInLegacyMode()
+ }
+}
+
+/** Extra implementation that simply implements the [DarkIconDispatcherStore] interface. */
+@SysUISingleton
+class DarkIconDispatcherStoreImpl
+@Inject
+constructor(private val store: SysuiDarkIconDispatcherStore) : DarkIconDispatcherStore {
+ override val defaultDisplay: DarkIconDispatcher
+ get() = store.defaultDisplay
+
+ override fun forDisplay(displayId: Int): DarkIconDispatcher = store.forDisplay(displayId)
+}
+
+@Module
+interface DarkIconDispatcherStoreModule {
+
+ @Binds fun store(impl: DarkIconDispatcherStoreImpl): DarkIconDispatcherStore
+
+ companion object {
+ @Provides
+ @SysUISingleton
+ fun sysUiStore(
+ singleDisplayLazy: Lazy<SingleDisplayDarkIconDispatcherStore>,
+ multiDisplayLazy: Lazy<MultiDisplayDarkIconDispatcherStore>,
+ ): SysuiDarkIconDispatcherStore {
+ return if (StatusBarConnectedDisplays.isEnabled) {
+ multiDisplayLazy.get()
+ } else {
+ singleDisplayLazy.get()
+ }
+ }
+
+ @Provides
+ @SysUISingleton
+ @IntoMap
+ @ClassKey(DarkIconDispatcherStore::class)
+ fun storeAsCoreStartable(
+ multiDisplayLazy: Lazy<MultiDisplayDarkIconDispatcherStore>
+ ): CoreStartable {
+ return if (StatusBarConnectedDisplays.isEnabled) {
+ multiDisplayLazy.get()
+ } else {
+ CoreStartable.NOP
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
index ff50e31..e498755 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
@@ -44,6 +44,7 @@
private val factory: LightBarControllerImpl.Factory,
private val displayScopeRepository: DisplayScopeRepository,
private val statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
+ private val darkIconDispatcherStore: DarkIconDispatcherStore,
) :
LightBarControllerStore,
PerDisplayStoreImpl<LightBarController>(backgroundApplicationScope, displayRepository) {
@@ -53,6 +54,7 @@
.create(
displayId,
displayScopeRepository.scopeForDisplay(displayId),
+ darkIconDispatcherStore.forDisplay(displayId),
statusBarModeRepositoryStore.forDisplay(displayId),
)
.also { it.start() }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationContentDescription.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationContentDescription.kt
index bdd9fd0..6b6920a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationContentDescription.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationContentDescription.kt
@@ -28,14 +28,5 @@
@MainThread
fun contentDescForNotification(c: Context, n: Notification): CharSequence {
val appName = n.loadHeaderAppName(c) ?: ""
- val title = n.extras?.getCharSequence(Notification.EXTRA_TITLE)
- val text = n.extras?.getCharSequence(Notification.EXTRA_TEXT)
- val ticker = n.tickerText
-
- // Some apps just put the app name into the title
- val titleOrText = if (TextUtils.equals(title, appName)) text else title
- val desc =
- if (!TextUtils.isEmpty(titleOrText)) titleOrText
- else if (!TextUtils.isEmpty(ticker)) ticker else ""
- return c.getString(R.string.accessibility_desc_notification_icon, appName, desc)
+ return c.getString(R.string.accessibility_desc_notification_icon, appName, "")
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
index 16d0cc4..3c8c42f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
@@ -18,7 +18,6 @@
import android.app.Notification
import android.content.Context
-import android.graphics.drawable.Drawable
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.contentDescForNotification
@@ -30,15 +29,11 @@
return StatusBarIconView(
context,
"${entry.sbn.packageName}/0x${Integer.toHexString(entry.sbn.id)}",
- entry.sbn
+ entry.sbn,
)
}
fun getIconContentDescription(n: Notification): CharSequence {
return contentDescForNotification(context, n)
}
-
- fun getAppIcon(n: Notification): Drawable {
- return n.loadHeaderAppIcon(context)
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
index db80483..4717194 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
@@ -26,6 +26,7 @@
import android.util.Log
import android.view.View
import android.widget.ImageView
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.traceSection
import com.android.internal.statusbar.StatusBarIcon
import com.android.systemui.Flags
@@ -44,7 +45,6 @@
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
-import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.withContext
/**
@@ -152,13 +152,7 @@
setIcon(entry, sensitiveIconDescriptor, shelfIcon)
setIcon(entry, sensitiveIconDescriptor, aodIcon)
entry.icons =
- IconPack.buildPack(
- sbIcon,
- sbChipIcon,
- shelfIcon,
- aodIcon,
- entry.icons,
- )
+ IconPack.buildPack(sbIcon, sbChipIcon, shelfIcon, aodIcon, entry.icons)
} catch (e: InflationException) {
entry.icons = IconPack.buildEmptyPack(entry.icons)
throw e
@@ -182,7 +176,7 @@
Log.wtf(
TAG,
"Updating using the cache is not supported when the " +
- "notifications_background_icons flag is off"
+ "notifications_background_icons flag is off",
)
}
if (!usingCache || !Flags.notificationsBackgroundIcons()) {
@@ -249,10 +243,6 @@
val (icon: Icon?, type: StatusBarIcon.Type) =
if (showPeopleAvatar) {
createPeopleAvatar(entry) to StatusBarIcon.Type.PeopleAvatar
- } else if (
- android.app.Flags.notificationsUseMonochromeAppIcon() && n.shouldUseAppIcon()
- ) {
- n.smallIcon to StatusBarIcon.Type.MaybeMonochromeAppIcon
} else {
n.smallIcon to StatusBarIcon.Type.NotifSmallIcon
}
@@ -267,33 +257,25 @@
private fun getCachedIconDescriptor(
entry: NotificationEntry,
- showPeopleAvatar: Boolean
+ showPeopleAvatar: Boolean,
): StatusBarIcon? {
val peopleAvatarDescriptor = entry.icons.peopleAvatarDescriptor
- val appIconDescriptor = entry.icons.appIconDescriptor
val smallIconDescriptor = entry.icons.smallIconDescriptor
// If cached, return corresponding cached values
return when {
showPeopleAvatar && peopleAvatarDescriptor != null -> peopleAvatarDescriptor
- android.app.Flags.notificationsUseMonochromeAppIcon() && appIconDescriptor != null ->
- appIconDescriptor
smallIconDescriptor != null -> smallIconDescriptor
else -> null
}
}
private fun cacheIconDescriptor(entry: NotificationEntry, descriptor: StatusBarIcon) {
- if (
- android.app.Flags.notificationsUseAppIcon() ||
- android.app.Flags.notificationsUseMonochromeAppIcon()
- ) {
- // If either of the new icon flags is enabled, we cache the icon all the time.
+ if (android.app.Flags.notificationsRedesignAppIcons()) {
+ // Although we're not actually using the app icon in the status bar, let's make sure
+ // we cache the icon all the time when the flag is on.
when (descriptor.type) {
StatusBarIcon.Type.PeopleAvatar -> entry.icons.peopleAvatarDescriptor = descriptor
- // When notificationsUseMonochromeAppIcon is enabled, we use the appIconDescriptor.
- StatusBarIcon.Type.MaybeMonochromeAppIcon ->
- entry.icons.appIconDescriptor = descriptor
// When notificationsUseAppIcon is enabled, the app icon overrides the small icon.
// But either way, it's a good idea to cache the descriptor.
else -> entry.icons.smallIconDescriptor = descriptor
@@ -312,7 +294,7 @@
private fun setIcon(
entry: NotificationEntry,
iconDescriptor: StatusBarIcon,
- iconView: StatusBarIconView
+ iconView: StatusBarIconView,
) {
iconView.setShowsConversation(showsConversation(entry, iconView, iconDescriptor))
iconView.setTag(R.id.icon_is_pre_L, entry.targetSdk < Build.VERSION_CODES.LOLLIPOP)
@@ -323,7 +305,7 @@
private fun Icon.toStatusBarIcon(
entry: NotificationEntry,
- type: StatusBarIcon.Type
+ type: StatusBarIcon.Type,
): StatusBarIcon {
val n = entry.sbn.notification
return StatusBarIcon(
@@ -333,7 +315,7 @@
n.iconLevel,
n.number,
iconBuilder.getIconContentDescription(n),
- type
+ type,
)
}
@@ -347,7 +329,7 @@
} catch (e: Exception) {
Log.e(
TAG,
- "Error calling LauncherApps#getShortcutIcon for notification $entry: $e"
+ "Error calling LauncherApps#getShortcutIcon for notification $entry: $e",
)
}
}
@@ -431,7 +413,7 @@
private fun showsConversation(
entry: NotificationEntry,
iconView: StatusBarIconView,
- iconDescriptor: StatusBarIcon
+ iconDescriptor: StatusBarIcon,
): Boolean {
val usedInSensitiveContext =
iconView === entry.icons.shelfIcon || iconView === entry.icons.aodIcon
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java
index 611cebc..cb6be66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java
@@ -34,7 +34,6 @@
@Nullable private final StatusBarIconView mAodIcon;
@Nullable private StatusBarIcon mSmallIconDescriptor;
- @Nullable private StatusBarIcon mAppIconDescriptor;
@Nullable private StatusBarIcon mPeopleAvatarDescriptor;
private boolean mIsImportantConversation;
@@ -127,15 +126,6 @@
mPeopleAvatarDescriptor = peopleAvatarDescriptor;
}
- @Nullable
- StatusBarIcon getAppIconDescriptor() {
- return mAppIconDescriptor;
- }
-
- void setAppIconDescriptor(@Nullable StatusBarIcon appIconDescriptor) {
- mAppIconDescriptor = appIconDescriptor;
- }
-
boolean isImportantConversation() {
return mIsImportantConversation;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerAlwaysOnDisplayViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerAlwaysOnDisplayViewBinder.kt
index 663588c..fc432ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerAlwaysOnDisplayViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerAlwaysOnDisplayViewBinder.kt
@@ -17,11 +17,13 @@
package com.android.systemui.statusbar.notification.icon.ui.viewbinder
import androidx.lifecycle.lifecycleScope
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.traceSection
import com.android.systemui.common.ui.ConfigurationState
import com.android.systemui.keyguard.ui.binder.KeyguardRootViewBinder
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.notification.collection.NotifCollection
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore
import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
@@ -30,7 +32,6 @@
import com.android.systemui.statusbar.ui.SystemBarUtilsState
import javax.inject.Inject
import kotlinx.coroutines.DisposableHandle
-import com.android.app.tracing.coroutines.launchTraced as launch
/** Binds a [NotificationIconContainer] to a [NotificationIconContainerAlwaysOnDisplayViewModel]. */
class NotificationIconContainerAlwaysOnDisplayViewBinder
@@ -38,7 +39,7 @@
constructor(
private val viewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
private val keyguardRootViewModel: KeyguardRootViewModel,
- private val configuration: ConfigurationState,
+ @ShadeDisplayAware private val configuration: ConfigurationState,
private val failureTracker: StatusBarIconViewBindingFailureTracker,
private val screenOffAnimationController: ScreenOffAnimationController,
private val systemBarUtilsState: SystemBarUtilsState,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerShelfViewBinder.kt
index 4e40888..5432f14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerShelfViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerShelfViewBinder.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.icon.ui.viewbinder
import com.android.systemui.common.ui.ConfigurationState
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.notification.collection.NotifCollection
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.bindIcons
@@ -30,7 +31,7 @@
@Inject
constructor(
private val viewModel: NotificationIconContainerShelfViewModel,
- private val configuration: ConfigurationState,
+ @ShadeDisplayAware private val configuration: ConfigurationState,
private val systemBarUtilsState: SystemBarUtilsState,
private val failureTracker: StatusBarIconViewBindingFailureTracker,
private val viewStore: ShelfNotificationIconViewStore,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt
index f0f529e..a21dabb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt
@@ -17,9 +17,11 @@
package com.android.systemui.statusbar.notification.icon.ui.viewbinder
import androidx.lifecycle.lifecycleScope
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.traceSection
import com.android.systemui.common.ui.ConfigurationState
import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.notification.collection.NotifCollection
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore
import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerStatusBarViewModel
@@ -27,23 +29,23 @@
import com.android.systemui.statusbar.ui.SystemBarUtilsState
import javax.inject.Inject
import kotlinx.coroutines.DisposableHandle
-import com.android.app.tracing.coroutines.launchTraced as launch
/** Binds a [NotificationIconContainer] to a [NotificationIconContainerStatusBarViewModel]. */
class NotificationIconContainerStatusBarViewBinder
@Inject
constructor(
private val viewModel: NotificationIconContainerStatusBarViewModel,
- private val configuration: ConfigurationState,
+ @ShadeDisplayAware private val configuration: ConfigurationState,
private val systemBarUtilsState: SystemBarUtilsState,
private val failureTracker: StatusBarIconViewBindingFailureTracker,
private val viewStore: StatusBarNotificationIconViewStore,
) {
- fun bindWhileAttached(view: NotificationIconContainer): DisposableHandle {
+ fun bindWhileAttached(view: NotificationIconContainer, displayId: Int): DisposableHandle {
return traceSection("NICStatusBar#bindWhileAttached") {
view.repeatWhenAttached {
lifecycleScope.launch {
NotificationIconContainerViewBinder.bind(
+ displayId = displayId,
view = view,
viewModel = viewModel,
configuration = configuration,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
index 063fe45..6dbb714 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt
@@ -24,6 +24,7 @@
import androidx.annotation.ColorInt
import androidx.collection.ArrayMap
import androidx.lifecycle.lifecycleScope
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.traceSection
import com.android.internal.R as RInternal
import com.android.internal.statusbar.StatusBarIcon
@@ -54,12 +55,12 @@
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
/** Binds a view-model to a [NotificationIconContainer]. */
object NotificationIconContainerViewBinder {
suspend fun bind(
+ displayId: Int,
view: NotificationIconContainer,
viewModel: NotificationIconContainerStatusBarViewModel,
configuration: ConfigurationState,
@@ -70,7 +71,10 @@
launch {
val contrastColorUtil = ContrastColorUtil.getInstance(view.context)
val iconColors: StateFlow<NotificationIconColors> =
- viewModel.iconColors.mapNotNull { it.iconColors(view.viewBounds) }.stateIn(this)
+ viewModel
+ .iconColors(displayId)
+ .mapNotNull { it.iconColors(view.viewBounds) }
+ .stateIn(this)
viewModel.icons.bindIcons(
logTag = "statusbar",
view = view,
@@ -79,11 +83,7 @@
notifyBindingFailures = { failureTracker.statusBarFailures = it },
viewStore = viewStore,
) { _, sbiv ->
- StatusBarIconViewBinder.bindIconColors(
- sbiv,
- iconColors,
- contrastColorUtil,
- )
+ StatusBarIconViewBinder.bindIconColors(sbiv, iconColors, contrastColorUtil)
}
}
launch { viewModel.bindIsolatedIcon(view, viewStore) }
@@ -194,8 +194,7 @@
combine(iconSizeFlow, iconHorizontalPaddingFlow, systemBarUtilsState.statusBarHeight) {
iconSize,
iconHPadding,
- statusBarHeight,
- ->
+ statusBarHeight ->
FrameLayout.LayoutParams(iconSize + 2 * iconHPadding, statusBarHeight)
}
.stateIn(this)
@@ -251,10 +250,7 @@
traceSection("addIcon") {
(sbiv.parent as? ViewGroup)?.run {
if (this !== view) {
- Log.wtf(
- TAG,
- "[$logTag] SBIV($notifKey) has an unexpected parent",
- )
+ Log.wtf(TAG, "[$logTag] SBIV($notifKey) has an unexpected parent")
}
// If the container was re-inflated and re-bound, then SBIVs might still
// be attached to the prior view.
@@ -271,7 +267,7 @@
launch {
launch {
layoutParams.collectTracingEach(
- tag = { "[$logTag] SBIV#bindLayoutParams" },
+ tag = { "[$logTag] SBIV#bindLayoutParams" }
) {
if (it != sbiv.layoutParams) {
sbiv.layoutParams = it
@@ -344,7 +340,7 @@
// a single SBIV instance for the group. Then this whole concept can go away.
private inline fun <R> NotificationIconContainer.withIconReplacements(
replacements: ArrayMap<String, StatusBarIcon>,
- block: () -> R
+ block: () -> R,
): R {
setReplacingIcons(replacements)
return block().also { setReplacingIcons(null) }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt
index 6b5642a..83f56a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt
@@ -20,7 +20,6 @@
import android.view.View
import com.android.app.tracing.traceSection
import com.android.internal.util.ContrastColorUtil
-import com.android.systemui.Flags
import com.android.systemui.res.R
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.StatusBarIconView.NO_COLOR
@@ -36,11 +35,9 @@
suspend fun bindColor(view: StatusBarIconView, color: Flow<Int>) {
color.collectTracingEach("SBIV#bindColor") { color ->
- // Don't change the icon color if an app icon experiment is enabled.
- if (!android.app.Flags.notificationsUseAppIcon()) {
- view.staticDrawableColor = color
- }
- // Continue changing the overflow dot color
+ // Set the color for the icons
+ view.staticDrawableColor = color
+ // Set the color for the overflow dot
view.setDecorColor(color)
}
}
@@ -59,14 +56,12 @@
contrastColorUtil: ContrastColorUtil,
) {
iconColors.collectTracingEach("SBIV#bindIconColors") { colors ->
- // Don't change the icon color if an app icon experiment is enabled.
- if (!android.app.Flags.notificationsUseAppIcon()) {
- val isPreL = java.lang.Boolean.TRUE == view.getTag(R.id.icon_is_pre_L)
- val isColorized = !isPreL || NotificationUtils.isGrayscale(view, contrastColorUtil)
- view.staticDrawableColor =
- if (isColorized) colors.staticDrawableColor(view.viewBounds) else NO_COLOR
- }
- // Continue changing the overflow dot color
+ // Set the icon color
+ val isPreL = java.lang.Boolean.TRUE == view.getTag(R.id.icon_is_pre_L)
+ val isColorized = !isPreL || NotificationUtils.isGrayscale(view, contrastColorUtil)
+ view.staticDrawableColor =
+ if (isColorized) colors.staticDrawableColor(view.viewBounds) else NO_COLOR
+ // Set the color for the overflow dot
view.setDecorColor(colors.tint)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
index a64f888..f0b0306 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt
@@ -45,8 +45,8 @@
class NotificationIconContainerStatusBarViewModel
@Inject
constructor(
- @Background bgContext: CoroutineContext,
- darkIconInteractor: DarkIconInteractor,
+ @Background private val bgContext: CoroutineContext,
+ private val darkIconInteractor: DarkIconInteractor,
iconsInteractor: StatusBarNotificationIconsInteractor,
headsUpIconInteractor: HeadsUpNotificationIconInteractor,
keyguardInteractor: KeyguardInteractor,
@@ -58,10 +58,9 @@
/** Are changes to the icon container animated? */
val animationsEnabled: Flow<Boolean> =
- combine(
- shadeInteractor.isShadeTouchable,
- keyguardInteractor.isKeyguardShowing,
- ) { panelTouchesEnabled, isKeyguardShowing ->
+ combine(shadeInteractor.isShadeTouchable, keyguardInteractor.isKeyguardShowing) {
+ panelTouchesEnabled,
+ isKeyguardShowing ->
panelTouchesEnabled && !isKeyguardShowing
}
.flowOn(bgContext)
@@ -69,8 +68,9 @@
.distinctUntilChanged()
/** The colors with which to display the notification icons. */
- val iconColors: Flow<NotificationIconColorLookup> =
- darkIconInteractor.darkState
+ fun iconColors(displayId: Int): Flow<NotificationIconColorLookup> =
+ darkIconInteractor
+ .darkState(displayId)
.map { (areas: Collection<Rect>, tint: Int) ->
NotificationIconColorLookup { viewBounds: Rect ->
if (DarkIconDispatcher.isInAreas(areas, viewBounds)) {
@@ -125,10 +125,8 @@
val isolatedIconLocation: Flow<Rect> =
headsUpIconInteractor.isolatedIconLocation.filterNotNull().conflate().distinctUntilChanged()
- private class IconColorsImpl(
- override val tint: Int,
- private val areas: Collection<Rect>,
- ) : NotificationIconColors {
+ private class IconColorsImpl(override val tint: Int, private val areas: Collection<Rect>) :
+ NotificationIconColors {
override fun staticDrawableColor(viewBounds: Rect): Int {
return if (DarkIconDispatcher.isInAreas(areas, viewBounds)) {
tint
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index b166def..2dcb706 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -95,7 +95,7 @@
private val smartReplyStateInflater: SmartReplyStateInflater,
private val notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
private val headsUpStyleProvider: HeadsUpStyleProvider,
- private val logger: NotificationRowContentBinderLogger
+ private val logger: NotificationRowContentBinderLogger,
) : NotificationRowContentBinder {
init {
@@ -110,7 +110,7 @@
@InflationFlag contentToBind: Int,
bindParams: BindParams,
forceInflate: Boolean,
- callback: InflationCallback?
+ callback: InflationCallback?,
) {
if (row.isRemoved) {
// We don't want to reinflate anything for removed notifications. Otherwise views might
@@ -147,7 +147,7 @@
/* isMediaFlagEnabled = */ smartReplyStateInflater,
notifLayoutInflaterFactoryProvider,
headsUpStyleProvider,
- logger
+ logger,
)
if (inflateSynchronously) {
task.onPostExecute(task.doInBackground())
@@ -165,7 +165,7 @@
@InflationFlag reInflateFlags: Int,
builder: Notification.Builder,
packageContext: Context,
- smartRepliesInflater: SmartReplyStateInflater
+ smartRepliesInflater: SmartReplyStateInflater,
): InflationProgress {
val systemUIContext = row.context
val result =
@@ -229,7 +229,7 @@
row,
remoteInputManager.remoteViewsOnClickHandler,
/* callback= */ null,
- logger
+ logger,
)
return result
}
@@ -246,7 +246,7 @@
override fun unbindContent(
entry: NotificationEntry,
row: ExpandableNotificationRow,
- @InflationFlag contentToUnbind: Int
+ @InflationFlag contentToUnbind: Int,
) {
logger.logUnbinding(entry, contentToUnbind)
var curFlag = 1
@@ -268,7 +268,7 @@
private fun freeNotificationView(
entry: NotificationEntry,
row: ExpandableNotificationRow,
- @InflationFlag inflateFlag: Int
+ @InflationFlag inflateFlag: Int,
) {
when (inflateFlag) {
FLAG_CONTENT_VIEW_CONTRACTED ->
@@ -319,7 +319,7 @@
*/
private fun cancelContentViewFrees(
row: ExpandableNotificationRow,
- @InflationFlag contentViews: Int
+ @InflationFlag contentViews: Int,
) {
if (contentViews and FLAG_CONTENT_VIEW_CONTRACTED != 0) {
row.privateLayout.removeContentInactiveRunnable(VISIBLE_TYPE_CONTRACTED)
@@ -372,7 +372,7 @@
private val smartRepliesInflater: SmartReplyStateInflater,
private val notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
private val headsUpStyleProvider: HeadsUpStyleProvider,
- private val logger: NotificationRowContentBinderLogger
+ private val logger: NotificationRowContentBinderLogger,
) : AsyncTask<Void, Void, Result<InflationProgress>>(), InflationCallback, InflationTask {
private val context: Context
get() = row.context
@@ -393,7 +393,7 @@
context.packageManager.getApplicationInfoAsUser(
packageName,
PackageManager.MATCH_UNINSTALLED_PACKAGES,
- userId
+ userId,
)
} catch (e: PackageManager.NameNotFoundException) {
return
@@ -442,11 +442,11 @@
notifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider,
headsUpStyleProvider = headsUpStyleProvider,
conversationProcessor = conversationProcessor,
- logger = logger
+ logger = logger,
)
logger.logAsyncTaskProgress(
entry,
- "getting existing smart reply state (on wrong thread!)"
+ "getting existing smart reply state (on wrong thread!)",
)
val previousSmartReplyState: InflatedSmartReplyState? = row.existingSmartReplyState
logger.logAsyncTaskProgress(entry, "inflating smart reply views")
@@ -469,7 +469,7 @@
reInflateFlags,
entry,
context,
- logger
+ logger,
)
}
}
@@ -483,7 +483,7 @@
reInflateFlags,
entry,
context,
- logger
+ logger,
)
}
}
@@ -513,7 +513,7 @@
row,
remoteViewClickHandler,
this /* callback */,
- logger
+ logger,
)
}
.onFailure { error -> handleError(error as Exception) }
@@ -530,7 +530,7 @@
Log.e(TAG, "couldn't inflate view for notification $ident", e)
callback?.handleInflationException(
row.entry,
- InflationException("Couldn't inflate contentViews$e")
+ InflationException("Couldn't inflate contentViews$e"),
)
// Cancel any image loading tasks, not useful any more
@@ -618,7 +618,7 @@
packageContext: Context,
previousSmartReplyState: InflatedSmartReplyState?,
inflater: SmartReplyStateInflater,
- logger: NotificationRowContentBinderLogger
+ logger: NotificationRowContentBinderLogger,
) {
val inflateContracted =
(reInflateFlags and FLAG_CONTENT_VIEW_CONTRACTED != 0 &&
@@ -641,7 +641,7 @@
packageContext,
entry,
previousSmartReplyState,
- result.inflatedSmartReplyState!!
+ result.inflatedSmartReplyState!!,
)
}
if (inflateHeadsUp) {
@@ -652,7 +652,7 @@
packageContext,
entry,
previousSmartReplyState,
- result.inflatedSmartReplyState!!
+ result.inflatedSmartReplyState!!,
)
}
}
@@ -670,7 +670,7 @@
notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
headsUpStyleProvider: HeadsUpStyleProvider,
conversationProcessor: ConversationNotificationProcessor,
- logger: NotificationRowContentBinderLogger
+ logger: NotificationRowContentBinderLogger,
): InflationProgress {
// process conversations and extract the messaging style
val messagingStyle =
@@ -713,7 +713,7 @@
logger.logAsyncTaskProgress(entry, "inflating public single line view model")
SingleLineViewInflater.inflateRedactedSingleLineViewModel(
systemUIContext,
- entry.ranking.isConversation
+ entry.ranking.isConversation,
)
} else null
@@ -746,7 +746,7 @@
row: ExpandableNotificationRow,
notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
headsUpStyleProvider: HeadsUpStyleProvider,
- logger: NotificationRowContentBinderLogger
+ logger: NotificationRowContentBinderLogger,
): NewRemoteViews {
return TraceUtils.trace("NotificationContentInflater.createRemoteViews") {
val entryForLogging: NotificationEntry = row.entry
@@ -754,7 +754,7 @@
if (reInflateFlags and FLAG_CONTENT_VIEW_CONTRACTED != 0) {
logger.logAsyncTaskProgress(
entryForLogging,
- "creating contracted remote view"
+ "creating contracted remote view",
)
createContentView(builder, isMinimized, usesIncreasedHeight)
} else null
@@ -762,7 +762,7 @@
if (reInflateFlags and FLAG_CONTENT_VIEW_EXPANDED != 0) {
logger.logAsyncTaskProgress(
entryForLogging,
- "creating expanded remote view"
+ "creating expanded remote view",
)
createExpandedView(builder, isMinimized)
} else null
@@ -770,7 +770,7 @@
if (reInflateFlags and FLAG_CONTENT_VIEW_HEADS_UP != 0) {
logger.logAsyncTaskProgress(
entryForLogging,
- "creating heads up remote view"
+ "creating heads up remote view",
)
val isHeadsUpCompact = headsUpStyleProvider.shouldApplyCompactStyle()
if (isHeadsUpCompact) {
@@ -791,7 +791,7 @@
) {
logger.logAsyncTaskProgress(
entryForLogging,
- "creating group summary remote view"
+ "creating group summary remote view",
)
builder.makeNotificationGroupHeader()
} else null
@@ -802,7 +802,7 @@
) {
logger.logAsyncTaskProgress(
entryForLogging,
- "creating low-priority group summary remote view"
+ "creating low-priority group summary remote view",
)
builder.makeLowPriorityContentView(true /* useRegularSubtext */)
} else null
@@ -812,7 +812,7 @@
expanded = expanded,
public = public,
normalGroupHeader = normalGroupHeader,
- minimizedGroupHeader = minimizedGroupHeader
+ minimizedGroupHeader = minimizedGroupHeader,
)
.withLayoutInflaterFactory(row, notifLayoutInflaterFactoryProvider)
}
@@ -820,7 +820,7 @@
private fun NewRemoteViews.withLayoutInflaterFactory(
row: ExpandableNotificationRow,
- provider: NotifLayoutInflaterFactory.Provider
+ provider: NotifLayoutInflaterFactory.Provider,
): NewRemoteViews {
contracted?.let {
it.layoutInflaterFactory = provider.provide(row, FLAG_CONTENT_VIEW_CONTRACTED)
@@ -848,7 +848,7 @@
row: ExpandableNotificationRow,
remoteViewClickHandler: InteractionHandler?,
callback: InflationCallback?,
- logger: NotificationRowContentBinderLogger
+ logger: NotificationRowContentBinderLogger,
): CancellationSignal {
Trace.beginAsyncSection(APPLY_TRACE_METHOD, System.identityHashCode(row))
val privateLayout = row.privateLayout
@@ -859,7 +859,7 @@
val isNewView =
!canReapplyRemoteView(
newView = result.remoteViews.contracted,
- oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_CONTRACTED)
+ oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_CONTRACTED),
)
val applyCallback: ApplyCallback =
object : ApplyCallback() {
@@ -890,7 +890,7 @@
existingWrapper = privateLayout.getVisibleWrapper(VISIBLE_TYPE_CONTRACTED),
runningInflations = runningInflations,
applyCallback = applyCallback,
- logger = logger
+ logger = logger,
)
}
flag = FLAG_CONTENT_VIEW_EXPANDED
@@ -898,7 +898,7 @@
val isNewView =
!canReapplyRemoteView(
newView = result.remoteViews.expanded,
- oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_EXPANDED)
+ oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_EXPANDED),
)
val applyCallback: ApplyCallback =
object : ApplyCallback() {
@@ -929,7 +929,7 @@
existingWrapper = privateLayout.getVisibleWrapper(VISIBLE_TYPE_EXPANDED),
runningInflations = runningInflations,
applyCallback = applyCallback,
- logger = logger
+ logger = logger,
)
}
flag = FLAG_CONTENT_VIEW_HEADS_UP
@@ -937,7 +937,7 @@
val isNewView =
!canReapplyRemoteView(
newView = result.remoteViews.headsUp,
- oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_HEADS_UP)
+ oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_HEADS_UP),
)
val applyCallback: ApplyCallback =
object : ApplyCallback() {
@@ -968,7 +968,7 @@
existingWrapper = privateLayout.getVisibleWrapper(VISIBLE_TYPE_HEADSUP),
runningInflations = runningInflations,
applyCallback = applyCallback,
- logger = logger
+ logger = logger,
)
}
flag = FLAG_CONTENT_VIEW_PUBLIC
@@ -976,7 +976,7 @@
val isNewView =
!canReapplyRemoteView(
newView = result.remoteViews.public,
- oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_PUBLIC)
+ oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_PUBLIC),
)
val applyCallback: ApplyCallback =
object : ApplyCallback() {
@@ -1007,7 +1007,7 @@
existingWrapper = publicLayout.getVisibleWrapper(VISIBLE_TYPE_CONTRACTED),
runningInflations = runningInflations,
applyCallback = applyCallback,
- logger = logger
+ logger = logger,
)
}
if (AsyncGroupHeaderViewInflation.isEnabled) {
@@ -1018,7 +1018,7 @@
!canReapplyRemoteView(
newView = result.remoteViews.normalGroupHeader,
oldView =
- remoteViewCache.getCachedView(entry, FLAG_GROUP_SUMMARY_HEADER)
+ remoteViewCache.getCachedView(entry, FLAG_GROUP_SUMMARY_HEADER),
)
val applyCallback: ApplyCallback =
object : ApplyCallback() {
@@ -1049,7 +1049,7 @@
existingWrapper = childrenContainer.notificationHeaderWrapper,
runningInflations = runningInflations,
applyCallback = applyCallback,
- logger = logger
+ logger = logger,
)
}
if (reInflateFlags and FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER != 0) {
@@ -1059,15 +1059,15 @@
oldView =
remoteViewCache.getCachedView(
entry,
- FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER
- )
+ FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER,
+ ),
)
val applyCallback: ApplyCallback =
object : ApplyCallback() {
override fun setResultView(v: View) {
logger.logAsyncTaskProgress(
entry,
- "low-priority group header view applied"
+ "low-priority group header view applied",
)
result.inflatedMinimizedGroupHeaderView =
v as NotificationHeaderView?
@@ -1095,7 +1095,7 @@
existingWrapper = childrenContainer.minimizedGroupHeaderWrapper,
runningInflations = runningInflations,
applyCallback = applyCallback,
- logger = logger
+ logger = logger,
)
}
}
@@ -1110,7 +1110,7 @@
callback,
entry,
row,
- logger
+ logger,
)
val cancellationSignal = CancellationSignal()
cancellationSignal.setOnCancelListener {
@@ -1142,7 +1142,7 @@
existingWrapper: NotificationViewWrapper?,
runningInflations: HashMap<Int, CancellationSignal>,
applyCallback: ApplyCallback,
- logger: NotificationRowContentBinderLogger
+ logger: NotificationRowContentBinderLogger,
) {
val newContentView: RemoteViews = applyCallback.remoteView
if (inflateSynchronously) {
@@ -1152,7 +1152,7 @@
newContentView.apply(
result.packageContext,
parentLayout,
- remoteViewClickHandler
+ remoteViewClickHandler,
)
validateView(v, entry, row.resources)
applyCallback.setResultView(v)
@@ -1162,7 +1162,7 @@
newContentView.reapply(
result.packageContext,
existingView,
- remoteViewClickHandler
+ remoteViewClickHandler,
)
validateView(existingView, entry, row.resources)
existingWrapper.onReinflated()
@@ -1174,7 +1174,7 @@
row.entry,
callback,
logger,
- "applying view synchronously"
+ "applying view synchronously",
)
// Add a running inflation to make sure we don't trigger callbacks.
// Safe to do because only happens in tests.
@@ -1199,7 +1199,7 @@
row.entry,
callback,
logger,
- "applied invalid view"
+ "applied invalid view",
)
runningInflations.remove(inflationId)
return
@@ -1219,7 +1219,7 @@
callback,
entry,
row,
- logger
+ logger,
)
}
@@ -1234,20 +1234,20 @@
newContentView.apply(
result.packageContext,
parentLayout,
- remoteViewClickHandler
+ remoteViewClickHandler,
)
} else {
newContentView.reapply(
result.packageContext,
existingView,
- remoteViewClickHandler
+ remoteViewClickHandler,
)
existingView!!
}
Log.wtf(
TAG,
"Async Inflation failed but normal inflation finished normally.",
- e
+ e,
)
onViewApplied(newView)
} catch (anotherException: Exception) {
@@ -1258,7 +1258,7 @@
row.entry,
callback,
logger,
- "applying view"
+ "applying view",
)
}
}
@@ -1270,7 +1270,7 @@
parentLayout,
inflationExecutor,
listener,
- remoteViewClickHandler
+ remoteViewClickHandler,
)
} else {
newContentView.reapplyAsync(
@@ -1278,7 +1278,7 @@
existingView,
inflationExecutor,
listener,
- remoteViewClickHandler
+ remoteViewClickHandler,
)
}
runningInflations[inflationId] = cancellationSignal
@@ -1299,7 +1299,7 @@
private fun satisfiesMinHeightRequirement(
view: View,
entry: NotificationEntry,
- resources: Resources
+ resources: Resources,
): Boolean {
return if (!requiresHeightCheck(entry)) {
true
@@ -1353,7 +1353,7 @@
notification: NotificationEntry,
callback: InflationCallback?,
logger: NotificationRowContentBinderLogger,
- logContext: String
+ logContext: String,
) {
Assert.isMainThread()
logger.logAsyncTaskException(notification, logContext, e)
@@ -1375,7 +1375,7 @@
endListener: InflationCallback?,
entry: NotificationEntry,
row: ExpandableNotificationRow,
- logger: NotificationRowContentBinderLogger
+ logger: NotificationRowContentBinderLogger,
): Boolean {
Assert.isMainThread()
if (runningInflations.isNotEmpty()) {
@@ -1439,19 +1439,19 @@
FLAG_CONTENT_VIEW_CONTRACTED,
result.remoteViews.contracted,
result.inflatedContentView,
- privateLayout::setContractedChild
+ privateLayout::setContractedChild,
)
remoteViewsUpdater.setContentView(
FLAG_CONTENT_VIEW_EXPANDED,
result.remoteViews.expanded,
result.inflatedExpandedView,
- privateLayout::setExpandedChild
+ privateLayout::setExpandedChild,
)
remoteViewsUpdater.setSmartReplies(
FLAG_CONTENT_VIEW_EXPANDED,
result.remoteViews.expanded,
result.expandedInflatedSmartReplies,
- privateLayout::setExpandedInflatedSmartReplies
+ privateLayout::setExpandedInflatedSmartReplies,
)
if (reInflateFlags and FLAG_CONTENT_VIEW_EXPANDED != 0) {
row.setExpandable(result.remoteViews.expanded != null)
@@ -1460,19 +1460,19 @@
FLAG_CONTENT_VIEW_HEADS_UP,
result.remoteViews.headsUp,
result.inflatedHeadsUpView,
- privateLayout::setHeadsUpChild
+ privateLayout::setHeadsUpChild,
)
remoteViewsUpdater.setSmartReplies(
FLAG_CONTENT_VIEW_HEADS_UP,
result.remoteViews.headsUp,
result.headsUpInflatedSmartReplies,
- privateLayout::setHeadsUpInflatedSmartReplies
+ privateLayout::setHeadsUpInflatedSmartReplies,
)
remoteViewsUpdater.setContentView(
FLAG_CONTENT_VIEW_PUBLIC,
result.remoteViews.public,
result.inflatedPublicView,
- publicLayout::setContractedChild
+ publicLayout::setContractedChild,
)
if (AsyncGroupHeaderViewInflation.isEnabled) {
remoteViewsUpdater.setContentView(
@@ -1540,7 +1540,7 @@
private fun createExpandedView(
builder: Notification.Builder,
- isMinimized: Boolean
+ isMinimized: Boolean,
): RemoteViews? {
@Suppress("DEPRECATION")
val bigContentView: RemoteViews? = builder.createBigContentView()
@@ -1558,7 +1558,7 @@
private fun createContentView(
builder: Notification.Builder,
isMinimized: Boolean,
- useLarge: Boolean
+ useLarge: Boolean,
): RemoteViews {
return if (isMinimized) {
builder.makeLowPriorityContentView(false /* useRegularSubtext */)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt
index 7177a7b..08c1d71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt
@@ -73,8 +73,8 @@
private val cache = NotifCollectionCache<Boolean>()
override fun shouldShowAppIcon(notification: StatusBarNotification, context: Context): Boolean {
- val packageContext = notification.getPackageContext(context)
return cache.getOrFetch(notification.packageName) {
+ val packageContext = notification.getPackageContext(context)
!belongsToHeadlessSystemApp(packageContext)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index f352123..b622def 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -203,11 +203,7 @@
addRemainingTransformTypes();
updateCropToPaddingForImageViews();
Notification n = row.getEntry().getSbn().getNotification();
- if (n.shouldUseAppIcon()) {
- mIcon.setTag(ImageTransformState.ICON_TAG, n.getAppIcon());
- } else {
- mIcon.setTag(ImageTransformState.ICON_TAG, n.getSmallIcon());
- }
+ mIcon.setTag(ImageTransformState.ICON_TAG, n.getSmallIcon());
// We need to reset all views that are no longer transforming in case a view was previously
// transformed, but now we decided to transform its container instead.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractor.kt
index 3a650aa..53d0c2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractor.kt
@@ -22,6 +22,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.shared.model.ScreenPowerState.SCREEN_ON
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
import com.android.systemui.util.animation.data.repository.AnimationStatusRepository
import com.android.systemui.util.kotlin.WithPrev
@@ -46,9 +47,9 @@
@Inject
constructor(
private val unfoldTransitionInteractor: UnfoldTransitionInteractor,
- private val configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
private val animationsStatus: AnimationStatusRepository,
- private val powerInteractor: PowerInteractor
+ private val powerInteractor: PowerInteractor,
) {
val shouldHideNotifications: Flow<Boolean>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
index e644815..b6ce708 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
@@ -47,7 +47,7 @@
constructor(
@ShadeDisplayAware private val context: Context,
private val splitShadeStateController: Lazy<SplitShadeStateController>,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
keyguardInteractor: KeyguardInteractor,
deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
largeScreenHeaderHelperLazy: Lazy<LargeScreenHeaderHelper>,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
index f75c89a..bffcae9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt
@@ -20,6 +20,7 @@
import android.view.View
import androidx.lifecycle.lifecycleScope
import com.android.app.tracing.TraceUtils.traceAsync
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.nano.MetricsProto
import com.android.systemui.common.ui.ConfigurationState
@@ -30,6 +31,7 @@
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.NotificationShelf
import com.android.systemui.statusbar.notification.NotificationActivityStarter
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
@@ -70,7 +72,6 @@
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
/** Binds a [NotificationStackScrollLayout] to its [view model][NotificationListViewModel]. */
class NotificationListViewBinder
@@ -78,7 +79,7 @@
constructor(
@Background private val backgroundDispatcher: CoroutineDispatcher,
private val hiderTracker: DisplaySwitchNotificationsHiderTracker,
- private val configuration: ConfigurationState,
+ @ShadeDisplayAware private val configuration: ConfigurationState,
private val falsingManager: FalsingManager,
private val hunBinder: HeadsUpNotificationViewBinder,
private val loggerOptional: Optional<NotificationStatsLogger>,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
index 4a76871..c5bef99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
@@ -28,6 +28,7 @@
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationScrollViewModel
import com.android.systemui.util.kotlin.FlowDumperImpl
@@ -48,7 +49,7 @@
@Main private val mainImmediateDispatcher: CoroutineDispatcher,
private val view: NotificationScrollView,
private val viewModelFactory: NotificationScrollViewModel.Factory,
- private val configuration: ConfigurationState,
+ @ShadeDisplayAware private val configuration: ConfigurationState,
) : FlowDumperImpl(dumpManager) {
private val viewLeftOffset = MutableStateFlow(0).dumpValue("viewLeftOffset")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 827e2bf..fb60f26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -72,6 +72,7 @@
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.LargeScreenHeaderHelper
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.model.ShadeMode.Dual
import com.android.systemui.shade.shared.model.ShadeMode.Single
@@ -116,7 +117,7 @@
dumpManager: DumpManager,
@Application applicationScope: CoroutineScope,
private val context: Context,
- configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
private val keyguardInteractor: KeyguardInteractor,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val shadeInteractor: ShadeInteractor,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
index 398c1d4..90b591f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
@@ -23,11 +23,15 @@
import android.graphics.Color;
import android.graphics.Rect;
import android.util.ArrayMap;
+import android.view.Display;
import android.widget.ImageView;
-import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedFactory;
+import dagger.assisted.AssistedInject;
+
import kotlinx.coroutines.flow.FlowKt;
import kotlinx.coroutines.flow.MutableStateFlow;
import kotlinx.coroutines.flow.StateFlow;
@@ -36,17 +40,15 @@
import java.io.PrintWriter;
import java.util.ArrayList;
-import javax.inject.Inject;
-
/**
*/
-@SysUISingleton
public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher,
LightBarTransitionsController.DarkIntensityApplier {
private final LightBarTransitionsController mTransitionsController;
private final ArrayList<Rect> mTintAreas = new ArrayList<>();
private final ArrayMap<Object, DarkReceiver> mReceivers = new ArrayMap<>();
+ private final DumpManager mDumpManager;
private int mIconTint = DEFAULT_ICON_TINT;
private int mContrastTint = DEFAULT_INVERSE_ICON_TINT;
@@ -61,14 +63,25 @@
private final MutableStateFlow<DarkChange> mDarkChangeFlow = StateFlowKt.MutableStateFlow(
DarkChange.EMPTY);
+ private final String mDumpableName;
+
+ /** */
+ @AssistedFactory
+ @FunctionalInterface
+ public interface Factory {
+ /** */
+ DarkIconDispatcherImpl create(int displayId, Context context);
+ }
+
/**
*/
- @Inject
+ @AssistedInject
public DarkIconDispatcherImpl(
- Context context,
+ @Assisted int displayId,
+ @Assisted Context context,
LightBarTransitionsController.Factory lightBarTransitionsControllerFactory,
DumpManager dumpManager) {
-
+ mDumpManager = dumpManager;
if (newStatusBarIcons()) {
mDarkModeIconColorSingleTone = Color.BLACK;
mLightModeIconColorSingleTone = Color.WHITE;
@@ -81,7 +94,19 @@
mTransitionsController = lightBarTransitionsControllerFactory.create(this);
- dumpManager.registerDumpable(getClass().getSimpleName(), this);
+ mDumpableName = getDumpableName(displayId);
+ dumpManager.registerNormalDumpable(mDumpableName, this);
+ }
+
+ @Override
+ public void stop() {
+ mDumpManager.unregisterDumpable(mDumpableName);
+ }
+
+ private String getDumpableName(int displayId) {
+ String dumpableNameSuffix =
+ displayId == Display.DEFAULT_DISPLAY ? "" : String.valueOf(displayId);
+ return getClass().getSimpleName() + dumpableNameSuffix;
}
public LightBarTransitionsController getTransitionsController() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index d0f4b6f..8de03d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -26,6 +26,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.ViewClippingUtil;
+import com.android.systemui.dagger.qualifiers.DisplaySpecific;
import com.android.systemui.flags.FeatureFlagsClassic;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -117,7 +118,7 @@
PhoneStatusBarTransitions phoneStatusBarTransitions,
KeyguardBypassController bypassController,
NotificationWakeUpCoordinator wakeUpCoordinator,
- DarkIconDispatcher darkIconDispatcher,
+ @DisplaySpecific DarkIconDispatcher darkIconDispatcher,
KeyguardStateController keyguardStateController,
CommandQueue commandQueue,
NotificationStackScrollLayoutController stackScrollerController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
index edc1f88..ccb9a11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
@@ -133,7 +133,7 @@
public LightBarControllerImpl(
@Assisted int displayId,
@Assisted CoroutineScope coroutineScope,
- DarkIconDispatcher darkIconDispatcher,
+ @Assisted DarkIconDispatcher darkIconDispatcher,
BatteryController batteryController,
NavigationModeController navModeController,
@Assisted StatusBarModePerDisplayRepository statusBarModeRepository,
@@ -487,6 +487,7 @@
LightBarControllerImpl create(
int displayId,
CoroutineScope coroutineScope,
+ DarkIconDispatcher darkIconDispatcher,
StatusBarModePerDisplayRepository statusBarModePerDisplayRepository);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index 4245494..16e023c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -27,6 +27,7 @@
import com.android.systemui.Flags
import com.android.systemui.Gefingerpoken
import com.android.systemui.battery.BatteryMeterView
+import com.android.systemui.dagger.qualifiers.DisplaySpecific
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.ENABLE_UNFOLD_STATUS_BAR_ANIMATIONS
import com.android.systemui.plugins.DarkIconDispatcher
@@ -341,7 +342,7 @@
private val viewUtil: ViewUtil,
private val configurationController: ConfigurationController,
private val statusOverlayHoverListenerFactory: StatusOverlayHoverListenerFactory,
- private val darkIconDispatcher: DarkIconDispatcher,
+ @DisplaySpecific private val darkIconDispatcher: DarkIconDispatcher,
private val statusBarContentInsetsProviderStore: StatusBarContentInsetsProviderStore,
) {
fun create(view: PhoneStatusBarView): PhoneStatusBarViewController {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
index c341bd3..394502b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
@@ -28,10 +28,13 @@
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.res.R
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
+import com.android.systemui.statusbar.data.repository.SysuiDarkIconDispatcherStore
import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
@@ -40,14 +43,14 @@
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
-import com.android.app.tracing.coroutines.launchTraced as launch
class StatusOverlayHoverListenerFactory
@Inject
constructor(
@Main private val resources: Resources,
private val configurationController: ConfigurationController,
- private val darkIconDispatcher: SysuiDarkIconDispatcher,
+ private val darkIconDispatcherStore: SysuiDarkIconDispatcherStore,
+ private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
) {
/** Creates listener always using the same light color for overlay */
@@ -63,7 +66,7 @@
* Creates listener using [DarkIconDispatcher] to determine light or dark color of the overlay
*/
fun createDarkAwareListener(view: View) =
- createDarkAwareListener(view, darkIconDispatcher.darkChangeFlow())
+ createDarkAwareListener(view, view.darkIconDispatcher.darkChangeFlow())
/**
* Creates listener using [DarkIconDispatcher] to determine light or dark color of the overlay
@@ -78,7 +81,7 @@
) =
createDarkAwareListener(
view,
- darkIconDispatcher.darkChangeFlow(),
+ view.darkIconDispatcher.darkChangeFlow(),
leftHoverMargin,
rightHoverMargin,
topHoverMargin,
@@ -92,8 +95,8 @@
fun createDarkAwareListener(view: View, darkFlow: StateFlow<DarkChange>) =
StatusOverlayHoverListener(
view,
- configurationController,
- resources,
+ view.statusBarConfigurationController,
+ view.resources,
darkFlow.map { toHoverTheme(view, it) },
)
@@ -107,8 +110,8 @@
) =
StatusOverlayHoverListener(
view,
- configurationController,
- resources,
+ view.statusBarConfigurationController,
+ view.resources,
darkFlow.map { toHoverTheme(view, it) },
leftHoverMargin,
rightHoverMargin,
@@ -116,6 +119,12 @@
bottomHoverMargin,
)
+ private val View.statusBarConfigurationController
+ get() = statusBarConfigurationControllerStore.forDisplay(context.displayId)
+
+ private val View.darkIconDispatcher
+ get() = darkIconDispatcherStore.forDisplay(context.displayId)
+
private fun toHoverTheme(view: View, darkChange: DarkChange): HoverTheme {
val calculatedTint = DarkIconDispatcher.getTint(darkChange.areas, view, darkChange.tint)
// currently calculated tint is either white or some shade of black.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt
index ba377497..49356eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.phone.data.repository
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
+import com.android.systemui.statusbar.data.repository.SysuiDarkIconDispatcherStore
import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange
import dagger.Binds
import dagger.Module
@@ -25,16 +25,16 @@
/** Dark-mode state for tinting icons. */
interface DarkIconRepository {
- val darkState: StateFlow<DarkChange>
+ fun darkState(displayId: Int): StateFlow<DarkChange>
}
@SysUISingleton
class DarkIconRepositoryImpl
@Inject
-constructor(
- darkIconDispatcher: SysuiDarkIconDispatcher,
-) : DarkIconRepository {
- override val darkState: StateFlow<DarkChange> = darkIconDispatcher.darkChangeFlow()
+constructor(private val darkIconDispatcherStore: SysuiDarkIconDispatcherStore) :
+ DarkIconRepository {
+ override fun darkState(displayId: Int): StateFlow<DarkChange> =
+ darkIconDispatcherStore.forDisplay(displayId).darkChangeFlow()
}
@Module
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/DarkIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/DarkIconInteractor.kt
index 72f4540..095f0cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/DarkIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/DarkIconInteractor.kt
@@ -22,7 +22,8 @@
import kotlinx.coroutines.flow.map
/** States pertaining to calculating colors for icons in dark mode. */
-class DarkIconInteractor @Inject constructor(repository: DarkIconRepository) {
+class DarkIconInteractor @Inject constructor(private val repository: DarkIconRepository) {
/** Dark-mode state for tinting icons. */
- val darkState: Flow<DarkState> = repository.darkState.map { DarkState(it.areas, it.tint) }
+ fun darkState(displayId: Int): Flow<DarkState> =
+ repository.darkState(displayId).map { DarkState(it.areas, it.tint) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 013141b..5cc4476 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -351,8 +351,11 @@
mStatusBar.restoreHierarchyState(
savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
}
- mDarkIconManager = mDarkIconManagerFactory.create(
- view.findViewById(R.id.statusIcons), StatusBarLocation.HOME);
+ mDarkIconManager =
+ mDarkIconManagerFactory.create(
+ view.findViewById(R.id.statusIcons),
+ StatusBarLocation.HOME,
+ mHomeStatusBarComponent.getDarkIconDispatcher());
mDarkIconManager.setShouldLog(true);
updateBlockedIcons();
mStatusBarIconController.addIconGroup(mDarkIconManager);
@@ -496,11 +499,12 @@
NotificationIconContainer notificationIcons =
notificationIconArea.requireViewById(R.id.notificationIcons);
mNotificationIconAreaInner = notificationIcons;
- if (getContext().getDisplayId() == Display.DEFAULT_DISPLAY) {
+ int displayId = mHomeStatusBarComponent.getDisplayId();
+ if (displayId == Display.DEFAULT_DISPLAY) {
//TODO(b/369337701): implement notification icons for all displays.
// Currently if we try to bind for all displays, there is a crash, because the same
// notification icon view can't have multiple parents.
- mNicBindingDisposable = mNicViewBinder.bindWhileAttached(notificationIcons);
+ mNicBindingDisposable = mNicViewBinder.bindWhileAttached(notificationIcons, displayId);
}
if (!StatusBarSimpleFragment.isEnabled()) {
@@ -939,7 +943,9 @@
if (mCarrierConfigTracker.getShowOperatorNameInStatusBarConfig(subId)) {
View view = mStatusBar.findViewById(R.id.operator_name);
mOperatorNameViewController =
- mOperatorNameViewControllerFactory.create((OperatorNameView) view);
+ mOperatorNameViewControllerFactory.create(
+ (OperatorNameView) view,
+ mHomeStatusBarComponent.getDarkIconDispatcher());
mOperatorNameViewController.init();
// This view should not be visible on lock-screen
if (mKeyguardStateController.isShowing()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java
index d4cb625..f8ad0f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java
@@ -17,7 +17,9 @@
package com.android.systemui.statusbar.phone.fragment.dagger;
import com.android.systemui.battery.BatteryMeterViewController;
+import com.android.systemui.dagger.qualifiers.DisplaySpecific;
import com.android.systemui.dagger.qualifiers.RootView;
+import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
import com.android.systemui.statusbar.phone.LegacyLightsOutNotifController;
@@ -121,4 +123,12 @@
/** */
StatusBarBoundsProvider getBoundsProvider();
+
+ /** */
+ @DisplaySpecific
+ DarkIconDispatcher getDarkIconDispatcher();
+
+ /** */
+ @DisplaySpecific
+ int getDisplayId();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java
index 45c53b0..182f8d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java
@@ -22,8 +22,10 @@
import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.dagger.qualifiers.DisplaySpecific;
import com.android.systemui.dagger.qualifiers.RootView;
+import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.HeadsUpStatusBarView;
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore;
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore;
import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
@@ -164,4 +166,12 @@
return store.forDisplay(displayId);
}
+ /** */
+ @Provides
+ @HomeStatusBarScope
+ @DisplaySpecific
+ static DarkIconDispatcher darkIconDispatcher(
+ @DisplaySpecific int displayId, DarkIconDispatcherStore store) {
+ return store.forDisplay(displayId);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/DarkIconManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/DarkIconManager.java
index 6c30330..8d314ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/DarkIconManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/DarkIconManager.java
@@ -19,7 +19,6 @@
import android.widget.LinearLayout;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider;
@@ -29,35 +28,34 @@
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter;
import com.android.systemui.statusbar.pipeline.wifi.ui.WifiUiAdapter;
-import javax.inject.Inject;
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedFactory;
+import dagger.assisted.AssistedInject;
-/**
- * Version of {@link IconManager} that observes state from the DarkIconDispatcher.
- */
+/** Version of {@link IconManager} that observes state from the {@link DarkIconDispatcher}. */
public class DarkIconManager extends IconManager {
private final DarkIconDispatcher mDarkIconDispatcher;
private final int mIconHorizontalMargin;
+ @AssistedInject
public DarkIconManager(
- LinearLayout linearLayout,
- StatusBarLocation location,
+ @Assisted LinearLayout linearLayout,
+ @Assisted StatusBarLocation location,
WifiUiAdapter wifiUiAdapter,
MobileUiAdapter mobileUiAdapter,
MobileContextProvider mobileContextProvider,
- DarkIconDispatcher darkIconDispatcher) {
- super(linearLayout,
- location,
- wifiUiAdapter,
- mobileUiAdapter,
- mobileContextProvider);
- mIconHorizontalMargin = mContext.getResources().getDimensionPixelSize(
- com.android.systemui.res.R.dimen.status_bar_icon_horizontal_margin);
+ @Assisted DarkIconDispatcher darkIconDispatcher) {
+ super(linearLayout, location, wifiUiAdapter, mobileUiAdapter, mobileContextProvider);
+ mIconHorizontalMargin =
+ mContext.getResources()
+ .getDimensionPixelSize(
+ com.android.systemui.res.R.dimen.status_bar_icon_horizontal_margin);
mDarkIconDispatcher = darkIconDispatcher;
}
@Override
- protected void onIconAdded(int index, String slot, boolean blocked,
- StatusBarIconHolder holder) {
+ protected void onIconAdded(
+ int index, String slot, boolean blocked, StatusBarIconHolder holder) {
StatusIconDisplayable view = addHolder(index, slot, blocked, holder);
mDarkIconDispatcher.addDarkReceiver(view);
}
@@ -106,34 +104,14 @@
super.exitDemoMode();
}
- @SysUISingleton
- public static class Factory {
- private final WifiUiAdapter mWifiUiAdapter;
- private final MobileContextProvider mMobileContextProvider;
- private final MobileUiAdapter mMobileUiAdapter;
- private final DarkIconDispatcher mDarkIconDispatcher;
+ /** */
+ @AssistedFactory
+ public interface Factory {
- @Inject
- public Factory(
- WifiUiAdapter wifiUiAdapter,
- MobileContextProvider mobileContextProvider,
- MobileUiAdapter mobileUiAdapter,
- DarkIconDispatcher darkIconDispatcher) {
- mWifiUiAdapter = wifiUiAdapter;
- mMobileContextProvider = mobileContextProvider;
- mMobileUiAdapter = mobileUiAdapter;
- mDarkIconDispatcher = darkIconDispatcher;
- }
-
- /** Creates a new {@link DarkIconManager} for the given view group and location. */
- public DarkIconManager create(LinearLayout group, StatusBarLocation location) {
- return new DarkIconManager(
- group,
- location,
- mWifiUiAdapter,
- mMobileUiAdapter,
- mMobileContextProvider,
- mDarkIconDispatcher);
- }
+ /** Creates a new {@link DarkIconManager}. */
+ DarkIconManager create(
+ LinearLayout group,
+ StatusBarLocation location,
+ DarkIconDispatcher darkIconDispatcher);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index a472318..247abc3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -31,7 +31,10 @@
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.res.R
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder
import com.android.systemui.statusbar.phone.NotificationIconContainer
import com.android.systemui.statusbar.phone.PhoneStatusBarView
@@ -44,7 +47,6 @@
import com.android.systemui.statusbar.pipeline.shared.ui.binder.StatusBarVisibilityChangeListener
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel
import javax.inject.Inject
-import com.android.app.tracing.coroutines.launchTraced as launch
/** Factory to simplify the dependency management for [StatusBarRoot] */
class StatusBarRootFactory
@@ -56,6 +58,7 @@
private val darkIconManagerFactory: DarkIconManager.Factory,
private val iconController: StatusBarIconController,
private val ongoingCallController: OngoingCallController,
+ private val darkIconDispatcherStore: DarkIconDispatcherStore,
) {
fun create(root: ViewGroup, andThen: (ViewGroup) -> Unit): ComposeView {
val composeView = ComposeView(root.context)
@@ -69,6 +72,7 @@
darkIconManagerFactory = darkIconManagerFactory,
iconController = iconController,
ongoingCallController = ongoingCallController,
+ darkIconDispatcher = darkIconDispatcherStore.forDisplay(root.context.displayId),
onViewCreated = andThen,
)
}
@@ -97,6 +101,7 @@
darkIconManagerFactory: DarkIconManager.Factory,
iconController: StatusBarIconController,
ongoingCallController: OngoingCallController,
+ darkIconDispatcher: DarkIconDispatcher,
onViewCreated: (ViewGroup) -> Unit,
) {
// None of these methods are used when [StatusBarSimpleFragment] is on.
@@ -135,7 +140,11 @@
phoneStatusBarView.requireViewById<StatusIconContainer>(R.id.statusIcons)
// TODO(b/364360986): turn this into a repo/intr/viewmodel
val darkIconManager =
- darkIconManagerFactory.create(statusIconContainer, StatusBarLocation.HOME)
+ darkIconManagerFactory.create(
+ statusIconContainer,
+ StatusBarLocation.HOME,
+ darkIconDispatcher,
+ )
iconController.addIconGroup(darkIconManager)
// TODO(b/372657935): This won't be needed once OngoingCallController is
@@ -157,9 +166,13 @@
// TODO(b/369337701): implement notification icons for all displays.
// Currently if we try to bind for all displays, there is a crash, because the
// same notification icon view can't have multiple parents.
- if (context.displayId == Display.DEFAULT_DISPLAY) {
+ val displayId = context.displayId
+ if (displayId == Display.DEFAULT_DISPLAY) {
scope.launch {
- notificationIconsBinder.bindWhileAttached(notificationIconContainer)
+ notificationIconsBinder.bindWhileAttached(
+ notificationIconContainer,
+ displayId,
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractor.kt
index 03499cb..885a2b0 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractor.kt
@@ -19,6 +19,7 @@
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.unfold.data.repository.UnfoldTransitionRepository
import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionFinished
import com.android.systemui.unfold.data.repository.UnfoldTransitionStatus.TransitionInProgress
@@ -41,7 +42,7 @@
@Inject
constructor(
private val repository: UnfoldTransitionRepository,
- private val configurationInteractor: ConfigurationInteractor,
+ @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
) {
/** Returns availability of fold/unfold transitions on the device */
val isAvailable: Boolean
diff --git a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
index 493aa8c..f20ce63 100644
--- a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
@@ -19,12 +19,16 @@
import android.annotation.SuppressLint
import android.annotation.UserIdInt
+import android.app.admin.DevicePolicyManager
import android.content.Context
+import android.content.IntentFilter
import android.content.pm.UserInfo
import android.os.UserHandle
import android.os.UserManager
import android.provider.Settings
import androidx.annotation.VisibleForTesting
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
@@ -38,6 +42,7 @@
import com.android.systemui.user.data.model.UserSwitcherSettingsModel
import com.android.systemui.util.settings.GlobalSettings
import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -49,11 +54,12 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
@@ -100,6 +106,9 @@
/** Whether refresh users should be paused. */
var isRefreshUsersPaused: Boolean
+ /** Whether logout for secondary users is enabled by admin device policy. */
+ val isSecondaryUserLogoutEnabled: StateFlow<Boolean>
+
/** Asynchronously refresh the list of users. This will cause [userInfos] to be updated. */
fun refreshUsers()
@@ -109,6 +118,9 @@
fun isUserSwitcherEnabled(): Boolean
+ /** Performs logout logout for secondary users. */
+ suspend fun logOutSecondaryUser()
+
/**
* Returns the user ID of the "main user" of the device. This user may have access to certain
* features which are limited to at most one user. There will never be more than one main user
@@ -137,6 +149,8 @@
@Background private val backgroundDispatcher: CoroutineDispatcher,
private val globalSettings: GlobalSettings,
private val tracker: UserTracker,
+ private val devicePolicyManager: DevicePolicyManager,
+ private val broadcastDispatcher: BroadcastDispatcher,
) : UserRepository {
private val _userSwitcherSettings: StateFlow<UserSwitcherSettingsModel> =
@@ -147,7 +161,7 @@
SETTING_SIMPLE_USER_SWITCHER,
Settings.Global.ADD_USERS_WHEN_LOCKED,
Settings.Global.USER_SWITCHER_ENABLED,
- ),
+ )
)
.onStart { emit(Unit) } // Forces an initial update.
.map { getSettings() }
@@ -163,6 +177,7 @@
override var mainUserId: Int = UserHandle.USER_NULL
private set
+
override var lastSelectedNonGuestUserId: Int = UserHandle.USER_NULL
private set
@@ -221,12 +236,51 @@
.stateIn(
applicationScope,
SharingStarted.Eagerly,
- initialValue = SelectedUserModel(tracker.userInfo, currentSelectionStatus)
+ initialValue = SelectedUserModel(tracker.userInfo, currentSelectionStatus),
)
}
override val selectedUserInfo: Flow<UserInfo> = selectedUser.map { it.userInfo }
+ /** Whether the secondary user logout is enabled by the admin device policy. */
+ private val isSecondaryUserLogoutSupported: Flow<Boolean> =
+ broadcastDispatcher
+ .broadcastFlow(
+ filter =
+ IntentFilter(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED)
+ ) { intent, _ ->
+ if (
+ DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED == intent.action
+ ) {
+ Unit
+ } else {
+ null
+ }
+ }
+ .filterNotNull()
+ .onStart { emit(Unit) }
+ .map { _ -> devicePolicyManager.isLogoutEnabled() }
+ .flowOn(backgroundDispatcher)
+
+ @SuppressLint("MissingPermission")
+ override val isSecondaryUserLogoutEnabled: StateFlow<Boolean> =
+ selectedUser
+ .flatMapLatestConflated { selectedUser ->
+ if (selectedUser.isEligibleForLogout()) {
+ isSecondaryUserLogoutSupported
+ } else {
+ flowOf(false)
+ }
+ }
+ .stateIn(applicationScope, SharingStarted.Eagerly, false)
+
+ @SuppressLint("MissingPermission")
+ override suspend fun logOutSecondaryUser() {
+ if (isSecondaryUserLogoutEnabled.value) {
+ withContext(backgroundDispatcher) { devicePolicyManager.logoutUser() }
+ }
+ }
+
@SuppressLint("MissingPermission")
override fun refreshUsers() {
applicationScope.launch {
@@ -277,10 +331,7 @@
) != 0
val isAddUsersFromLockscreen =
- globalSettings.getInt(
- Settings.Global.ADD_USERS_WHEN_LOCKED,
- 0,
- ) != 0
+ globalSettings.getInt(Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0
val isUserSwitcherEnabled =
globalSettings.getInt(
@@ -309,3 +360,11 @@
@VisibleForTesting const val SETTING_SIMPLE_USER_SWITCHER = "lockscreenSimpleUserSwitcher"
}
}
+
+fun SelectedUserModel.isEligibleForLogout(): Boolean {
+ // TODO(b/206032495): should call mDevicePolicyManager.getLogoutUserId() instead of
+ // hardcode it to USER_SYSTEM so it properly supports headless system user mode
+ // (and then call mDevicePolicyManager.clearLogoutUser() after switched)
+ return selectionStatus == SelectionStatus.SELECTION_COMPLETE &&
+ userInfo.id != android.os.UserHandle.USER_SYSTEM
+}
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserLogoutInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserLogoutInteractor.kt
new file mode 100644
index 0000000..154f1dc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserLogoutInteractor.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.user.domain.interactor
+
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.user.data.repository.UserRepository
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.StateFlow
+
+/** Encapsulates business logic to for the logout. */
+@SysUISingleton
+class UserLogoutInteractor
+@Inject
+constructor(
+ private val userRepository: UserRepository,
+ @Application private val applicationScope: CoroutineScope,
+) {
+ val isLogoutEnabled: StateFlow<Boolean> = userRepository.isSecondaryUserLogoutEnabled
+
+ fun logOut() {
+ if (userRepository.isSecondaryUserLogoutEnabled.value) {
+ applicationScope.launch { userRepository.logOutSecondaryUser() }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepository.kt
index 71335ec..bc3726d 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepository.kt
@@ -30,6 +30,7 @@
* Repository for observing values of [Settings.Secure] for the currently active user. That means
* when user is switched and the new user has different value, flow will emit new value.
*/
+// TODO: b/377244768 - Make internal once call sites inject SecureSettingsRepository instead.
@SysUISingleton
class UserAwareSecureSettingsRepository
@Inject
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt
index a31b8d9..49a0f14 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt
@@ -16,7 +16,6 @@
package com.android.systemui.util.settings.repository
-import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
@@ -34,10 +33,10 @@
/**
* Repository for observing values of a [UserSettingsProxy], for the currently active user. That
- * means that when user is switched and the new user has a different value, the flow will emit the
- * new value.
+ * means that when the user is switched and the new user has a different value, the flow will emit
+ * the new value.
*/
-@SysUISingleton
+// TODO: b/377244768 - Make internal when UserAwareSecureSettingsRepository can be made internal.
@OptIn(ExperimentalCoroutinesApi::class)
abstract class UserAwareSettingsRepository(
private val userSettings: UserSettingsProxy,
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSystemSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSystemSettingsRepository.kt
index 8b1fca5..4b01ded 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSystemSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSystemSettingsRepository.kt
@@ -17,12 +17,10 @@
package com.android.systemui.util.settings.repository
import android.provider.Settings
-import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.shared.settings.data.repository.SystemSettingsRepository
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.settings.SystemSettings
-import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineDispatcher
@@ -30,10 +28,8 @@
* Repository for observing values of [Settings.Secure] for the currently active user. That means
* when user is switched and the new user has different value, flow will emit new value.
*/
-@SysUISingleton
-class UserAwareSystemSettingsRepository
-@Inject
-constructor(
+// TODO: b/377244768 - Make internal once call sites inject SystemSettingsRepository instead.
+class UserAwareSystemSettingsRepository(
systemSettings: SystemSettings,
userRepository: UserRepository,
@Background backgroundDispatcher: CoroutineDispatcher,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt
index f7ad320..9440a93 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogComponent.kt
@@ -18,6 +18,7 @@
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderComponent
import dagger.BindsInstance
import dagger.Subcomponent
import kotlinx.coroutines.CoroutineScope
@@ -40,6 +41,8 @@
@VolumeDialogScope fun volumeDialog(): com.android.systemui.volume.dialog.VolumeDialog
+ fun sliderComponentFactory(): VolumeDialogSliderComponent.Factory
+
@Subcomponent.Factory
interface Factory {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt
new file mode 100644
index 0000000..538ee47
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.volume.dialog.sliders.dagger
+
+import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
+import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSliderViewBinder
+import dagger.BindsInstance
+import dagger.Subcomponent
+
+/**
+ * This component hosts all the stuff, that Volume Dialog sliders need. It's recreated alongside
+ * each slider view.
+ */
+@VolumeDialogSliderScope
+@Subcomponent
+interface VolumeDialogSliderComponent {
+
+ fun sliderViewBinder(): VolumeDialogSliderViewBinder
+
+ @Subcomponent.Factory
+ interface Factory {
+
+ fun create(@BindsInstance sliderType: VolumeDialogSliderType): VolumeDialogSliderComponent
+ }
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderScope.kt
similarity index 65%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderScope.kt
index e21bf8f..9f5e0f6 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderScope.kt
@@ -14,6 +14,15 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package com.android.systemui.volume.dialog.sliders.dagger
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+import javax.inject.Scope
+
+/**
+ * Volume Panel Slider dependency injection scope. This scope is created for each of the volume
+ * sliders in the dialog.
+ */
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+@Scope
+annotation class VolumeDialogSliderScope
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInteractor.kt
index 876bf2c..2967fe8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInteractor.kt
@@ -17,22 +17,21 @@
package com.android.systemui.volume.dialog.sliders.domain.interactor
import com.android.systemui.plugins.VolumeDialogController
-import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogStateInteractor
import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.mapNotNull
/** Operates a state of particular slider of the Volume Dialog. */
+@VolumeDialogSliderScope
class VolumeDialogSliderInteractor
-@AssistedInject
+@Inject
constructor(
- @Assisted private val sliderType: VolumeDialogSliderType,
+ private val sliderType: VolumeDialogSliderType,
volumeDialogStateInteractor: VolumeDialogStateInteractor,
private val volumeDialogController: VolumeDialogController,
) {
@@ -56,11 +55,4 @@
setActiveStream(sliderType.audioStream)
}
}
-
- @VolumeDialogScope
- @AssistedFactory
- interface Factory {
-
- fun create(sliderType: VolumeDialogSliderType): VolumeDialogSliderInteractor
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
index 3bf8c54..1c231b5 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
@@ -24,16 +24,14 @@
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
-import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderViewModel
import com.android.systemui.volume.dialog.ui.utils.JankListenerFactory
import com.android.systemui.volume.dialog.ui.utils.awaitAnimation
import com.google.android.material.slider.LabelFormatter
import com.google.android.material.slider.Slider
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
import kotlin.math.roundToInt
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.launchIn
@@ -41,10 +39,11 @@
private const val PROGRESS_CHANGE_ANIMATION_DURATION_MS = 80L
+@VolumeDialogSliderScope
class VolumeDialogSliderViewBinder
-@AssistedInject
+@Inject
constructor(
- @Assisted private val viewModelProvider: () -> VolumeDialogSliderViewModel,
+ private val viewModelFactory: VolumeDialogSliderViewModel.Factory,
private val jankListenerFactory: JankListenerFactory,
) {
@@ -58,7 +57,7 @@
viewModel(
traceName = "VolumeDialogSliderViewBinder",
minWindowLifecycleState = WindowLifecycleState.ATTACHED,
- factory = { viewModelProvider() },
+ factory = { viewModelFactory.create() },
) { viewModel ->
sliderView.addOnChangeListener { _, value, fromUser ->
viewModel.setStreamVolume(value.roundToInt(), fromUser)
@@ -85,15 +84,6 @@
)
}
}
-
- @AssistedFactory
- @VolumeDialogScope
- interface Factory {
-
- fun create(
- viewModelProvider: () -> VolumeDialogSliderViewModel
- ): VolumeDialogSliderViewBinder
- }
}
private suspend fun Slider.setValueAnimated(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
index 0a4e3f4..a17c1e5 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
@@ -28,7 +28,6 @@
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSlidersViewModel
import javax.inject.Inject
-import kotlin.math.abs
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -50,15 +49,17 @@
) { viewModel ->
viewModel.sliders
.onEach { uiModel ->
- uiModel.sliderViewBinder.bind(volumeDialog)
+ uiModel.sliderComponent.sliderViewBinder().bind(volumeDialog)
- val floatingSliderViewBinders = uiModel.floatingSliderViewBinders
+ val floatingSliderViewBinders = uiModel.floatingSliderComponent
floatingSlidersContainer.ensureChildCount(
viewLayoutId = R.layout.volume_dialog_slider_floating,
count = floatingSliderViewBinders.size,
)
- floatingSliderViewBinders.fastForEachIndexed { index, viewBinder ->
- viewBinder.bind(floatingSlidersContainer.getChildAt(index))
+ floatingSliderViewBinders.fastForEachIndexed { index, sliderComponent ->
+ sliderComponent
+ .sliderViewBinder()
+ .bind(floatingSlidersContainer.getChildAt(index))
}
}
.launchIn(this)
@@ -76,7 +77,7 @@
}
childCountDelta < 0 -> {
val inflater = LayoutInflater.from(context)
- repeat(abs(childCountDelta)) { inflater.inflate(viewLayoutId, this, true) }
+ repeat(-childCountDelta) { inflater.inflate(viewLayoutId, this, true) }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
index ea0b49d..cf04d45 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
@@ -22,7 +22,6 @@
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSliderInteractor
-import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope
@@ -53,7 +52,7 @@
class VolumeDialogSliderViewModel
@AssistedInject
constructor(
- @Assisted private val interactor: VolumeDialogSliderInteractor,
+ private val interactor: VolumeDialogSliderInteractor,
private val visibilityInteractor: VolumeDialogVisibilityInteractor,
@VolumeDialog private val coroutineScope: CoroutineScope,
private val systemClock: SystemClock,
@@ -90,11 +89,11 @@
private fun getTimestampMillis(): Long = systemClock.uptimeMillis()
+ private data class VolumeUpdate(val newVolumeLevel: Int, val timestampMillis: Long)
+
@AssistedFactory
interface Factory {
- fun create(interactor: VolumeDialogSliderInteractor): VolumeDialogSliderViewModel
+ fun create(): VolumeDialogSliderViewModel
}
-
- private data class VolumeUpdate(val newVolumeLevel: Int, val timestampMillis: Long)
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSlidersViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSlidersViewModel.kt
index b5b292f..d197223 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSlidersViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSlidersViewModel.kt
@@ -17,16 +17,13 @@
package com.android.systemui.volume.dialog.sliders.ui.viewmodel
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
-import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSliderInteractor
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderComponent
import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSlidersInteractor
-import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
-import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSliderViewBinder
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@@ -36,29 +33,21 @@
constructor(
@VolumeDialog coroutineScope: CoroutineScope,
private val slidersInteractor: VolumeDialogSlidersInteractor,
- private val sliderInteractorFactory: VolumeDialogSliderInteractor.Factory,
- private val sliderViewModelFactory: VolumeDialogSliderViewModel.Factory,
- private val sliderViewBinderFactory: VolumeDialogSliderViewBinder.Factory,
+ private val sliderComponentFactory: VolumeDialogSliderComponent.Factory,
) {
val sliders: Flow<VolumeDialogSliderUiModel> =
slidersInteractor.sliders
- .distinctUntilChanged()
.map { slidersModel ->
VolumeDialogSliderUiModel(
- sliderViewBinder = createSliderViewBinder(slidersModel.slider),
- floatingSliderViewBinders =
- slidersModel.floatingSliders.map(::createSliderViewBinder),
+ sliderComponent = sliderComponentFactory.create(slidersModel.slider),
+ floatingSliderComponent =
+ slidersModel.floatingSliders.map(sliderComponentFactory::create),
)
}
.stateIn(coroutineScope, SharingStarted.Eagerly, null)
.filterNotNull()
- private fun createSliderViewBinder(type: VolumeDialogSliderType): VolumeDialogSliderViewBinder =
- sliderViewBinderFactory.create {
- sliderViewModelFactory.create(sliderInteractorFactory.create(type))
- }
-
@AssistedFactory
interface Factory {
@@ -68,6 +57,6 @@
/** Models slider ui */
data class VolumeDialogSliderUiModel(
- val sliderViewBinder: VolumeDialogSliderViewBinder,
- val floatingSliderViewBinders: List<VolumeDialogSliderViewBinder>,
+ val sliderComponent: VolumeDialogSliderComponent,
+ val floatingSliderComponent: List<VolumeDialogSliderComponent>,
)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt
index 9be669f..869a6a2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogViewModel.kt
@@ -18,16 +18,19 @@
import android.content.Context
import com.android.systemui.res.R
+import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogStateInteractor
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
+import com.android.systemui.volume.dialog.shared.model.VolumeDialogStateModel
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
import com.android.systemui.volume.dialog.shared.model.streamLabel
-import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSliderInteractor
import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSlidersInteractor
+import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
/** Provides a state for the Volume Dialog. */
@@ -38,18 +41,21 @@
private val context: Context,
dialogVisibilityInteractor: VolumeDialogVisibilityInteractor,
volumeDialogSlidersInteractor: VolumeDialogSlidersInteractor,
- private val volumeDialogSliderInteractorFactory: VolumeDialogSliderInteractor.Factory,
+ volumeDialogStateInteractor: VolumeDialogStateInteractor,
) {
val dialogVisibilityModel: Flow<VolumeDialogVisibilityModel> =
dialogVisibilityInteractor.dialogVisibility
val dialogTitle: Flow<String> =
- volumeDialogSlidersInteractor.sliders.flatMapLatest { slidersModel ->
- val interactor = volumeDialogSliderInteractorFactory.create(slidersModel.slider)
- interactor.slider.map { sliderModel ->
- context.getString(R.string.volume_dialog_title, sliderModel.streamLabel(context))
+ combine(
+ volumeDialogStateInteractor.volumeDialogState,
+ volumeDialogSlidersInteractor.sliders.map { it.slider },
+ ) { state: VolumeDialogStateModel, sliderType: VolumeDialogSliderType ->
+ state.streamModels[sliderType.audioStream]?.let { model ->
+ context.getString(R.string.volume_dialog_title, model.streamLabel(context))
+ }
}
- }
+ .filterNotNull()
@AssistedFactory
interface Factory {
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching.json b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withAnimator.json
similarity index 100%
rename from packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching.json
rename to packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withAnimator.json
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching_withSpring.json b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withSpring.json
similarity index 82%
rename from packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching_withSpring.json
rename to packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withSpring.json
index a840d3c..7abff2c 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching_withSpring.json
+++ b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenLaunching_withSpring.json
@@ -33,118 +33,118 @@
"bottom": 0
},
{
- "left": 94,
- "top": 284,
- "right": 206,
+ "left": 104,
+ "top": 285,
+ "right": 215,
"bottom": 414
},
{
- "left": 83,
- "top": 251,
- "right": 219,
+ "left": 92,
+ "top": 252,
+ "right": 227,
"bottom": 447
},
{
- "left": 70,
- "top": 212,
- "right": 234,
- "bottom": 485
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
},
{
- "left": 57,
- "top": 173,
- "right": 250,
- "bottom": 522
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
},
{
- "left": 46,
- "top": 139,
- "right": 264,
- "bottom": 555
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
},
{
- "left": 36,
- "top": 109,
- "right": 276,
- "bottom": 584
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
},
{
- "left": 28,
- "top": 84,
- "right": 285,
- "bottom": 608
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
},
{
- "left": 21,
- "top": 65,
- "right": 293,
- "bottom": 627
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
},
{
- "left": 16,
- "top": 49,
- "right": 300,
- "bottom": 642
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
},
{
- "left": 12,
- "top": 36,
- "right": 305,
- "bottom": 653
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
},
{
- "left": 9,
- "top": 27,
- "right": 308,
- "bottom": 662
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
},
{
"left": 7,
- "top": 20,
+ "top": 24,
"right": 312,
- "bottom": 669
+ "bottom": 673
},
{
"left": 5,
- "top": 14,
+ "top": 18,
"right": 314,
- "bottom": 675
- },
- {
- "left": 4,
- "top": 11,
- "right": 315,
"bottom": 678
},
{
- "left": 3,
- "top": 8,
- "right": 316,
+ "left": 4,
+ "top": 13,
+ "right": 315,
"bottom": 681
},
{
- "left": 2,
- "top": 5,
- "right": 317,
+ "left": 3,
+ "top": 10,
+ "right": 316,
"bottom": 684
},
{
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
"left": 1,
"top": 4,
"right": 318,
- "bottom": 685
- },
- {
- "left": 1,
- "top": 3,
- "right": 318,
- "bottom": 686
+ "bottom": 688
},
{
"left": 0,
- "top": 2,
+ "top": 3,
"right": 319,
- "bottom": 687
+ "bottom": 688
}
]
},
@@ -371,5 +371,14 @@
0
]
}
- ]
+ ],
+ "\/\/metadata": {
+ "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimation_whenLaunching_withSpring.json",
+ "goldenIdentifier": "backgroundAnimation_whenLaunching_withSpring",
+ "testClassName": "TransitionAnimatorTest",
+ "testMethodName": "backgroundAnimation_whenLaunching[true]",
+ "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
+ "result": "FAILED",
+ "videoLocation": "TransitionAnimatorTest\/backgroundAnimation_whenLaunching_withSpring.actual.mp4"
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching.json b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withAnimator.json
similarity index 100%
copy from packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching.json
copy to packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withAnimator.json
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimation_whenReturning_withSpring.json b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withSpring.json
similarity index 82%
rename from packages/SystemUI/tests/goldens/backgroundAnimation_whenReturning_withSpring.json
rename to packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withSpring.json
index a840d3c..5619611 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimation_whenReturning_withSpring.json
+++ b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withFade_whenReturning_withSpring.json
@@ -33,118 +33,118 @@
"bottom": 0
},
{
- "left": 94,
- "top": 284,
- "right": 206,
+ "left": 104,
+ "top": 285,
+ "right": 215,
"bottom": 414
},
{
- "left": 83,
- "top": 251,
- "right": 219,
+ "left": 92,
+ "top": 252,
+ "right": 227,
"bottom": 447
},
{
- "left": 70,
- "top": 212,
- "right": 234,
- "bottom": 485
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
},
{
- "left": 57,
- "top": 173,
- "right": 250,
- "bottom": 522
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
},
{
- "left": 46,
- "top": 139,
- "right": 264,
- "bottom": 555
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
},
{
- "left": 36,
- "top": 109,
- "right": 276,
- "bottom": 584
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
},
{
- "left": 28,
- "top": 84,
- "right": 285,
- "bottom": 608
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
},
{
- "left": 21,
- "top": 65,
- "right": 293,
- "bottom": 627
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
},
{
- "left": 16,
- "top": 49,
- "right": 300,
- "bottom": 642
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
},
{
- "left": 12,
- "top": 36,
- "right": 305,
- "bottom": 653
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
},
{
- "left": 9,
- "top": 27,
- "right": 308,
- "bottom": 662
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
},
{
"left": 7,
- "top": 20,
+ "top": 24,
"right": 312,
- "bottom": 669
+ "bottom": 673
},
{
"left": 5,
- "top": 14,
+ "top": 18,
"right": 314,
- "bottom": 675
- },
- {
- "left": 4,
- "top": 11,
- "right": 315,
"bottom": 678
},
{
- "left": 3,
- "top": 8,
- "right": 316,
+ "left": 4,
+ "top": 13,
+ "right": 315,
"bottom": 681
},
{
- "left": 2,
- "top": 5,
- "right": 317,
+ "left": 3,
+ "top": 10,
+ "right": 316,
"bottom": 684
},
{
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
"left": 1,
"top": 4,
"right": 318,
- "bottom": 685
- },
- {
- "left": 1,
- "top": 3,
- "right": 318,
- "bottom": 686
+ "bottom": 688
},
{
"left": 0,
- "top": 2,
+ "top": 3,
"right": 319,
- "bottom": 687
+ "bottom": 688
}
]
},
@@ -371,5 +371,14 @@
0
]
}
- ]
+ ],
+ "\/\/metadata": {
+ "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimation_whenReturning_withSpring.json",
+ "goldenIdentifier": "backgroundAnimation_whenReturning_withSpring",
+ "testClassName": "TransitionAnimatorTest",
+ "testMethodName": "backgroundAnimation_whenReturning[true]",
+ "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
+ "result": "FAILED",
+ "videoLocation": "TransitionAnimatorTest\/backgroundAnimation_whenReturning_withSpring.actual.mp4"
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching.json b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withAnimator.json
similarity index 100%
rename from packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching.json
rename to packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withAnimator.json
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching_withSpring.json b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withSpring.json
similarity index 81%
copy from packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching_withSpring.json
copy to packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withSpring.json
index 18eedd4..825190b 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching_withSpring.json
+++ b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenLaunching_withSpring.json
@@ -33,118 +33,118 @@
"bottom": 0
},
{
- "left": 94,
- "top": 284,
- "right": 206,
+ "left": 104,
+ "top": 285,
+ "right": 215,
"bottom": 414
},
{
- "left": 83,
- "top": 251,
- "right": 219,
+ "left": 92,
+ "top": 252,
+ "right": 227,
"bottom": 447
},
{
- "left": 70,
- "top": 212,
- "right": 234,
- "bottom": 485
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
},
{
- "left": 57,
- "top": 173,
- "right": 250,
- "bottom": 522
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
},
{
- "left": 46,
- "top": 139,
- "right": 264,
- "bottom": 555
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
},
{
- "left": 36,
- "top": 109,
- "right": 276,
- "bottom": 584
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
},
{
- "left": 28,
- "top": 84,
- "right": 285,
- "bottom": 608
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
},
{
- "left": 21,
- "top": 65,
- "right": 293,
- "bottom": 627
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
},
{
- "left": 16,
- "top": 49,
- "right": 300,
- "bottom": 642
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
},
{
- "left": 12,
- "top": 36,
- "right": 305,
- "bottom": 653
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
},
{
- "left": 9,
- "top": 27,
- "right": 308,
- "bottom": 662
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
},
{
"left": 7,
- "top": 20,
+ "top": 24,
"right": 312,
- "bottom": 669
+ "bottom": 673
},
{
"left": 5,
- "top": 14,
+ "top": 18,
"right": 314,
- "bottom": 675
- },
- {
- "left": 4,
- "top": 11,
- "right": 315,
"bottom": 678
},
{
- "left": 3,
- "top": 8,
- "right": 316,
+ "left": 4,
+ "top": 13,
+ "right": 315,
"bottom": 681
},
{
- "left": 2,
- "top": 5,
- "right": 317,
+ "left": 3,
+ "top": 10,
+ "right": 316,
"bottom": 684
},
{
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
"left": 1,
"top": 4,
"right": 318,
- "bottom": 685
- },
- {
- "left": 1,
- "top": 3,
- "right": 318,
- "bottom": 686
+ "bottom": 688
},
{
"left": 0,
- "top": 2,
+ "top": 3,
"right": 319,
- "bottom": 687
+ "bottom": 688
}
]
},
@@ -371,5 +371,14 @@
0
]
}
- ]
+ ],
+ "\/\/metadata": {
+ "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimationWithoutFade_whenLaunching_withSpring.json",
+ "goldenIdentifier": "backgroundAnimationWithoutFade_whenLaunching_withSpring",
+ "testClassName": "TransitionAnimatorTest",
+ "testMethodName": "backgroundAnimationWithoutFade_whenLaunching[true]",
+ "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
+ "result": "FAILED",
+ "videoLocation": "TransitionAnimatorTest\/backgroundAnimationWithoutFade_whenLaunching_withSpring.actual.mp4"
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenReturning.json b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withAnimator.json
similarity index 100%
rename from packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenReturning.json
rename to packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withAnimator.json
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching_withSpring.json b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withSpring.json
similarity index 81%
rename from packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching_withSpring.json
rename to packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withSpring.json
index 18eedd4..63c2631 100644
--- a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching_withSpring.json
+++ b/packages/SystemUI/tests/goldens/backgroundAnimationTimeSeries_withoutFade_whenReturning_withSpring.json
@@ -33,118 +33,118 @@
"bottom": 0
},
{
- "left": 94,
- "top": 284,
- "right": 206,
+ "left": 104,
+ "top": 285,
+ "right": 215,
"bottom": 414
},
{
- "left": 83,
- "top": 251,
- "right": 219,
+ "left": 92,
+ "top": 252,
+ "right": 227,
"bottom": 447
},
{
- "left": 70,
- "top": 212,
- "right": 234,
- "bottom": 485
+ "left": 77,
+ "top": 213,
+ "right": 242,
+ "bottom": 486
},
{
- "left": 57,
- "top": 173,
- "right": 250,
- "bottom": 522
+ "left": 63,
+ "top": 175,
+ "right": 256,
+ "bottom": 524
},
{
- "left": 46,
- "top": 139,
- "right": 264,
- "bottom": 555
+ "left": 50,
+ "top": 141,
+ "right": 269,
+ "bottom": 558
},
{
- "left": 36,
- "top": 109,
- "right": 276,
- "bottom": 584
+ "left": 40,
+ "top": 112,
+ "right": 279,
+ "bottom": 587
},
{
- "left": 28,
- "top": 84,
- "right": 285,
- "bottom": 608
+ "left": 31,
+ "top": 88,
+ "right": 288,
+ "bottom": 611
},
{
- "left": 21,
- "top": 65,
- "right": 293,
- "bottom": 627
+ "left": 23,
+ "top": 68,
+ "right": 296,
+ "bottom": 631
},
{
- "left": 16,
- "top": 49,
- "right": 300,
- "bottom": 642
+ "left": 18,
+ "top": 53,
+ "right": 301,
+ "bottom": 646
},
{
- "left": 12,
- "top": 36,
- "right": 305,
- "bottom": 653
+ "left": 13,
+ "top": 41,
+ "right": 306,
+ "bottom": 658
},
{
- "left": 9,
- "top": 27,
- "right": 308,
- "bottom": 662
+ "left": 10,
+ "top": 31,
+ "right": 309,
+ "bottom": 667
},
{
"left": 7,
- "top": 20,
+ "top": 24,
"right": 312,
- "bottom": 669
+ "bottom": 673
},
{
"left": 5,
- "top": 14,
+ "top": 18,
"right": 314,
- "bottom": 675
- },
- {
- "left": 4,
- "top": 11,
- "right": 315,
"bottom": 678
},
{
- "left": 3,
- "top": 8,
- "right": 316,
+ "left": 4,
+ "top": 13,
+ "right": 315,
"bottom": 681
},
{
- "left": 2,
- "top": 5,
- "right": 317,
+ "left": 3,
+ "top": 10,
+ "right": 316,
"bottom": 684
},
{
+ "left": 2,
+ "top": 7,
+ "right": 317,
+ "bottom": 685
+ },
+ {
+ "left": 1,
+ "top": 5,
+ "right": 318,
+ "bottom": 687
+ },
+ {
"left": 1,
"top": 4,
"right": 318,
- "bottom": 685
- },
- {
- "left": 1,
- "top": 3,
- "right": 318,
- "bottom": 686
+ "bottom": 688
},
{
"left": 0,
- "top": 2,
+ "top": 3,
"right": 319,
- "bottom": 687
+ "bottom": 688
}
]
},
@@ -371,5 +371,14 @@
0
]
}
- ]
+ ],
+ "\/\/metadata": {
+ "goldenRepoPath": "frameworks\/base\/packages\/SystemUI\/tests\/goldens\/backgroundAnimationWithoutFade_whenReturning_withSpring.json",
+ "goldenIdentifier": "backgroundAnimationWithoutFade_whenReturning_withSpring",
+ "testClassName": "TransitionAnimatorTest",
+ "testMethodName": "backgroundAnimationWithoutFade_whenReturning[true]",
+ "deviceLocalPath": "\/data\/user\/0\/com.android.systemui.tests\/files\/platform_screenshots",
+ "result": "FAILED",
+ "videoLocation": "TransitionAnimatorTest\/backgroundAnimationWithoutFade_whenReturning_withSpring.actual.mp4"
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenReturning_withSpring.json b/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenReturning_withSpring.json
deleted file mode 100644
index 18eedd4..0000000
--- a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenReturning_withSpring.json
+++ /dev/null
@@ -1,375 +0,0 @@
-{
- "frame_ids": [
- 0,
- 16,
- 32,
- 48,
- 64,
- 80,
- 96,
- 112,
- 128,
- 144,
- 160,
- 176,
- 192,
- 208,
- 224,
- 240,
- 256,
- 272,
- 288,
- 304
- ],
- "features": [
- {
- "name": "bounds",
- "type": "rect",
- "data_points": [
- {
- "left": 0,
- "top": 0,
- "right": 0,
- "bottom": 0
- },
- {
- "left": 94,
- "top": 284,
- "right": 206,
- "bottom": 414
- },
- {
- "left": 83,
- "top": 251,
- "right": 219,
- "bottom": 447
- },
- {
- "left": 70,
- "top": 212,
- "right": 234,
- "bottom": 485
- },
- {
- "left": 57,
- "top": 173,
- "right": 250,
- "bottom": 522
- },
- {
- "left": 46,
- "top": 139,
- "right": 264,
- "bottom": 555
- },
- {
- "left": 36,
- "top": 109,
- "right": 276,
- "bottom": 584
- },
- {
- "left": 28,
- "top": 84,
- "right": 285,
- "bottom": 608
- },
- {
- "left": 21,
- "top": 65,
- "right": 293,
- "bottom": 627
- },
- {
- "left": 16,
- "top": 49,
- "right": 300,
- "bottom": 642
- },
- {
- "left": 12,
- "top": 36,
- "right": 305,
- "bottom": 653
- },
- {
- "left": 9,
- "top": 27,
- "right": 308,
- "bottom": 662
- },
- {
- "left": 7,
- "top": 20,
- "right": 312,
- "bottom": 669
- },
- {
- "left": 5,
- "top": 14,
- "right": 314,
- "bottom": 675
- },
- {
- "left": 4,
- "top": 11,
- "right": 315,
- "bottom": 678
- },
- {
- "left": 3,
- "top": 8,
- "right": 316,
- "bottom": 681
- },
- {
- "left": 2,
- "top": 5,
- "right": 317,
- "bottom": 684
- },
- {
- "left": 1,
- "top": 4,
- "right": 318,
- "bottom": 685
- },
- {
- "left": 1,
- "top": 3,
- "right": 318,
- "bottom": 686
- },
- {
- "left": 0,
- "top": 2,
- "right": 319,
- "bottom": 687
- }
- ]
- },
- {
- "name": "corner_radii",
- "type": "cornerRadii",
- "data_points": [
- null,
- {
- "top_left_x": 9.492916,
- "top_left_y": 9.492916,
- "top_right_x": 9.492916,
- "top_right_y": 9.492916,
- "bottom_right_x": 18.985832,
- "bottom_right_y": 18.985832,
- "bottom_left_x": 18.985832,
- "bottom_left_y": 18.985832
- },
- {
- "top_left_x": 8.381761,
- "top_left_y": 8.381761,
- "top_right_x": 8.381761,
- "top_right_y": 8.381761,
- "bottom_right_x": 16.763521,
- "bottom_right_y": 16.763521,
- "bottom_left_x": 16.763521,
- "bottom_left_y": 16.763521
- },
- {
- "top_left_x": 7.07397,
- "top_left_y": 7.07397,
- "top_right_x": 7.07397,
- "top_right_y": 7.07397,
- "bottom_right_x": 14.14794,
- "bottom_right_y": 14.14794,
- "bottom_left_x": 14.14794,
- "bottom_left_y": 14.14794
- },
- {
- "top_left_x": 5.7880254,
- "top_left_y": 5.7880254,
- "top_right_x": 5.7880254,
- "top_right_y": 5.7880254,
- "bottom_right_x": 11.576051,
- "bottom_right_y": 11.576051,
- "bottom_left_x": 11.576051,
- "bottom_left_y": 11.576051
- },
- {
- "top_left_x": 4.6295347,
- "top_left_y": 4.6295347,
- "top_right_x": 4.6295347,
- "top_right_y": 4.6295347,
- "bottom_right_x": 9.259069,
- "bottom_right_y": 9.259069,
- "bottom_left_x": 9.259069,
- "bottom_left_y": 9.259069
- },
- {
- "top_left_x": 3.638935,
- "top_left_y": 3.638935,
- "top_right_x": 3.638935,
- "top_right_y": 3.638935,
- "bottom_right_x": 7.27787,
- "bottom_right_y": 7.27787,
- "bottom_left_x": 7.27787,
- "bottom_left_y": 7.27787
- },
- {
- "top_left_x": 2.8209057,
- "top_left_y": 2.8209057,
- "top_right_x": 2.8209057,
- "top_right_y": 2.8209057,
- "bottom_right_x": 5.6418114,
- "bottom_right_y": 5.6418114,
- "bottom_left_x": 5.6418114,
- "bottom_left_y": 5.6418114
- },
- {
- "top_left_x": 2.1620893,
- "top_left_y": 2.1620893,
- "top_right_x": 2.1620893,
- "top_right_y": 2.1620893,
- "bottom_right_x": 4.3241787,
- "bottom_right_y": 4.3241787,
- "bottom_left_x": 4.3241787,
- "bottom_left_y": 4.3241787
- },
- {
- "top_left_x": 1.6414614,
- "top_left_y": 1.6414614,
- "top_right_x": 1.6414614,
- "top_right_y": 1.6414614,
- "bottom_right_x": 3.2829227,
- "bottom_right_y": 3.2829227,
- "bottom_left_x": 3.2829227,
- "bottom_left_y": 3.2829227
- },
- {
- "top_left_x": 1.2361269,
- "top_left_y": 1.2361269,
- "top_right_x": 1.2361269,
- "top_right_y": 1.2361269,
- "bottom_right_x": 2.4722538,
- "bottom_right_y": 2.4722538,
- "bottom_left_x": 2.4722538,
- "bottom_left_y": 2.4722538
- },
- {
- "top_left_x": 0.92435074,
- "top_left_y": 0.92435074,
- "top_right_x": 0.92435074,
- "top_right_y": 0.92435074,
- "bottom_right_x": 1.8487015,
- "bottom_right_y": 1.8487015,
- "bottom_left_x": 1.8487015,
- "bottom_left_y": 1.8487015
- },
- {
- "top_left_x": 0.68693924,
- "top_left_y": 0.68693924,
- "top_right_x": 0.68693924,
- "top_right_y": 0.68693924,
- "bottom_right_x": 1.3738785,
- "bottom_right_y": 1.3738785,
- "bottom_left_x": 1.3738785,
- "bottom_left_y": 1.3738785
- },
- {
- "top_left_x": 0.5076904,
- "top_left_y": 0.5076904,
- "top_right_x": 0.5076904,
- "top_right_y": 0.5076904,
- "bottom_right_x": 1.0153809,
- "bottom_right_y": 1.0153809,
- "bottom_left_x": 1.0153809,
- "bottom_left_y": 1.0153809
- },
- {
- "top_left_x": 0.3733511,
- "top_left_y": 0.3733511,
- "top_right_x": 0.3733511,
- "top_right_y": 0.3733511,
- "bottom_right_x": 0.7467022,
- "bottom_right_y": 0.7467022,
- "bottom_left_x": 0.7467022,
- "bottom_left_y": 0.7467022
- },
- {
- "top_left_x": 0.27331638,
- "top_left_y": 0.27331638,
- "top_right_x": 0.27331638,
- "top_right_y": 0.27331638,
- "bottom_right_x": 0.54663277,
- "bottom_right_y": 0.54663277,
- "bottom_left_x": 0.54663277,
- "bottom_left_y": 0.54663277
- },
- {
- "top_left_x": 0.19925308,
- "top_left_y": 0.19925308,
- "top_right_x": 0.19925308,
- "top_right_y": 0.19925308,
- "bottom_right_x": 0.39850616,
- "bottom_right_y": 0.39850616,
- "bottom_left_x": 0.39850616,
- "bottom_left_y": 0.39850616
- },
- {
- "top_left_x": 0.14470005,
- "top_left_y": 0.14470005,
- "top_right_x": 0.14470005,
- "top_right_y": 0.14470005,
- "bottom_right_x": 0.2894001,
- "bottom_right_y": 0.2894001,
- "bottom_left_x": 0.2894001,
- "bottom_left_y": 0.2894001
- },
- {
- "top_left_x": 0.10470486,
- "top_left_y": 0.10470486,
- "top_right_x": 0.10470486,
- "top_right_y": 0.10470486,
- "bottom_right_x": 0.20940971,
- "bottom_right_y": 0.20940971,
- "bottom_left_x": 0.20940971,
- "bottom_left_y": 0.20940971
- },
- {
- "top_left_x": 0.07550812,
- "top_left_y": 0.07550812,
- "top_right_x": 0.07550812,
- "top_right_y": 0.07550812,
- "bottom_right_x": 0.15101624,
- "bottom_right_y": 0.15101624,
- "bottom_left_x": 0.15101624,
- "bottom_left_y": 0.15101624
- }
- ]
- },
- {
- "name": "alpha",
- "type": "int",
- "data_points": [
- 0,
- 255,
- 255,
- 255,
- 255,
- 255,
- 255,
- 255,
- 255,
- 255,
- 249,
- 226,
- 192,
- 153,
- 112,
- 72,
- 34,
- 0,
- 0,
- 0
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimation_whenReturning.json b/packages/SystemUI/tests/goldens/backgroundAnimation_whenReturning.json
deleted file mode 100644
index aa80445..0000000
--- a/packages/SystemUI/tests/goldens/backgroundAnimation_whenReturning.json
+++ /dev/null
@@ -1,492 +0,0 @@
-{
- "frame_ids": [
- 0,
- 20,
- 40,
- 60,
- 80,
- 100,
- 120,
- 140,
- 160,
- 180,
- 200,
- 220,
- 240,
- 260,
- 280,
- 300,
- 320,
- 340,
- 360,
- 380,
- 400,
- 420,
- 440,
- 460,
- 480,
- 500
- ],
- "features": [
- {
- "name": "bounds",
- "type": "rect",
- "data_points": [
- {
- "left": 100,
- "top": 300,
- "right": 200,
- "bottom": 400
- },
- {
- "left": 99,
- "top": 296,
- "right": 202,
- "bottom": 404
- },
- {
- "left": 95,
- "top": 283,
- "right": 207,
- "bottom": 417
- },
- {
- "left": 86,
- "top": 256,
- "right": 219,
- "bottom": 443
- },
- {
- "left": 68,
- "top": 198,
- "right": 243,
- "bottom": 499
- },
- {
- "left": 39,
- "top": 110,
- "right": 278,
- "bottom": 584
- },
- {
- "left": 26,
- "top": 74,
- "right": 292,
- "bottom": 618
- },
- {
- "left": 19,
- "top": 55,
- "right": 299,
- "bottom": 637
- },
- {
- "left": 15,
- "top": 42,
- "right": 304,
- "bottom": 649
- },
- {
- "left": 12,
- "top": 33,
- "right": 307,
- "bottom": 658
- },
- {
- "left": 9,
- "top": 27,
- "right": 310,
- "bottom": 664
- },
- {
- "left": 7,
- "top": 21,
- "right": 312,
- "bottom": 669
- },
- {
- "left": 6,
- "top": 17,
- "right": 314,
- "bottom": 674
- },
- {
- "left": 5,
- "top": 13,
- "right": 315,
- "bottom": 677
- },
- {
- "left": 4,
- "top": 10,
- "right": 316,
- "bottom": 680
- },
- {
- "left": 3,
- "top": 8,
- "right": 317,
- "bottom": 682
- },
- {
- "left": 2,
- "top": 6,
- "right": 318,
- "bottom": 684
- },
- {
- "left": 2,
- "top": 5,
- "right": 318,
- "bottom": 685
- },
- {
- "left": 1,
- "top": 4,
- "right": 319,
- "bottom": 687
- },
- {
- "left": 1,
- "top": 2,
- "right": 319,
- "bottom": 688
- },
- {
- "left": 1,
- "top": 2,
- "right": 319,
- "bottom": 688
- },
- {
- "left": 0,
- "top": 1,
- "right": 320,
- "bottom": 689
- },
- {
- "left": 0,
- "top": 1,
- "right": 320,
- "bottom": 689
- },
- {
- "left": 0,
- "top": 0,
- "right": 320,
- "bottom": 690
- },
- {
- "left": 0,
- "top": 0,
- "right": 320,
- "bottom": 690
- },
- {
- "left": 0,
- "top": 0,
- "right": 320,
- "bottom": 690
- }
- ]
- },
- {
- "name": "corner_radii",
- "type": "cornerRadii",
- "data_points": [
- {
- "top_left_x": 10,
- "top_left_y": 10,
- "top_right_x": 10,
- "top_right_y": 10,
- "bottom_right_x": 20,
- "bottom_right_y": 20,
- "bottom_left_x": 20,
- "bottom_left_y": 20
- },
- {
- "top_left_x": 9.865689,
- "top_left_y": 9.865689,
- "top_right_x": 9.865689,
- "top_right_y": 9.865689,
- "bottom_right_x": 19.731379,
- "bottom_right_y": 19.731379,
- "bottom_left_x": 19.731379,
- "bottom_left_y": 19.731379
- },
- {
- "top_left_x": 9.419104,
- "top_left_y": 9.419104,
- "top_right_x": 9.419104,
- "top_right_y": 9.419104,
- "bottom_right_x": 18.838207,
- "bottom_right_y": 18.838207,
- "bottom_left_x": 18.838207,
- "bottom_left_y": 18.838207
- },
- {
- "top_left_x": 8.533693,
- "top_left_y": 8.533693,
- "top_right_x": 8.533693,
- "top_right_y": 8.533693,
- "bottom_right_x": 17.067387,
- "bottom_right_y": 17.067387,
- "bottom_left_x": 17.067387,
- "bottom_left_y": 17.067387
- },
- {
- "top_left_x": 6.5919456,
- "top_left_y": 6.5919456,
- "top_right_x": 6.5919456,
- "top_right_y": 6.5919456,
- "bottom_right_x": 13.183891,
- "bottom_right_y": 13.183891,
- "bottom_left_x": 13.183891,
- "bottom_left_y": 13.183891
- },
- {
- "top_left_x": 3.6674318,
- "top_left_y": 3.6674318,
- "top_right_x": 3.6674318,
- "top_right_y": 3.6674318,
- "bottom_right_x": 7.3348637,
- "bottom_right_y": 7.3348637,
- "bottom_left_x": 7.3348637,
- "bottom_left_y": 7.3348637
- },
- {
- "top_left_x": 2.4832253,
- "top_left_y": 2.4832253,
- "top_right_x": 2.4832253,
- "top_right_y": 2.4832253,
- "bottom_right_x": 4.9664507,
- "bottom_right_y": 4.9664507,
- "bottom_left_x": 4.9664507,
- "bottom_left_y": 4.9664507
- },
- {
- "top_left_x": 1.8252907,
- "top_left_y": 1.8252907,
- "top_right_x": 1.8252907,
- "top_right_y": 1.8252907,
- "bottom_right_x": 3.6505814,
- "bottom_right_y": 3.6505814,
- "bottom_left_x": 3.6505814,
- "bottom_left_y": 3.6505814
- },
- {
- "top_left_x": 1.4077549,
- "top_left_y": 1.4077549,
- "top_right_x": 1.4077549,
- "top_right_y": 1.4077549,
- "bottom_right_x": 2.8155098,
- "bottom_right_y": 2.8155098,
- "bottom_left_x": 2.8155098,
- "bottom_left_y": 2.8155098
- },
- {
- "top_left_x": 1.1067667,
- "top_left_y": 1.1067667,
- "top_right_x": 1.1067667,
- "top_right_y": 1.1067667,
- "bottom_right_x": 2.2135334,
- "bottom_right_y": 2.2135334,
- "bottom_left_x": 2.2135334,
- "bottom_left_y": 2.2135334
- },
- {
- "top_left_x": 0.88593864,
- "top_left_y": 0.88593864,
- "top_right_x": 0.88593864,
- "top_right_y": 0.88593864,
- "bottom_right_x": 1.7718773,
- "bottom_right_y": 1.7718773,
- "bottom_left_x": 1.7718773,
- "bottom_left_y": 1.7718773
- },
- {
- "top_left_x": 0.7069988,
- "top_left_y": 0.7069988,
- "top_right_x": 0.7069988,
- "top_right_y": 0.7069988,
- "bottom_right_x": 1.4139977,
- "bottom_right_y": 1.4139977,
- "bottom_left_x": 1.4139977,
- "bottom_left_y": 1.4139977
- },
- {
- "top_left_x": 0.55613136,
- "top_left_y": 0.55613136,
- "top_right_x": 0.55613136,
- "top_right_y": 0.55613136,
- "bottom_right_x": 1.1122627,
- "bottom_right_y": 1.1122627,
- "bottom_left_x": 1.1122627,
- "bottom_left_y": 1.1122627
- },
- {
- "top_left_x": 0.44889355,
- "top_left_y": 0.44889355,
- "top_right_x": 0.44889355,
- "top_right_y": 0.44889355,
- "bottom_right_x": 0.8977871,
- "bottom_right_y": 0.8977871,
- "bottom_left_x": 0.8977871,
- "bottom_left_y": 0.8977871
- },
- {
- "top_left_x": 0.34557533,
- "top_left_y": 0.34557533,
- "top_right_x": 0.34557533,
- "top_right_y": 0.34557533,
- "bottom_right_x": 0.69115067,
- "bottom_right_y": 0.69115067,
- "bottom_left_x": 0.69115067,
- "bottom_left_y": 0.69115067
- },
- {
- "top_left_x": 0.27671337,
- "top_left_y": 0.27671337,
- "top_right_x": 0.27671337,
- "top_right_y": 0.27671337,
- "bottom_right_x": 0.55342674,
- "bottom_right_y": 0.55342674,
- "bottom_left_x": 0.55342674,
- "bottom_left_y": 0.55342674
- },
- {
- "top_left_x": 0.20785141,
- "top_left_y": 0.20785141,
- "top_right_x": 0.20785141,
- "top_right_y": 0.20785141,
- "bottom_right_x": 0.41570282,
- "bottom_right_y": 0.41570282,
- "bottom_left_x": 0.41570282,
- "bottom_left_y": 0.41570282
- },
- {
- "top_left_x": 0.1601448,
- "top_left_y": 0.1601448,
- "top_right_x": 0.1601448,
- "top_right_y": 0.1601448,
- "bottom_right_x": 0.3202896,
- "bottom_right_y": 0.3202896,
- "bottom_left_x": 0.3202896,
- "bottom_left_y": 0.3202896
- },
- {
- "top_left_x": 0.117860794,
- "top_left_y": 0.117860794,
- "top_right_x": 0.117860794,
- "top_right_y": 0.117860794,
- "bottom_right_x": 0.23572159,
- "bottom_right_y": 0.23572159,
- "bottom_left_x": 0.23572159,
- "bottom_left_y": 0.23572159
- },
- {
- "top_left_x": 0.08036041,
- "top_left_y": 0.08036041,
- "top_right_x": 0.08036041,
- "top_right_y": 0.08036041,
- "bottom_right_x": 0.16072083,
- "bottom_right_y": 0.16072083,
- "bottom_left_x": 0.16072083,
- "bottom_left_y": 0.16072083
- },
- {
- "top_left_x": 0.05836296,
- "top_left_y": 0.05836296,
- "top_right_x": 0.05836296,
- "top_right_y": 0.05836296,
- "bottom_right_x": 0.11672592,
- "bottom_right_y": 0.11672592,
- "bottom_left_x": 0.11672592,
- "bottom_left_y": 0.11672592
- },
- {
- "top_left_x": 0.03636551,
- "top_left_y": 0.03636551,
- "top_right_x": 0.03636551,
- "top_right_y": 0.03636551,
- "bottom_right_x": 0.07273102,
- "bottom_right_y": 0.07273102,
- "bottom_left_x": 0.07273102,
- "bottom_left_y": 0.07273102
- },
- {
- "top_left_x": 0.018137932,
- "top_left_y": 0.018137932,
- "top_right_x": 0.018137932,
- "top_right_y": 0.018137932,
- "bottom_right_x": 0.036275864,
- "bottom_right_y": 0.036275864,
- "bottom_left_x": 0.036275864,
- "bottom_left_y": 0.036275864
- },
- {
- "top_left_x": 0.0082063675,
- "top_left_y": 0.0082063675,
- "top_right_x": 0.0082063675,
- "top_right_y": 0.0082063675,
- "bottom_right_x": 0.016412735,
- "bottom_right_y": 0.016412735,
- "bottom_left_x": 0.016412735,
- "bottom_left_y": 0.016412735
- },
- {
- "top_left_x": 0.0031013489,
- "top_left_y": 0.0031013489,
- "top_right_x": 0.0031013489,
- "top_right_y": 0.0031013489,
- "bottom_right_x": 0.0062026978,
- "bottom_right_y": 0.0062026978,
- "bottom_left_x": 0.0062026978,
- "bottom_left_y": 0.0062026978
- },
- {
- "top_left_x": 0,
- "top_left_y": 0,
- "top_right_x": 0,
- "top_right_y": 0,
- "bottom_right_x": 0,
- "bottom_right_y": 0,
- "bottom_left_x": 0,
- "bottom_left_y": 0
- }
- ]
- },
- {
- "name": "alpha",
- "type": "int",
- "data_points": [
- 0,
- 96,
- 153,
- 192,
- 220,
- 238,
- 249,
- 254,
- 233,
- 191,
- 153,
- 117,
- 85,
- 57,
- 33,
- 14,
- 3,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 3d9eb53..a39ca5d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -103,6 +103,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.FlagsParameterization;
import android.service.dreams.IDreamManager;
import android.service.trust.TrustAgentService;
@@ -129,6 +130,7 @@
import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
import com.android.keyguard.logging.SimLogger;
import com.android.settingslib.fuelgauge.BatteryStatus;
+import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
@@ -190,6 +192,7 @@
@SmallTest
@RunWith(ParameterizedAndroidJunit4.class)
@TestableLooper.RunWithLooper
+@EnableFlags(Flags.FLAG_USER_ENCRYPTED_SOURCE)
public class KeyguardUpdateMonitorTest extends SysuiTestCase {
private static final String PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY =
"test_app_fp_listen_on_occluding_activity";
@@ -1292,12 +1295,15 @@
@Test
public void testIsUserUnlocked() {
+ when(mUserManager.isUserUnlocked(mSelectedUserInteractor.getSelectedUserId())).thenReturn(
+ true);
// mUserManager will report the user as unlocked on @Before
assertThat(
mKeyguardUpdateMonitor.isUserUnlocked(mSelectedUserInteractor.getSelectedUserId()))
.isTrue();
// Invalid user should not be unlocked.
int randomUser = 99;
+ when(mUserManager.isUserUnlocked(randomUser)).thenReturn(false);
assertThat(mKeyguardUpdateMonitor.isUserUnlocked(randomUser)).isFalse();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index c6e4e0d..fa88f62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -46,7 +46,6 @@
import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.animation.AccelerateInterpolator;
import android.window.InputTransferToken;
@@ -1030,10 +1029,7 @@
callback,
sysUiState,
secureSettings,
- scvhSupplier,
- sfVsyncFrameProvider,
- WindowManagerGlobal::getWindowSession,
- viewCaptureAwareWindowManager);
+ scvhSupplier);
mSpyController = Mockito.mock(WindowMagnificationController.class);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
deleted file mode 100644
index 9b09ec2..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
+++ /dev/null
@@ -1,1594 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.accessibility;
-
-import static android.content.pm.PackageManager.FEATURE_WINDOW_MAGNIFICATION;
-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.view.MotionEvent.ACTION_DOWN;
-import static android.view.MotionEvent.ACTION_UP;
-import static android.view.WindowInsets.Type.systemGestures;
-import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.AdditionalAnswers.returnsSecondArg;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import static java.util.Arrays.asList;
-
-import android.animation.ValueAnimator;
-import android.annotation.IdRes;
-import android.annotation.Nullable;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Insets;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
-import android.provider.Settings;
-import android.testing.TestableLooper;
-import android.testing.TestableResources;
-import android.util.Size;
-import android.view.AttachedSurfaceControl;
-import android.view.Display;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.SurfaceControl;
-import android.view.SurfaceControlViewHost;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewRootImpl;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.IRemoteMagnificationAnimationCallback;
-import android.widget.FrameLayout;
-import android.window.InputTransferToken;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.LargeTest;
-
-import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
-import com.android.systemui.Flags;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.animation.AnimatorTestRule;
-import com.android.systemui.kosmos.KosmosJavaAdapter;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.res.R;
-import com.android.systemui.settings.FakeDisplayTracker;
-import com.android.systemui.util.FakeSharedPreferences;
-import com.android.systemui.util.leak.ReferenceTestUtils;
-import com.android.systemui.util.settings.SecureSettings;
-import com.android.systemui.utils.os.FakeHandler;
-
-import com.google.common.util.concurrent.AtomicDouble;
-
-import org.junit.After;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Supplier;
-
-@LargeTest
-@TestableLooper.RunWithLooper
-@RunWith(AndroidJUnit4.class)
-@EnableFlags(Flags.FLAG_CREATE_WINDOWLESS_WINDOW_MAGNIFIER)
-public class WindowMagnificationControllerWindowlessMagnifierTest extends SysuiTestCase {
-
- @Rule
- // NOTE: pass 'null' to allow this test advances time on the main thread.
- public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(/* test= */ null);
-
- private static final int LAYOUT_CHANGE_TIMEOUT_MS = 5000;
- @Mock
- private MirrorWindowControl mMirrorWindowControl;
- @Mock
- private WindowMagnifierCallback mWindowMagnifierCallback;
- @Mock
- IRemoteMagnificationAnimationCallback mAnimationCallback;
- @Mock
- IRemoteMagnificationAnimationCallback mAnimationCallback2;
-
- private SurfaceControl.Transaction mTransaction;
- @Mock
- private SecureSettings mSecureSettings;
- @Mock
- private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager;
-
- private long mWaitAnimationDuration;
- private long mWaitBounceEffectDuration;
-
- private Handler mHandler;
- private TestableWindowManager mWindowManager;
- private SysUiState mSysUiState;
- private Resources mResources;
- private WindowMagnificationAnimationController mWindowMagnificationAnimationController;
- private WindowMagnificationController mWindowMagnificationController;
- private Instrumentation mInstrumentation;
- private final ValueAnimator mValueAnimator = ValueAnimator.ofFloat(0, 1.0f).setDuration(0);
- private final FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
-
- private View mSpyView;
- private View.OnTouchListener mTouchListener;
-
- private MotionEventHelper mMotionEventHelper = new MotionEventHelper();
-
- // This list contains all SurfaceControlViewHosts created during a given test. If the
- // magnification window is recreated during a test, the list will contain more than a single
- // element.
- private List<SurfaceControlViewHost> mSurfaceControlViewHosts = new ArrayList<>();
- // The most recently created SurfaceControlViewHost.
- private SurfaceControlViewHost mSurfaceControlViewHost;
- private KosmosJavaAdapter mKosmos;
- private FakeSharedPreferences mSharedPreferences;
-
- /**
- * return whether window magnification is supported for current test context.
- */
- private boolean isWindowModeSupported() {
- return getContext().getPackageManager().hasSystemFeature(FEATURE_WINDOW_MAGNIFICATION);
- }
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mContext = spy(mContext);
- mKosmos = new KosmosJavaAdapter(this);
- mContext = Mockito.spy(getContext());
- mHandler = new FakeHandler(TestableLooper.get(this).getLooper());
- mInstrumentation = InstrumentationRegistry.getInstrumentation();
- final WindowManager wm = mContext.getSystemService(WindowManager.class);
- mWindowManager = spy(new TestableWindowManager(wm));
-
- mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
- mSysUiState = new SysUiState(mDisplayTracker, mKosmos.getSceneContainerPlugin());
- mSysUiState.addCallback(Mockito.mock(SysUiState.SysUiStateCallback.class));
- when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).then(
- returnsSecondArg());
- when(mSecureSettings.getFloatForUser(anyString(), anyFloat(), anyInt())).then(
- returnsSecondArg());
-
- mResources = getContext().getOrCreateTestableResources().getResources();
- // prevent the config orientation from undefined, which may cause config.diff method
- // neglecting the orientation update.
- if (mResources.getConfiguration().orientation == ORIENTATION_UNDEFINED) {
- mResources.getConfiguration().orientation = ORIENTATION_PORTRAIT;
- }
-
- // Using the animation duration in WindowMagnificationAnimationController for testing.
- mWaitAnimationDuration = mResources.getInteger(
- com.android.internal.R.integer.config_longAnimTime);
- // Using the bounce effect duration in WindowMagnificationController for testing.
- mWaitBounceEffectDuration = mResources.getInteger(
- com.android.internal.R.integer.config_shortAnimTime);
-
- mWindowMagnificationAnimationController = new WindowMagnificationAnimationController(
- mContext, mValueAnimator);
- Supplier<SurfaceControlViewHost> scvhSupplier = () -> {
- mSurfaceControlViewHost = spy(new SurfaceControlViewHost(
- mContext, mContext.getDisplay(), new InputTransferToken(),
- "WindowMagnification"));
- ViewRootImpl viewRoot = mock(ViewRootImpl.class);
- when(mSurfaceControlViewHost.getRootSurfaceControl()).thenReturn(viewRoot);
- mSurfaceControlViewHosts.add(mSurfaceControlViewHost);
- return mSurfaceControlViewHost;
- };
- mTransaction = spy(new SurfaceControl.Transaction());
- mSharedPreferences = new FakeSharedPreferences();
- when(mContext.getSharedPreferences(
- eq("window_magnification_preferences"), anyInt()))
- .thenReturn(mSharedPreferences);
- mWindowMagnificationController =
- new WindowMagnificationController(
- mContext,
- mHandler,
- mWindowMagnificationAnimationController,
- mMirrorWindowControl,
- mTransaction,
- mWindowMagnifierCallback,
- mSysUiState,
- mSecureSettings,
- scvhSupplier,
- /* sfVsyncFrameProvider= */ null,
- /* globalWindowSessionSupplier= */ null,
- mViewCaptureAwareWindowManager);
-
- verify(mMirrorWindowControl).setWindowDelegate(
- any(MirrorWindowControl.MirrorWindowDelegate.class));
- mSpyView = Mockito.spy(new View(mContext));
- doAnswer((invocation) -> {
- mTouchListener = invocation.getArgument(0);
- return null;
- }).when(mSpyView).setOnTouchListener(
- any(View.OnTouchListener.class));
-
- // skip test if window magnification is not supported to prevent fail results. (b/279820875)
- Assume.assumeTrue(isWindowModeSupported());
- }
-
- @After
- public void tearDown() {
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController.deleteWindowMagnification();
- });
- mValueAnimator.cancel();
- }
-
- @Test
- public void initWindowMagnificationController_checkAllowDiagonalScrollingWithSecureSettings() {
- verify(mSecureSettings).getIntForUser(
- eq(Settings.Secure.ACCESSIBILITY_ALLOW_DIAGONAL_SCROLLING),
- /* def */ eq(1), /* userHandle= */ anyInt());
- assertThat(mWindowMagnificationController.isDiagonalScrollingEnabled()).isTrue();
- }
-
- @Test
- public void enableWindowMagnification_showControlAndNotifyBoundsChanged() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- verify(mMirrorWindowControl).showControl();
- verify(mWindowMagnifierCallback,
- timeout(LAYOUT_CHANGE_TIMEOUT_MS).atLeastOnce()).onWindowMagnifierBoundsChanged(
- eq(mContext.getDisplayId()), any(Rect.class));
- }
-
- @Test
- public void enableWindowMagnification_notifySourceBoundsChanged() {
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
- Float.NaN, /* magnificationFrameOffsetRatioX= */ 0,
- /* magnificationFrameOffsetRatioY= */ 0, null));
-
- // Waits for the surface created
- verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS)).onSourceBoundsChanged(
- (eq(mContext.getDisplayId())), any());
- }
-
- @Test
- public void enableWindowMagnification_disabled_notifySourceBoundsChanged() {
- enableWindowMagnification_notifySourceBoundsChanged();
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.deleteWindowMagnification(null));
- Mockito.reset(mWindowMagnifierCallback);
-
- enableWindowMagnification_notifySourceBoundsChanged();
- }
-
- @Test
- public void enableWindowMagnification_withAnimation_schedulesFrame() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnification(2.0f, 10,
- 10, /* magnificationFrameOffsetRatioX= */ 0,
- /* magnificationFrameOffsetRatioY= */ 0,
- Mockito.mock(IRemoteMagnificationAnimationCallback.class));
- });
- advanceTimeBy(LAYOUT_CHANGE_TIMEOUT_MS);
-
- verify(mTransaction, atLeastOnce()).setGeometry(any(), any(), any(),
- eq(Surface.ROTATION_0));
- }
-
- @Test
- public void moveWindowMagnifier_enabled_notifySourceBoundsChanged() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
- Float.NaN, 0, 0, null);
- });
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.moveWindowMagnifier(10, 10);
- });
-
- final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
- verify(mWindowMagnifierCallback, atLeast(2)).onSourceBoundsChanged(
- (eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
- assertThat(mWindowMagnificationController.getCenterX())
- .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
- assertThat(mWindowMagnificationController.getCenterY())
- .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
- }
-
- @Test
- public void enableWindowMagnification_systemGestureExclusionRectsIsSet() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
- // Wait for Rects updated.
- waitForIdleSync();
-
- List<Rect> rects = mSurfaceControlViewHost.getView().getSystemGestureExclusionRects();
- assertThat(rects).isNotEmpty();
- }
-
- @Ignore("The default window size should be constrained after fixing b/288056772")
- @Test
- public void enableWindowMagnification_LargeScreen_windowSizeIsConstrained() {
- final int screenSize = mWindowManager.getCurrentWindowMetrics().getBounds().width() * 10;
- mWindowManager.setWindowBounds(new Rect(0, 0, screenSize, screenSize));
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- final int halfScreenSize = screenSize / 2;
- ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
- // The frame size should be the half of smaller value of window height/width unless it
- //exceed the max frame size.
- assertThat(params.width).isLessThan(halfScreenSize);
- assertThat(params.height).isLessThan(halfScreenSize);
- }
-
- @Test
- public void deleteWindowMagnification_destroyControlAndUnregisterComponentCallback() {
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- Float.NaN,
- Float.NaN));
-
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.deleteWindowMagnification());
-
- verify(mMirrorWindowControl).destroyControl();
- verify(mContext).unregisterComponentCallbacks(mWindowMagnificationController);
- }
-
- @Test
- public void deleteWindowMagnification_enableAtTheBottom_overlapFlagIsFalse() {
- final WindowManager wm = mContext.getSystemService(WindowManager.class);
- final Rect bounds = wm.getCurrentWindowMetrics().getBounds();
- setSystemGestureInsets();
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- bounds.bottom);
- });
- ReferenceTestUtils.waitForCondition(this::hasMagnificationOverlapFlag);
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.deleteWindowMagnification();
- });
-
- verify(mMirrorWindowControl).destroyControl();
- assertThat(hasMagnificationOverlapFlag()).isFalse();
- }
-
- @Test
- public void deleteWindowMagnification_notifySourceBoundsChanged() {
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- Float.NaN,
- Float.NaN));
-
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.deleteWindowMagnification());
-
- // The first time is for notifying magnification enabled and the second time is for
- // notifying magnification disabled.
- verify(mWindowMagnifierCallback, times(2)).onSourceBoundsChanged(
- (eq(mContext.getDisplayId())), any());
- }
-
- @Test
- public void moveMagnifier_schedulesFrame() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- waitForIdleSync();
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.moveWindowMagnifier(100f, 100f));
-
- verify(mTransaction, atLeastOnce()).setGeometry(any(), any(), any(),
- eq(Surface.ROTATION_0));
- }
-
- @Test
- public void moveWindowMagnifierToPositionWithAnimation_expectedValuesAndInvokeCallback()
- throws RemoteException {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
- Float.NaN, 0, 0, null);
- });
-
- final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
- verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
- .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
- final float targetCenterX = sourceBoundsCaptor.getValue().exactCenterX() + 10;
- final float targetCenterY = sourceBoundsCaptor.getValue().exactCenterY() + 10;
-
- reset(mWindowMagnifierCallback);
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.moveWindowMagnifierToPosition(
- targetCenterX, targetCenterY, mAnimationCallback);
- });
- advanceTimeBy(mWaitAnimationDuration);
-
- verify(mAnimationCallback, times(1)).onResult(eq(true));
- verify(mAnimationCallback, never()).onResult(eq(false));
- verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
- .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
- assertThat(mWindowMagnificationController.getCenterX())
- .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
- assertThat(mWindowMagnificationController.getCenterY())
- .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
- assertThat(mWindowMagnificationController.getCenterX()).isEqualTo(targetCenterX);
- assertThat(mWindowMagnificationController.getCenterY()).isEqualTo(targetCenterY);
- }
-
- @Test
- public void moveWindowMagnifierToPositionMultipleTimes_expectedValuesAndInvokeCallback()
- throws RemoteException {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
- Float.NaN, 0, 0, null);
- });
-
- final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
- verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
- .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
- final float centerX = sourceBoundsCaptor.getValue().exactCenterX();
- final float centerY = sourceBoundsCaptor.getValue().exactCenterY();
-
- reset(mWindowMagnifierCallback);
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.moveWindowMagnifierToPosition(
- centerX + 10, centerY + 10, mAnimationCallback);
- mWindowMagnificationController.moveWindowMagnifierToPosition(
- centerX + 20, centerY + 20, mAnimationCallback);
- mWindowMagnificationController.moveWindowMagnifierToPosition(
- centerX + 30, centerY + 30, mAnimationCallback);
- mWindowMagnificationController.moveWindowMagnifierToPosition(
- centerX + 40, centerY + 40, mAnimationCallback2);
- });
- advanceTimeBy(mWaitAnimationDuration);
-
- // only the last one callback will return true
- verify(mAnimationCallback2).onResult(eq(true));
- // the others will return false
- verify(mAnimationCallback, times(3)).onResult(eq(false));
- verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
- .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
- assertThat(mWindowMagnificationController.getCenterX())
- .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
- assertThat(mWindowMagnificationController.getCenterY())
- .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
- assertThat(mWindowMagnificationController.getCenterX()).isEqualTo(centerX + 40);
- assertThat(mWindowMagnificationController.getCenterY()).isEqualTo(centerY + 40);
- }
-
- @Test
- public void setScale_enabled_expectedValueAndUpdateStateDescription() {
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.updateWindowMagnificationInternal(2.0f,
- Float.NaN, Float.NaN));
-
- mInstrumentation.runOnMainSync(() -> mWindowMagnificationController.setScale(3.0f));
-
- assertThat(mWindowMagnificationController.getScale()).isEqualTo(3.0f);
- final View mirrorView = mSurfaceControlViewHost.getView();
- assertThat(mirrorView).isNotNull();
- assertThat(mirrorView.getStateDescription().toString()).contains("300");
- }
-
- @Test
- public void onConfigurationChanged_disabled_withoutException() {
- Display display = Mockito.spy(mContext.getDisplay());
- when(display.getRotation()).thenReturn(Surface.ROTATION_90);
- when(mContext.getDisplay()).thenReturn(display);
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_ORIENTATION);
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_LOCALE);
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
- });
- }
-
- @Test
- public void onOrientationChanged_enabled_updateDisplayRotationAndCenterStayAtSamePosition() {
- final int newRotation = simulateRotateTheDevice();
- final Rect windowBounds = new Rect(mWindowManager.getCurrentWindowMetrics().getBounds());
- final float center = Math.min(windowBounds.exactCenterX(), windowBounds.exactCenterY());
- final float displayWidth = windowBounds.width();
- final PointF magnifiedCenter = new PointF(center, center + 5f);
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- magnifiedCenter.x, magnifiedCenter.y);
- // Get the center again in case the center we set is out of screen.
- magnifiedCenter.set(mWindowMagnificationController.getCenterX(),
- mWindowMagnificationController.getCenterY());
- });
- // Rotate the window clockwise 90 degree.
- windowBounds.set(windowBounds.top, windowBounds.left, windowBounds.bottom,
- windowBounds.right);
- mWindowManager.setWindowBounds(windowBounds);
-
- mInstrumentation.runOnMainSync(() -> mWindowMagnificationController.onConfigurationChanged(
- ActivityInfo.CONFIG_ORIENTATION));
-
- assertThat(mWindowMagnificationController.mRotation).isEqualTo(newRotation);
- final PointF expectedCenter = new PointF(magnifiedCenter.y,
- displayWidth - magnifiedCenter.x);
- final PointF actualCenter = new PointF(mWindowMagnificationController.getCenterX(),
- mWindowMagnificationController.getCenterY());
- assertThat(actualCenter).isEqualTo(expectedCenter);
- }
-
- @Test
- public void onOrientationChanged_disabled_updateDisplayRotation() {
- final Rect windowBounds = new Rect(mWindowManager.getCurrentWindowMetrics().getBounds());
- // Rotate the window clockwise 90 degree.
- windowBounds.set(windowBounds.top, windowBounds.left, windowBounds.bottom,
- windowBounds.right);
- mWindowManager.setWindowBounds(windowBounds);
- final int newRotation = simulateRotateTheDevice();
-
- mInstrumentation.runOnMainSync(() -> mWindowMagnificationController.onConfigurationChanged(
- ActivityInfo.CONFIG_ORIENTATION));
-
- assertThat(mWindowMagnificationController.mRotation).isEqualTo(newRotation);
- }
-
- @Test
- public void onScreenSizeAndDensityChanged_enabledAtTheCenterOfScreen_keepSameWindowSizeRatio() {
- // The default position is at the center of the screen.
- final float expectedRatio = 0.5f;
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- // Screen size and density change
- mContext.getResources().getConfiguration().smallestScreenWidthDp =
- mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
- final Rect testWindowBounds = new Rect(
- mWindowManager.getCurrentWindowMetrics().getBounds());
- testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
- testWindowBounds.right + 100, testWindowBounds.bottom + 100);
- mWindowManager.setWindowBounds(testWindowBounds);
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
- });
-
- // The ratio of center to window size should be the same.
- assertThat(mWindowMagnificationController.getCenterX() / testWindowBounds.width())
- .isEqualTo(expectedRatio);
- assertThat(mWindowMagnificationController.getCenterY() / testWindowBounds.height())
- .isEqualTo(expectedRatio);
- }
-
- @DisableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
- @Test
- public void onScreenSizeAndDensityChanged_enabled_restoreSavedMagnifierWindow() {
- int newSmallestScreenWidthDp =
- mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
- int windowFrameSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- Size preferredWindowSize = new Size(windowFrameSize, windowFrameSize);
- mSharedPreferences
- .edit()
- .putString(String.valueOf(newSmallestScreenWidthDp),
- preferredWindowSize.toString())
- .commit();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- // Screen density and size change
- mContext.getResources().getConfiguration().smallestScreenWidthDp = newSmallestScreenWidthDp;
- final Rect testWindowBounds = new Rect(
- mWindowManager.getCurrentWindowMetrics().getBounds());
- testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
- testWindowBounds.right + 100, testWindowBounds.bottom + 100);
- mWindowManager.setWindowBounds(testWindowBounds);
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
- });
-
- // wait for rect update
- waitForIdleSync();
- ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
- final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
- R.dimen.magnification_mirror_surface_margin);
- // The width and height of the view include the magnification frame and the margins.
- assertThat(params.width).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
- assertThat(params.height).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
- }
-
- @EnableFlags(Flags.FLAG_SAVE_AND_RESTORE_MAGNIFICATION_SETTINGS_BUTTONS)
- @Test
- public void onScreenSizeAndDensityChanged_enabled_restoreSavedMagnifierIndexAndWindow() {
- int newSmallestScreenWidthDp =
- mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
- int windowFrameSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- Size preferredWindowSize = new Size(windowFrameSize, windowFrameSize);
- mSharedPreferences
- .edit()
- .putString(String.valueOf(newSmallestScreenWidthDp),
- WindowMagnificationFrameSpec.serialize(
- WindowMagnificationSettings.MagnificationSize.CUSTOM,
- preferredWindowSize))
- .commit();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- // Screen density and size change
- mContext.getResources().getConfiguration().smallestScreenWidthDp = newSmallestScreenWidthDp;
- final Rect testWindowBounds = new Rect(
- mWindowManager.getCurrentWindowMetrics().getBounds());
- testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
- testWindowBounds.right + 100, testWindowBounds.bottom + 100);
- mWindowManager.setWindowBounds(testWindowBounds);
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
- });
-
- // wait for rect update
- waitForIdleSync();
- verify(mWindowMagnifierCallback).onWindowMagnifierBoundsRestored(
- eq(mContext.getDisplayId()),
- eq(WindowMagnificationSettings.MagnificationSize.CUSTOM));
- ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
- final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
- R.dimen.magnification_mirror_surface_margin);
- // The width and height of the view include the magnification frame and the margins.
- assertThat(params.width).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
- assertThat(params.height).isEqualTo(windowFrameSize + 2 * mirrorSurfaceMargin);
- }
-
- @Test
- public void screenSizeIsChangedToLarge_enabled_defaultWindowSize() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
- final int screenSize = mWindowManager.getCurrentWindowMetrics().getBounds().width() * 10;
- // Screen size and density change
- mContext.getResources().getConfiguration().smallestScreenWidthDp =
- mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
- mWindowManager.setWindowBounds(new Rect(0, 0, screenSize, screenSize));
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
- });
-
- final int defaultWindowSize =
- mWindowMagnificationController.getMagnificationWindowSizeFromIndex(
- WindowMagnificationSettings.MagnificationSize.MEDIUM);
- ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
-
- assertThat(params.width).isEqualTo(defaultWindowSize);
- assertThat(params.height).isEqualTo(defaultWindowSize);
- }
-
- @Test
- public void onDensityChanged_enabled_updateDimensionsAndResetWindowMagnification() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- Mockito.reset(mWindowManager);
- Mockito.reset(mMirrorWindowControl);
- });
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
- });
-
- verify(mResources, atLeastOnce()).getDimensionPixelSize(anyInt());
- verify(mSurfaceControlViewHosts.get(0)).release();
- verify(mMirrorWindowControl).destroyControl();
- verify(mSurfaceControlViewHosts.get(1)).setView(any(), any());
- verify(mMirrorWindowControl).showControl();
- }
-
- @Test
- public void onDensityChanged_disabled_updateDimensions() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
- });
-
- verify(mResources, atLeastOnce()).getDimensionPixelSize(anyInt());
- }
-
- @Test
- public void initializeA11yNode_enabled_expectedValues() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(2.5f, Float.NaN,
- Float.NaN);
- });
- final View mirrorView = mSurfaceControlViewHost.getView();
- assertThat(mirrorView).isNotNull();
- final AccessibilityNodeInfo nodeInfo = new AccessibilityNodeInfo();
-
- mirrorView.onInitializeAccessibilityNodeInfo(nodeInfo);
-
- assertThat(nodeInfo.getContentDescription()).isNotNull();
- assertThat(nodeInfo.getStateDescription().toString()).contains("250");
- assertThat(nodeInfo.getActionList()).containsExactlyElementsIn(asList(
- new AccessibilityAction(AccessibilityAction.ACTION_CLICK.getId(),
- mContext.getResources().getString(
- R.string.magnification_open_settings_click_label)),
- new AccessibilityAction(R.id.accessibility_action_zoom_in,
- mContext.getString(R.string.accessibility_control_zoom_in)),
- new AccessibilityAction(R.id.accessibility_action_zoom_out,
- mContext.getString(R.string.accessibility_control_zoom_out)),
- new AccessibilityAction(R.id.accessibility_action_move_right,
- mContext.getString(R.string.accessibility_control_move_right)),
- new AccessibilityAction(R.id.accessibility_action_move_left,
- mContext.getString(R.string.accessibility_control_move_left)),
- new AccessibilityAction(R.id.accessibility_action_move_down,
- mContext.getString(R.string.accessibility_control_move_down)),
- new AccessibilityAction(R.id.accessibility_action_move_up,
- mContext.getString(R.string.accessibility_control_move_up))));
- }
-
- @Test
- public void performA11yActions_visible_expectedResults() {
- final int displayId = mContext.getDisplayId();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(1.5f, Float.NaN,
- Float.NaN);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- assertThat(mirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_out, null))
- .isTrue();
- // Minimum scale is 1.0.
- verify(mWindowMagnifierCallback).onPerformScaleAction(
- eq(displayId), /* scale= */ eq(1.0f), /* updatePersistence= */ eq(true));
-
- assertThat(mirrorView.performAccessibilityAction(R.id.accessibility_action_zoom_in, null))
- .isTrue();
- verify(mWindowMagnifierCallback).onPerformScaleAction(
- eq(displayId), /* scale= */ eq(2.5f), /* updatePersistence= */ eq(true));
-
- // TODO: Verify the final state when the mirror surface is visible.
- assertThat(mirrorView.performAccessibilityAction(R.id.accessibility_action_move_up, null))
- .isTrue();
- assertThat(
- mirrorView.performAccessibilityAction(R.id.accessibility_action_move_down, null))
- .isTrue();
- assertThat(
- mirrorView.performAccessibilityAction(R.id.accessibility_action_move_right, null))
- .isTrue();
- assertThat(
- mirrorView.performAccessibilityAction(R.id.accessibility_action_move_left, null))
- .isTrue();
- verify(mWindowMagnifierCallback, times(4)).onMove(eq(displayId));
-
- assertThat(mirrorView.performAccessibilityAction(
- AccessibilityAction.ACTION_CLICK.getId(), null)).isTrue();
- verify(mWindowMagnifierCallback).onClickSettingsButton(eq(displayId));
- }
-
- @Test
- public void performA11yActions_visible_notifyAccessibilityActionPerformed() {
- final int displayId = mContext.getDisplayId();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(2.5f, Float.NaN,
- Float.NaN);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- mirrorView.performAccessibilityAction(R.id.accessibility_action_move_up, null);
-
- verify(mWindowMagnifierCallback).onAccessibilityActionPerformed(eq(displayId));
- }
-
- @Test
- public void windowMagnifierEditMode_performA11yClickAction_exitEditMode() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- View closeButton = getInternalView(R.id.close_button);
- View bottomRightCorner = getInternalView(R.id.bottom_right_corner);
- View bottomLeftCorner = getInternalView(R.id.bottom_left_corner);
- View topRightCorner = getInternalView(R.id.top_right_corner);
- View topLeftCorner = getInternalView(R.id.top_left_corner);
-
- assertThat(closeButton.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(bottomRightCorner.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(bottomLeftCorner.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(topRightCorner.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(topLeftCorner.getVisibility()).isEqualTo(View.VISIBLE);
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- mInstrumentation.runOnMainSync(() ->
- mirrorView.performAccessibilityAction(AccessibilityAction.ACTION_CLICK.getId(),
- null));
-
- assertThat(closeButton.getVisibility()).isEqualTo(View.GONE);
- assertThat(bottomRightCorner.getVisibility()).isEqualTo(View.GONE);
- assertThat(bottomLeftCorner.getVisibility()).isEqualTo(View.GONE);
- assertThat(topRightCorner.getVisibility()).isEqualTo(View.GONE);
- assertThat(topLeftCorner.getVisibility()).isEqualTo(View.GONE);
- }
-
- @Test
-
- public void windowWidthIsNotMax_performA11yActionIncreaseWidth_windowWidthIncreased() {
- final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- final int startingWidth = (int) (windowBounds.width() * 0.8);
- final int startingHeight = (int) (windowBounds.height() * 0.8);
- final float changeWindowSizeAmount = mContext.getResources().getFraction(
- R.fraction.magnification_resize_window_size_amount,
- /* base= */ 1,
- /* pbase= */ 1);
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
-
- mInstrumentation.runOnMainSync(
- () -> {
- mirrorView.performAccessibilityAction(
- R.id.accessibility_action_increase_window_width, null);
- actualWindowHeight.set(
- mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(
- mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
-
- final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
- R.dimen.magnification_mirror_surface_margin);
- // Window width includes the magnifier frame and the margin. Increasing the window size
- // will be increasing the amount of the frame size only.
- int newWindowWidth =
- (int) ((startingWidth - 2 * mirrorSurfaceMargin) * (1 + changeWindowSizeAmount))
- + 2 * mirrorSurfaceMargin;
- assertThat(actualWindowWidth.get()).isEqualTo(newWindowWidth);
- assertThat(actualWindowHeight.get()).isEqualTo(startingHeight);
- }
-
- @Test
- public void windowHeightIsNotMax_performA11yActionIncreaseHeight_windowHeightIncreased() {
- final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- final int startingWidth = (int) (windowBounds.width() * 0.8);
- final int startingHeight = (int) (windowBounds.height() * 0.8);
- final float changeWindowSizeAmount = mContext.getResources().getFraction(
- R.fraction.magnification_resize_window_size_amount,
- /* base= */ 1,
- /* pbase= */ 1);
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
-
- mInstrumentation.runOnMainSync(
- () -> {
- mirrorView.performAccessibilityAction(
- R.id.accessibility_action_increase_window_height, null);
- actualWindowHeight.set(
- mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(
- mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
-
- final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
- R.dimen.magnification_mirror_surface_margin);
- // Window height includes the magnifier frame and the margin. Increasing the window size
- // will be increasing the amount of the frame size only.
- int newWindowHeight =
- (int) ((startingHeight - 2 * mirrorSurfaceMargin) * (1 + changeWindowSizeAmount))
- + 2 * mirrorSurfaceMargin;
- assertThat(actualWindowWidth.get()).isEqualTo(startingWidth);
- assertThat(actualWindowHeight.get()).isEqualTo(newWindowHeight);
- }
-
- @Test
- public void windowWidthIsMax_noIncreaseWindowWidthA11yAction() {
- final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- final int startingWidth = windowBounds.width();
- final int startingHeight = windowBounds.height();
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- final AccessibilityNodeInfo accessibilityNodeInfo =
- mirrorView.createAccessibilityNodeInfo();
- assertThat(accessibilityNodeInfo.getActionList()).doesNotContain(
- new AccessibilityAction(
- R.id.accessibility_action_increase_window_width,
- mContext.getString(
- R.string.accessibility_control_increase_window_width)));
- }
-
- @Test
- public void windowHeightIsMax_noIncreaseWindowHeightA11yAction() {
- final Rect windowBounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- final int startingWidth = windowBounds.width();
- final int startingHeight = windowBounds.height();
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- final AccessibilityNodeInfo accessibilityNodeInfo =
- mirrorView.createAccessibilityNodeInfo();
- assertThat(accessibilityNodeInfo.getActionList()).doesNotContain(
- new AccessibilityAction(
- R.id.accessibility_action_increase_window_height, null));
- }
-
- @Test
- public void windowWidthIsNotMin_performA11yActionDecreaseWidth_windowWidthDecreased() {
- int mMinWindowSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- final int startingSize = (int) (mMinWindowSize * 1.1);
- final float changeWindowSizeAmount = mContext.getResources().getFraction(
- R.fraction.magnification_resize_window_size_amount,
- /* base= */ 1,
- /* pbase= */ 1);
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- mWindowMagnificationController.setWindowSize(startingSize, startingSize);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
-
- mInstrumentation.runOnMainSync(
- () -> {
- mirrorView.performAccessibilityAction(
- R.id.accessibility_action_decrease_window_width, null);
- actualWindowHeight.set(
- mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(
- mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
-
- final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
- R.dimen.magnification_mirror_surface_margin);
- // Window width includes the magnifier frame and the margin. Decreasing the window size
- // will be decreasing the amount of the frame size only.
- int newWindowWidth =
- (int) ((startingSize - 2 * mirrorSurfaceMargin) * (1 - changeWindowSizeAmount))
- + 2 * mirrorSurfaceMargin;
- assertThat(actualWindowWidth.get()).isEqualTo(newWindowWidth);
- assertThat(actualWindowHeight.get()).isEqualTo(startingSize);
- }
-
- @Test
- public void windowHeightIsNotMin_performA11yActionDecreaseHeight_windowHeightDecreased() {
- int mMinWindowSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- final int startingSize = (int) (mMinWindowSize * 1.1);
- final float changeWindowSizeAmount = mContext.getResources().getFraction(
- R.fraction.magnification_resize_window_size_amount,
- /* base= */ 1,
- /* pbase= */ 1);
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- mWindowMagnificationController.setWindowSize(startingSize, startingSize);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
-
- mInstrumentation.runOnMainSync(
- () -> {
- mirrorView.performAccessibilityAction(
- R.id.accessibility_action_decrease_window_height, null);
- actualWindowHeight.set(
- mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(
- mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
-
- final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
- R.dimen.magnification_mirror_surface_margin);
- // Window height includes the magnifier frame and the margin. Decreasing the window size
- // will be decreasing the amount of the frame size only.
- int newWindowHeight =
- (int) ((startingSize - 2 * mirrorSurfaceMargin) * (1 - changeWindowSizeAmount))
- + 2 * mirrorSurfaceMargin;
- assertThat(actualWindowWidth.get()).isEqualTo(startingSize);
- assertThat(actualWindowHeight.get()).isEqualTo(newWindowHeight);
- }
-
- @Test
- public void windowWidthIsMin_noDecreaseWindowWidthA11yAction() {
- int mMinWindowSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- final int startingSize = mMinWindowSize;
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- mWindowMagnificationController.setWindowSize(startingSize, startingSize);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- final AccessibilityNodeInfo accessibilityNodeInfo =
- mirrorView.createAccessibilityNodeInfo();
- assertThat(accessibilityNodeInfo.getActionList()).doesNotContain(
- new AccessibilityAction(
- R.id.accessibility_action_decrease_window_width, null));
- }
-
- @Test
- public void windowHeightIsMin_noDecreaseWindowHeightA11yAction() {
- int mMinWindowSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- final int startingSize = mMinWindowSize;
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- mWindowMagnificationController.setWindowSize(startingSize, startingSize);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
- final AccessibilityNodeInfo accessibilityNodeInfo =
- mirrorView.createAccessibilityNodeInfo();
- assertThat(accessibilityNodeInfo.getActionList()).doesNotContain(
- new AccessibilityAction(
- R.id.accessibility_action_decrease_window_height, null));
- }
-
- @Test
- public void enableWindowMagnification_hasA11yWindowTitle() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- assertThat(getAccessibilityWindowTitle()).isEqualTo(getContext().getResources().getString(
- com.android.internal.R.string.android_system_label));
- }
-
- @Test
- public void enableWindowMagnificationWithScaleLessThanOne_enabled_disabled() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(0.9f, Float.NaN,
- Float.NaN);
- });
-
- assertThat(mWindowMagnificationController.getScale()).isEqualTo(Float.NaN);
- }
-
- @Test
- public void enableWindowMagnification_rotationIsChanged_updateRotationValue() {
- // the config orientation should not be undefined, since it would cause config.diff
- // returning 0 and thus the orientation changed would not be detected
- assertThat(mResources.getConfiguration().orientation).isNotEqualTo(ORIENTATION_UNDEFINED);
-
- final Configuration config = mResources.getConfiguration();
- config.orientation = config.orientation == ORIENTATION_LANDSCAPE ? ORIENTATION_PORTRAIT
- : ORIENTATION_LANDSCAPE;
- final int newRotation = simulateRotateTheDevice();
-
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- Float.NaN, Float.NaN));
-
- assertThat(mWindowMagnificationController.mRotation).isEqualTo(newRotation);
- }
-
- @Test
- public void enableWindowMagnification_registerComponentCallback() {
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- Float.NaN,
- Float.NaN));
-
- verify(mContext).registerComponentCallbacks(mWindowMagnificationController);
- }
-
- @Test
- public void onLocaleChanged_enabled_updateA11yWindowTitle() {
- final String newA11yWindowTitle = "new a11y window title";
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
- final TestableResources testableResources = getContext().getOrCreateTestableResources();
- testableResources.addOverride(com.android.internal.R.string.android_system_label,
- newA11yWindowTitle);
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_LOCALE);
- });
-
- assertThat(getAccessibilityWindowTitle()).isEqualTo(newA11yWindowTitle);
- }
-
- @Ignore("it's flaky in presubmit but works in abtd, filter for now. b/305654925")
- @Test
- public void onSingleTap_enabled_scaleAnimates() {
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.onSingleTap(mSpyView);
- });
-
- final View mirrorView = mSurfaceControlViewHost.getView();
-
- final AtomicDouble maxScaleX = new AtomicDouble();
- advanceTimeBy(mWaitBounceEffectDuration, /* runnableOnEachRefresh= */ () -> {
- // For some reason the fancy way doesn't compile...
- // maxScaleX.getAndAccumulate(mirrorView.getScaleX(), Math::max);
- final double oldMax = maxScaleX.get();
- final double newMax = Math.max(mirrorView.getScaleX(), oldMax);
- assertThat(maxScaleX.compareAndSet(oldMax, newMax)).isTrue();
- });
-
- assertThat(maxScaleX.get()).isGreaterThan(1.0);
- }
-
- @Test
- public void moveWindowMagnificationToTheBottom_enabledWithGestureInset_overlapFlagIsTrue() {
- final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- setSystemGestureInsets();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
- Float.NaN);
- });
-
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.moveWindowMagnifier(0, bounds.height());
- });
-
- ReferenceTestUtils.waitForCondition(() -> hasMagnificationOverlapFlag());
- }
-
- @Test
- public void moveWindowMagnificationToRightEdge_dragHandleMovesToLeftAndUpdatesTapExcludeRegion()
- throws RemoteException {
- final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- setSystemGestureInsets();
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(
- Float.NaN, Float.NaN, Float.NaN);
- });
- // Wait for Region updated.
- waitForIdleSync();
-
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController.moveWindowMagnifier(bounds.width(), 0);
- });
- // Wait for Region updated.
- waitForIdleSync();
-
- AttachedSurfaceControl viewRoot = mSurfaceControlViewHost.getRootSurfaceControl();
- // Verifying two times in: (1) enable window magnification (2) reposition drag handle
- verify(viewRoot, times(2)).setTouchableRegion(any());
-
- View dragButton = getInternalView(R.id.drag_handle);
- FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) dragButton.getLayoutParams();
- assertThat(params.gravity).isEqualTo(Gravity.BOTTOM | Gravity.LEFT);
- }
-
- @Test
- public void moveWindowMagnificationToLeftEdge_dragHandleMovesToRightAndUpdatesTapExcludeRegion()
- throws RemoteException {
- final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- setSystemGestureInsets();
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(
- Float.NaN, Float.NaN, Float.NaN);
- });
- // Wait for Region updated.
- waitForIdleSync();
-
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController.moveWindowMagnifier(-bounds.width(), 0);
- });
- // Wait for Region updated.
- waitForIdleSync();
-
- AttachedSurfaceControl viewRoot = mSurfaceControlViewHost.getRootSurfaceControl();
- // Verifying one times in: (1) enable window magnification
- verify(viewRoot).setTouchableRegion(any());
-
- View dragButton = getInternalView(R.id.drag_handle);
- FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) dragButton.getLayoutParams();
- assertThat(params.gravity).isEqualTo(Gravity.BOTTOM | Gravity.RIGHT);
- }
-
- @Test
- public void setMinimumWindowSize_enabled_expectedWindowSize() {
- final int minimumWindowSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- final int expectedWindowHeight = minimumWindowSize;
- final int expectedWindowWidth = minimumWindowSize;
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- Float.NaN, Float.NaN));
-
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.setWindowSize(expectedWindowWidth, expectedWindowHeight);
- actualWindowHeight.set(mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(mSurfaceControlViewHost.getView().getLayoutParams().width);
-
- });
-
- assertThat(actualWindowHeight.get()).isEqualTo(expectedWindowHeight);
- assertThat(actualWindowWidth.get()).isEqualTo(expectedWindowWidth);
- }
-
- @Test
- public void setMinimumWindowSizeThenEnable_expectedWindowSize() {
- final int minimumWindowSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- final int expectedWindowHeight = minimumWindowSize;
- final int expectedWindowWidth = minimumWindowSize;
-
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.setWindowSize(expectedWindowWidth, expectedWindowHeight);
- mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- Float.NaN, Float.NaN);
- actualWindowHeight.set(mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
-
- assertThat(actualWindowHeight.get()).isEqualTo(expectedWindowHeight);
- assertThat(actualWindowWidth.get()).isEqualTo(expectedWindowWidth);
- }
-
- @Test
- public void setWindowSizeLessThanMin_enabled_minimumWindowSize() {
- final int minimumWindowSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- Float.NaN, Float.NaN));
-
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.setWindowSize(minimumWindowSize - 10,
- minimumWindowSize - 10);
- actualWindowHeight.set(mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
-
- assertThat(actualWindowHeight.get()).isEqualTo(minimumWindowSize);
- assertThat(actualWindowWidth.get()).isEqualTo(minimumWindowSize);
- }
-
- @Test
- public void setWindowSizeLargerThanScreenSize_enabled_windowSizeIsScreenSize() {
- final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- Float.NaN, Float.NaN));
-
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.setWindowSize(bounds.width() + 10, bounds.height() + 10);
- actualWindowHeight.set(mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
-
- assertThat(actualWindowHeight.get()).isEqualTo(bounds.height());
- assertThat(actualWindowWidth.get()).isEqualTo(bounds.width());
- }
-
- @Test
- public void changeMagnificationSize_expectedWindowSize() {
- final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
-
- final float magnificationScaleLarge = 2.5f;
- final int initSize = Math.min(bounds.width(), bounds.height()) / 3;
- final int magnificationSize = (int) (initSize * magnificationScaleLarge)
- - (int) (initSize * magnificationScaleLarge) % 2;
-
- final int expectedWindowHeight = magnificationSize;
- final int expectedWindowWidth = magnificationSize;
-
- mInstrumentation.runOnMainSync(
- () ->
- mWindowMagnificationController.updateWindowMagnificationInternal(
- Float.NaN, Float.NaN, Float.NaN));
-
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController.changeMagnificationSize(
- WindowMagnificationSettings.MagnificationSize.LARGE);
- actualWindowHeight.set(
- mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(
- mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
-
- assertThat(actualWindowHeight.get()).isEqualTo(expectedWindowHeight);
- assertThat(actualWindowWidth.get()).isEqualTo(expectedWindowWidth);
- }
-
- @Test
- public void editModeOnDragCorner_resizesWindow() {
- final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
-
- final int startingSize = (int) (bounds.width() / 2);
-
- mInstrumentation.runOnMainSync(
- () ->
- mWindowMagnificationController.updateWindowMagnificationInternal(
- Float.NaN, Float.NaN, Float.NaN));
-
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
-
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController.setWindowSize(startingSize, startingSize);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- });
-
- waitForIdleSync();
-
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController
- .onDrag(getInternalView(R.id.bottom_right_corner), 2f, 1f);
- actualWindowHeight.set(
- mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(
- mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
-
- assertThat(actualWindowHeight.get()).isEqualTo(startingSize + 1);
- assertThat(actualWindowWidth.get()).isEqualTo(startingSize + 2);
- }
-
- @Test
- public void editModeOnDragEdge_resizesWindowInOnlyOneDirection() {
- final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
-
- final int startingSize = (int) (bounds.width() / 2f);
-
- mInstrumentation.runOnMainSync(
- () ->
- mWindowMagnificationController.updateWindowMagnificationInternal(
- Float.NaN, Float.NaN, Float.NaN));
-
- final AtomicInteger actualWindowHeight = new AtomicInteger();
- final AtomicInteger actualWindowWidth = new AtomicInteger();
-
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController.setWindowSize(startingSize, startingSize);
- mWindowMagnificationController.setEditMagnifierSizeMode(true);
- mWindowMagnificationController
- .onDrag(getInternalView(R.id.bottom_handle), 2f, 1f);
- actualWindowHeight.set(
- mSurfaceControlViewHost.getView().getLayoutParams().height);
- actualWindowWidth.set(
- mSurfaceControlViewHost.getView().getLayoutParams().width);
- });
- assertThat(actualWindowHeight.get()).isEqualTo(startingSize + 1);
- assertThat(actualWindowWidth.get()).isEqualTo(startingSize);
- }
-
- @Test
- public void setWindowCenterOutOfScreen_enabled_magnificationCenterIsInsideTheScreen() {
-
- final int minimumWindowSize = mResources.getDimensionPixelSize(
- com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
- final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
- Float.NaN, Float.NaN));
-
- final AtomicInteger magnificationCenterX = new AtomicInteger();
- final AtomicInteger magnificationCenterY = new AtomicInteger();
- mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.setWindowSizeAndCenter(minimumWindowSize,
- minimumWindowSize, bounds.right, bounds.bottom);
- magnificationCenterX.set((int) mWindowMagnificationController.getCenterX());
- magnificationCenterY.set((int) mWindowMagnificationController.getCenterY());
- });
-
- assertThat(magnificationCenterX.get()).isLessThan(bounds.right);
- assertThat(magnificationCenterY.get()).isLessThan(bounds.bottom);
- }
-
- @Test
- public void performSingleTap_DragHandle() {
- final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
- mInstrumentation.runOnMainSync(
- () -> {
- mWindowMagnificationController.updateWindowMagnificationInternal(
- 1.5f, bounds.centerX(), bounds.centerY());
- });
- View dragButton = getInternalView(R.id.drag_handle);
-
- // Perform a single-tap
- final long downTime = SystemClock.uptimeMillis();
- dragButton.dispatchTouchEvent(
- obtainMotionEvent(downTime, 0, ACTION_DOWN, 100, 100));
- dragButton.dispatchTouchEvent(
- obtainMotionEvent(downTime, downTime, ACTION_UP, 100, 100));
-
- verify(mSurfaceControlViewHost).setView(any(View.class), any());
- }
-
- private <T extends View> T getInternalView(@IdRes int idRes) {
- View mirrorView = mSurfaceControlViewHost.getView();
- T view = mirrorView.findViewById(idRes);
- assertThat(view).isNotNull();
- return view;
- }
-
- private MotionEvent obtainMotionEvent(long downTime, long eventTime, int action, float x,
- float y) {
- return mMotionEventHelper.obtainMotionEvent(downTime, eventTime, action, x, y);
- }
-
- private String getAccessibilityWindowTitle() {
- final View mirrorView = mSurfaceControlViewHost.getView();
- if (mirrorView == null) {
- return null;
- }
- WindowManager.LayoutParams layoutParams =
- (WindowManager.LayoutParams) mirrorView.getLayoutParams();
- return layoutParams.accessibilityTitle.toString();
- }
-
- private boolean hasMagnificationOverlapFlag() {
- return (mSysUiState.getFlags() & SYSUI_STATE_MAGNIFICATION_OVERLAP) != 0;
- }
-
- private void setSystemGestureInsets() {
- final WindowInsets testInsets = new WindowInsets.Builder()
- .setInsets(systemGestures(), Insets.of(0, 0, 0, 10))
- .build();
- mWindowManager.setWindowInsets(testInsets);
- }
-
- private int updateMirrorSurfaceMarginDimension() {
- return mContext.getResources().getDimensionPixelSize(
- R.dimen.magnification_mirror_surface_margin);
- }
-
- @Surface.Rotation
- private int simulateRotateTheDevice() {
- final Display display = Mockito.spy(mContext.getDisplay());
- final int currentRotation = display.getRotation();
- final int newRotation = (currentRotation + 1) % 4;
- when(display.getRotation()).thenReturn(newRotation);
- when(mContext.getDisplay()).thenReturn(display);
- return newRotation;
- }
-
- // advance time based on the device frame refresh rate
- private void advanceTimeBy(long timeDelta) {
- advanceTimeBy(timeDelta, /* runnableOnEachRefresh= */ null);
- }
-
- // advance time based on the device frame refresh rate, and trigger runnable on each refresh
- private void advanceTimeBy(long timeDelta, @Nullable Runnable runnableOnEachRefresh) {
- final float frameRate = mContext.getDisplay().getRefreshRate();
- final int timeSlot = (int) (1000 / frameRate);
- int round = (int) Math.ceil((double) timeDelta / timeSlot);
- for (; round >= 0; round--) {
- mInstrumentation.runOnMainSync(() -> {
- mAnimatorTestRule.advanceTimeBy(timeSlot);
- if (runnableOnEachRefresh != null) {
- runnableOnEachRefresh.run();
- }
- });
- }
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt
index 288ed4d..a1f59c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt
@@ -20,18 +20,20 @@
import android.animation.AnimatorTestRuleToolkit
import android.animation.MotionControl
import android.animation.recordMotion
+import android.graphics.Color
+import android.graphics.PointF
import android.graphics.drawable.GradientDrawable
import android.platform.test.annotations.MotionTest
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.filters.SmallTest
-import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.android.systemui.SysuiTestCase
import com.android.systemui.activity.EmptyTestActivity
import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
+import com.android.systemui.runOnMainThreadAndWaitForIdleSync
import kotlin.test.assertTrue
import org.junit.Rule
import org.junit.Test
@@ -47,13 +49,25 @@
@SmallTest
@MotionTest
@RunWith(ParameterizedAndroidJunit4::class)
-class TransitionAnimatorTest(val useSpring: Boolean) : SysuiTestCase() {
+class TransitionAnimatorTest(
+ private val fadeWindowBackgroundLayer: Boolean,
+ private val isLaunching: Boolean,
+ private val useSpring: Boolean,
+) : SysuiTestCase() {
companion object {
private const val GOLDENS_PATH = "frameworks/base/packages/SystemUI/tests/goldens"
- @get:Parameters(name = "{0}")
+ @get:Parameters(name = "fadeBackground={0}, isLaunching={1}, useSpring={2}")
@JvmStatic
- val useSpringValues = booleanArrayOf(false, true).toList()
+ val parameterValues = buildList {
+ booleanArrayOf(true, false).forEach { fadeBackground ->
+ booleanArrayOf(true, false).forEach { isLaunching ->
+ booleanArrayOf(true, false).forEach { useSpring ->
+ add(arrayOf(fadeBackground, isLaunching, useSpring))
+ }
+ }
+ }
+ }
}
private val kosmos = Kosmos()
@@ -66,11 +80,23 @@
ActivityTransitionAnimator.SPRING_TIMINGS,
ActivityTransitionAnimator.SPRING_INTERPOLATORS,
)
- private val withSpring =
- if (useSpring) {
- "_withSpring"
+ private val fade =
+ if (fadeWindowBackgroundLayer) {
+ "withFade"
} else {
- ""
+ "withoutFade"
+ }
+ private val direction =
+ if (isLaunching) {
+ "whenLaunching"
+ } else {
+ "whenReturning"
+ }
+ private val mode =
+ if (useSpring) {
+ "withSpring"
+ } else {
+ "withAnimator"
}
@get:Rule(order = 1) val activityRule = ActivityScenarioRule(EmptyTestActivity::class.java)
@@ -83,113 +109,75 @@
)
@Test
- fun backgroundAnimation_whenLaunching() {
- val backgroundLayer = GradientDrawable().apply { alpha = 0 }
- val animator =
- setUpTest(backgroundLayer, isLaunching = true).apply {
- getInstrumentation().runOnMainSync { start() }
- }
+ fun backgroundAnimationTimeSeries() {
+ val transitionContainer = createScene()
+ val backgroundLayer = createBackgroundLayer()
+ val animation = createAnimation(transitionContainer, backgroundLayer)
- val recordedMotion = recordMotion(backgroundLayer, animator)
+ val recordedMotion = record(backgroundLayer, animation)
motionRule
.assertThat(recordedMotion)
- .timeSeriesMatchesGolden("backgroundAnimation_whenLaunching$withSpring")
+ .timeSeriesMatchesGolden("backgroundAnimationTimeSeries_${fade}_${direction}_$mode")
}
- @Test
- fun backgroundAnimation_whenReturning() {
- val backgroundLayer = GradientDrawable().apply { alpha = 0 }
- val animator =
- setUpTest(backgroundLayer, isLaunching = false).apply {
- getInstrumentation().runOnMainSync { start() }
- }
-
- val recordedMotion = recordMotion(backgroundLayer, animator)
-
- motionRule
- .assertThat(recordedMotion)
- .timeSeriesMatchesGolden("backgroundAnimation_whenReturning$withSpring")
- }
-
- @Test
- fun backgroundAnimationWithoutFade_whenLaunching() {
- val backgroundLayer = GradientDrawable().apply { alpha = 0 }
- val animator =
- setUpTest(backgroundLayer, isLaunching = true, fadeWindowBackgroundLayer = false)
- .apply { getInstrumentation().runOnMainSync { start() } }
-
- val recordedMotion = recordMotion(backgroundLayer, animator)
-
- motionRule
- .assertThat(recordedMotion)
- .timeSeriesMatchesGolden("backgroundAnimationWithoutFade_whenLaunching$withSpring")
- }
-
- @Test
- fun backgroundAnimationWithoutFade_whenReturning() {
- val backgroundLayer = GradientDrawable().apply { alpha = 0 }
- val animator =
- setUpTest(backgroundLayer, isLaunching = false, fadeWindowBackgroundLayer = false)
- .apply { getInstrumentation().runOnMainSync { start() } }
-
- val recordedMotion = recordMotion(backgroundLayer, animator)
-
- motionRule
- .assertThat(recordedMotion)
- .timeSeriesMatchesGolden("backgroundAnimationWithoutFade_whenReturning$withSpring")
- }
-
- private fun setUpTest(
- backgroundLayer: GradientDrawable,
- isLaunching: Boolean,
- fadeWindowBackgroundLayer: Boolean = true,
- ): TransitionAnimator.Animation {
+ private fun createScene(): ViewGroup {
lateinit var transitionContainer: ViewGroup
activityRule.scenario.onActivity { activity ->
- transitionContainer = FrameLayout(activity).apply { setBackgroundColor(0x00FF00) }
+ transitionContainer = FrameLayout(activity)
activity.setContentView(transitionContainer)
}
waitForIdleSync()
+ return transitionContainer
+ }
+ private fun createBackgroundLayer() =
+ GradientDrawable().apply {
+ setColor(Color.BLACK)
+ alpha = 0
+ }
+
+ private fun createAnimation(
+ transitionContainer: ViewGroup,
+ backgroundLayer: GradientDrawable,
+ ): TransitionAnimator.Animation {
val controller = TestController(transitionContainer, isLaunching)
- return transitionAnimator.createAnimation(
- controller,
- controller.createAnimatorState(),
- createEndState(transitionContainer),
- backgroundLayer,
- fadeWindowBackgroundLayer,
- useSpring = useSpring,
- )
- }
- private fun createEndState(container: ViewGroup): TransitionAnimator.State {
val containerLocation = IntArray(2)
- container.getLocationOnScreen(containerLocation)
- return TransitionAnimator.State(
- left = containerLocation[0],
- top = containerLocation[1],
- right = containerLocation[0] + 320,
- bottom = containerLocation[1] + 690,
- topCornerRadius = 0f,
- bottomCornerRadius = 0f,
- )
+ transitionContainer.getLocationOnScreen(containerLocation)
+ val endState =
+ TransitionAnimator.State(
+ left = containerLocation[0],
+ top = containerLocation[1],
+ right = containerLocation[0] + 320,
+ bottom = containerLocation[1] + 690,
+ topCornerRadius = 0f,
+ bottomCornerRadius = 0f,
+ )
+
+ val startVelocity =
+ if (useSpring) {
+ PointF(2500f, 30000f)
+ } else {
+ null
+ }
+
+ return transitionAnimator
+ .createAnimation(
+ controller,
+ controller.createAnimatorState(),
+ endState,
+ backgroundLayer,
+ fadeWindowBackgroundLayer,
+ startVelocity = startVelocity,
+ )
+ .apply { runOnMainThreadAndWaitForIdleSync { start() } }
}
- private fun recordMotion(
+ private fun record(
backgroundLayer: GradientDrawable,
animation: TransitionAnimator.Animation,
): RecordedMotion {
- fun record(motionControl: MotionControl, sampleIntervalMs: Long): RecordedMotion {
- return motionRule.recordMotion(
- AnimatorRuleRecordingSpec(backgroundLayer, motionControl, sampleIntervalMs) {
- feature(DrawableFeatureCaptures.bounds, "bounds")
- feature(DrawableFeatureCaptures.cornerRadii, "corner_radii")
- feature(DrawableFeatureCaptures.alpha, "alpha")
- }
- )
- }
-
val motionControl: MotionControl
val sampleIntervalMs: Long
if (useSpring) {
@@ -204,9 +192,13 @@
sampleIntervalMs = 20L
}
- var recording: RecordedMotion? = null
- getInstrumentation().runOnMainSync { recording = record(motionControl, sampleIntervalMs) }
- return recording!!
+ return motionRule.recordMotion(
+ AnimatorRuleRecordingSpec(backgroundLayer, motionControl, sampleIntervalMs) {
+ feature(DrawableFeatureCaptures.bounds, "bounds")
+ feature(DrawableFeatureCaptures.cornerRadii, "corner_radii")
+ feature(DrawableFeatureCaptures.alpha, "alpha")
+ }
+ )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
index 6061063..5624815 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
@@ -20,6 +20,7 @@
import static com.android.systemui.Flags.FLAG_CLIPBOARD_SHARED_TRANSITIONS;
import static com.android.systemui.Flags.FLAG_CLIPBOARD_USE_DESCRIPTION_MIMETYPE;
+import static com.android.systemui.Flags.FLAG_SHOW_CLIPBOARD_INDICATION;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ACTION_SHOWN;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_DISMISS_TAPPED;
import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_EXPANDED_FROM_MINIMIZED;
@@ -121,6 +122,24 @@
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+ private class FakeClipboardIndicationProvider implements ClipboardIndicationProvider {
+ private ClipboardIndicationCallback mIndicationCallback;
+
+ public void notifyIndicationTextChanged(CharSequence indicationText) {
+ if (mIndicationCallback != null) {
+ mIndicationCallback.onIndicationTextChanged(indicationText);
+ }
+ }
+
+ @Override
+ public void getIndicationText(ClipboardIndicationCallback callback) {
+ mIndicationCallback = callback;
+ }
+ }
+
+ private FakeClipboardIndicationProvider mClipboardIndicationProvider =
+ new FakeClipboardIndicationProvider();
+
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
@@ -156,6 +175,7 @@
mExecutor,
mClipboardImageLoader,
mClipboardTransitionExecutor,
+ mClipboardIndicationProvider,
mUiEventLogger);
verify(mClipboardOverlayView).setCallbacks(mOverlayCallbacksCaptor.capture());
mCallbacks = mOverlayCallbacksCaptor.getValue();
@@ -305,6 +325,17 @@
}
@Test
+ @EnableFlags(FLAG_SHOW_CLIPBOARD_INDICATION)
+ public void test_onIndicationTextChanged_setIndicationTextCorrectly() {
+ initController();
+ mOverlayController.setClipData(mSampleClipData, "");
+
+ mClipboardIndicationProvider.notifyIndicationTextChanged("copied");
+
+ verify(mClipboardOverlayView).setIndicationText("copied");
+ }
+
+ @Test
@DisableFlags(FLAG_CLIPBOARD_SHARED_TRANSITIONS)
public void test_viewCallbacks_onShareTapped_sharedTransitionsOff() {
initController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
index df50f76..24bca70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -31,7 +31,6 @@
import static org.mockito.Mockito.when;
import android.app.IActivityManager;
-import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
@@ -80,6 +79,7 @@
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
+import com.android.systemui.user.domain.interactor.UserLogoutInteractor;
import com.android.systemui.util.RingerModeLiveData;
import com.android.systemui.util.RingerModeTracker;
import com.android.systemui.util.settings.FakeGlobalSettings;
@@ -106,7 +106,6 @@
@Mock private GlobalActions.GlobalActionsManager mWindowManagerFuncs;
@Mock private AudioManager mAudioManager;
- @Mock private DevicePolicyManager mDevicePolicyManager;
@Mock private LockPatternUtils mLockPatternUtils;
@Mock private BroadcastDispatcher mBroadcastDispatcher;
@Mock private TelephonyListenerManager mTelephonyListenerManager;
@@ -140,6 +139,7 @@
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock private DialogTransitionAnimator mDialogTransitionAnimator;
@Mock private SelectedUserInteractor mSelectedUserInteractor;
+ @Mock private UserLogoutInteractor mLogoutInteractor;
@Mock private OnBackInvokedDispatcher mOnBackInvokedDispatcher;
@Captor private ArgumentCaptor<OnBackInvokedCallback> mOnBackInvokedCallback;
@@ -166,7 +166,6 @@
mGlobalActionsDialogLite = new GlobalActionsDialogLite(mContext,
mWindowManagerFuncs,
mAudioManager,
- mDevicePolicyManager,
mLockPatternUtils,
mBroadcastDispatcher,
mTelephonyListenerManager,
@@ -198,6 +197,7 @@
mKeyguardUpdateMonitor,
mDialogTransitionAnimator,
mSelectedUserInteractor,
+ mLogoutInteractor,
mInteractor);
mGlobalActionsDialogLite.setZeroDialogPressDelayForTesting();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
index b3bd7d1..c7beb15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
@@ -23,7 +23,6 @@
import android.view.accessibility.AccessibilityManager
import com.android.app.viewcapture.ViewCaptureAwareWindowManager
import com.android.systemui.dump.DumpManager
-import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
@@ -43,7 +42,6 @@
dumpManager: DumpManager,
powerManager: PowerManager,
mainHandler: Handler,
- mediaTttFlags: MediaTttFlags,
uiEventLogger: MediaTttReceiverUiEventLogger,
viewUtil: ViewUtil,
wakeLockBuilder: WakeLock.Builder,
@@ -62,7 +60,6 @@
dumpManager,
powerManager,
mainHandler,
- mediaTttFlags,
uiEventLogger,
viewUtil,
wakeLockBuilder,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 9afa5ad..378dd45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -37,7 +37,6 @@
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
-import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.res.R
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -55,7 +54,6 @@
import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@@ -66,32 +64,18 @@
class MediaTttChipControllerReceiverTest : SysuiTestCase() {
private lateinit var controllerReceiver: MediaTttChipControllerReceiver
- @Mock
- private lateinit var packageManager: PackageManager
- @Mock
- private lateinit var applicationInfo: ApplicationInfo
- @Mock
- private lateinit var logger: MediaTttReceiverLogger
- @Mock
- private lateinit var accessibilityManager: AccessibilityManager
- @Mock
- private lateinit var configurationController: ConfigurationController
- @Mock
- private lateinit var dumpManager: DumpManager
- @Mock
- private lateinit var mediaTttFlags: MediaTttFlags
- @Mock
- private lateinit var powerManager: PowerManager
- @Mock
- private lateinit var viewUtil: ViewUtil
- @Mock
- private lateinit var windowManager: WindowManager
- @Mock
- private lateinit var commandQueue: CommandQueue
- @Mock
- private lateinit var rippleController: MediaTttReceiverRippleController
- @Mock
- private lateinit var lazyViewCapture: Lazy<ViewCapture>
+ @Mock private lateinit var packageManager: PackageManager
+ @Mock private lateinit var applicationInfo: ApplicationInfo
+ @Mock private lateinit var logger: MediaTttReceiverLogger
+ @Mock private lateinit var accessibilityManager: AccessibilityManager
+ @Mock private lateinit var configurationController: ConfigurationController
+ @Mock private lateinit var dumpManager: DumpManager
+ @Mock private lateinit var powerManager: PowerManager
+ @Mock private lateinit var viewUtil: ViewUtil
+ @Mock private lateinit var windowManager: WindowManager
+ @Mock private lateinit var commandQueue: CommandQueue
+ @Mock private lateinit var rippleController: MediaTttReceiverRippleController
+ @Mock private lateinit var lazyViewCapture: Lazy<ViewCapture>
private lateinit var viewCaptureAwareWindowManager: ViewCaptureAwareWindowManager
private lateinit var commandQueueCallback: CommandQueue.Callbacks
private lateinit var fakeAppIconDrawable: Drawable
@@ -106,14 +90,17 @@
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(true)
fakeAppIconDrawable = context.getDrawable(R.drawable.ic_cake)!!
whenever(packageManager.getApplicationIcon(PACKAGE_NAME)).thenReturn(fakeAppIconDrawable)
whenever(applicationInfo.loadLabel(packageManager)).thenReturn(APP_NAME)
- whenever(packageManager.getApplicationInfo(
- eq(PACKAGE_NAME), any<PackageManager.ApplicationInfoFlags>()
- )).thenReturn(applicationInfo)
+ whenever(
+ packageManager.getApplicationInfo(
+ eq(PACKAGE_NAME),
+ any<PackageManager.ApplicationInfoFlags>(),
+ )
+ )
+ .thenReturn(applicationInfo)
context.setMockPackageManager(packageManager)
fakeClock = FakeSystemClock()
@@ -127,27 +114,31 @@
fakeWakeLockBuilder = WakeLockFake.Builder(context)
fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
- viewCaptureAwareWindowManager = ViewCaptureAwareWindowManager(windowManager,
- lazyViewCapture, isViewCaptureEnabled = false)
- controllerReceiver = FakeMediaTttChipControllerReceiver(
- commandQueue,
- context,
- logger,
- viewCaptureAwareWindowManager,
- fakeExecutor,
- accessibilityManager,
- configurationController,
- dumpManager,
- powerManager,
- Handler.getMain(),
- mediaTttFlags,
- receiverUiEventLogger,
- viewUtil,
- fakeWakeLockBuilder,
- fakeClock,
- rippleController,
- temporaryViewUiEventLogger,
- )
+ viewCaptureAwareWindowManager =
+ ViewCaptureAwareWindowManager(
+ windowManager,
+ lazyViewCapture,
+ isViewCaptureEnabled = false,
+ )
+ controllerReceiver =
+ FakeMediaTttChipControllerReceiver(
+ commandQueue,
+ context,
+ logger,
+ viewCaptureAwareWindowManager,
+ fakeExecutor,
+ accessibilityManager,
+ configurationController,
+ dumpManager,
+ powerManager,
+ Handler.getMain(),
+ receiverUiEventLogger,
+ viewUtil,
+ fakeWakeLockBuilder,
+ fakeClock,
+ rippleController,
+ temporaryViewUiEventLogger,
+ )
controllerReceiver.start()
val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -156,48 +147,18 @@
}
@Test
- fun commandQueueCallback_flagOff_noCallbackAdded() {
- reset(commandQueue)
- whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(false)
-
- controllerReceiver = MediaTttChipControllerReceiver(
- commandQueue,
- context,
- logger,
- viewCaptureAwareWindowManager,
- FakeExecutor(FakeSystemClock()),
- accessibilityManager,
- configurationController,
- dumpManager,
- powerManager,
- Handler.getMain(),
- mediaTttFlags,
- receiverUiEventLogger,
- viewUtil,
- fakeWakeLockBuilder,
- fakeClock,
- rippleController,
- temporaryViewUiEventLogger,
- )
- controllerReceiver.start()
-
- verify(commandQueue, never()).addCallback(any())
- }
-
- @Test
fun commandQueueCallback_closeToSender_triggersChip() {
val appName = "FakeAppName"
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
routeInfo,
/* appIcon= */ null,
- appName
+ appName,
)
assertThat(getChipView().getAppIconView().contentDescription).isEqualTo(appName)
- assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
- MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER.id
- )
+ assertThat(uiEventLoggerFake.eventId(0))
+ .isEqualTo(MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER.id)
assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
}
@@ -207,45 +168,44 @@
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
routeInfo,
null,
- null
+ null,
)
verify(windowManager, never()).addView(any(), any())
- assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
- MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER.id
- )
+ assertThat(uiEventLoggerFake.eventId(0))
+ .isEqualTo(MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER.id)
assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
}
@Test
fun commandQueueCallback_transferToReceiverSucceeded_noChipShown() {
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
- routeInfo,
- null,
- null
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+ routeInfo,
+ null,
+ null,
)
verify(windowManager, never()).addView(any(), any())
- assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+ assertThat(uiEventLoggerFake.eventId(0))
+ .isEqualTo(
MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_SUCCEEDED.id
- )
+ )
assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
}
@Test
fun commandQueueCallback_transferToReceiverFailed_noChipShown() {
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_FAILED,
- routeInfo,
- null,
- null
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_FAILED,
+ routeInfo,
+ null,
+ null,
)
verify(windowManager, never()).addView(any(), any())
- assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
- MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_FAILED.id
- )
+ assertThat(uiEventLoggerFake.eventId(0))
+ .isEqualTo(MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_FAILED.id)
assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
}
@@ -255,14 +215,14 @@
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
routeInfo,
null,
- null
+ null,
)
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
routeInfo,
null,
- null
+ null,
)
val viewCaptor = ArgumentCaptor.forClass(View::class.java)
@@ -276,14 +236,14 @@
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
routeInfo,
null,
- null
+ null,
)
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
null,
- null
+ null,
)
val viewCaptor = ArgumentCaptor.forClass(View::class.java)
@@ -297,14 +257,14 @@
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
routeInfo,
null,
- null
+ null,
)
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
null,
- null
+ null,
)
assertThat(uiEventLoggerFake[0].instanceId).isEqualTo(uiEventLoggerFake[1].instanceId)
@@ -316,14 +276,14 @@
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
routeInfo,
null,
- null
+ null,
)
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_FAILED,
routeInfo,
null,
- null
+ null,
)
val viewCaptor = ArgumentCaptor.forClass(View::class.java)
@@ -334,19 +294,19 @@
@Test
fun commandQueueCallback_closeThenFar_wakeLockAcquiredThenReleased() {
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
- routeInfo,
- null,
- null
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
+ routeInfo,
+ null,
+ null,
)
assertThat(fakeWakeLock.isHeld).isTrue()
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
- routeInfo,
- null,
- null
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
+ routeInfo,
+ null,
+ null,
)
assertThat(fakeWakeLock.isHeld).isFalse()
@@ -355,10 +315,10 @@
@Test
fun commandQueueCallback_closeThenFar_wakeLockNeverAcquired() {
commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
- StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
- routeInfo,
- null,
- null
+ StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_FAR_FROM_SENDER,
+ routeInfo,
+ null,
+ null,
)
assertThat(fakeWakeLock.isHeld).isFalse()
@@ -370,7 +330,7 @@
StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
routeInfo,
null,
- null
+ null,
)
verify(logger).logStateChange(any(), any(), any())
@@ -391,10 +351,12 @@
val view = getChipView()
assertThat(view.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
assertThat(view.getAppIconView().contentDescription)
- .isEqualTo(context.getString(
- R.string.media_transfer_receiver_content_description_with_app_name,
- APP_NAME,
- ))
+ .isEqualTo(
+ context.getString(
+ R.string.media_transfer_receiver_content_description_with_app_name,
+ APP_NAME,
+ )
+ )
}
@Test
@@ -463,7 +425,7 @@
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
routeInfo,
null,
- APP_NAME
+ APP_NAME,
)
verify(windowManager, never()).addView(any(), any())
@@ -476,10 +438,11 @@
}
private fun getChipReceiverInfo(packageName: String?): ChipReceiverInfo {
- val routeInfo = MediaRoute2Info.Builder("id", "Test route name")
- .addFeature("feature")
- .setClientPackageName(packageName)
- .build()
+ val routeInfo =
+ MediaRoute2Info.Builder("id", "Test route name")
+ .addFeature("feature")
+ .setClientPackageName(packageName)
+ .build()
return ChipReceiverInfo(
routeInfo,
null,
@@ -495,7 +458,8 @@
private const val APP_NAME = "Fake app name"
private const val PACKAGE_NAME = "com.android.systemui"
-private val routeInfo = MediaRoute2Info.Builder("id", "Test route name")
- .addFeature("feature")
- .setClientPackageName(PACKAGE_NAME)
- .build()
+private val routeInfo =
+ MediaRoute2Info.Builder("id", "Test route name")
+ .addFeature("feature")
+ .setClientPackageName(PACKAGE_NAME)
+ .build()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
index b4cad6b..c90ac59 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
@@ -41,7 +41,6 @@
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.common.shared.model.Text.Companion.loadText
import com.android.systemui.dump.DumpManager
-import com.android.systemui.media.taptotransfer.MediaTttFlags
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.res.R
import com.android.systemui.statusbar.CommandQueue
@@ -95,7 +94,6 @@
@Mock private lateinit var falsingCollector: FalsingCollector
@Mock private lateinit var chipbarLogger: ChipbarLogger
@Mock private lateinit var logger: MediaTttSenderLogger
- @Mock private lateinit var mediaTttFlags: MediaTttFlags
@Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var powerManager: PowerManager
@Mock private lateinit var viewUtil: ViewUtil
@@ -118,7 +116,6 @@
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(true)
whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any())).thenReturn(TIMEOUT)
fakeAppIconDrawable = context.getDrawable(R.drawable.ic_cake)!!
@@ -127,7 +124,7 @@
whenever(
packageManager.getApplicationInfo(
eq(PACKAGE_NAME),
- any<PackageManager.ApplicationInfoFlags>()
+ any<PackageManager.ApplicationInfoFlags>(),
)
)
.thenReturn(applicationInfo)
@@ -148,8 +145,11 @@
ChipbarCoordinator(
context,
chipbarLogger,
- ViewCaptureAwareWindowManager(windowManager, lazyViewCapture,
- isViewCaptureEnabled = false),
+ ViewCaptureAwareWindowManager(
+ windowManager,
+ lazyViewCapture,
+ isViewCaptureEnabled = false,
+ ),
fakeExecutor,
accessibilityManager,
configurationController,
@@ -174,7 +174,6 @@
context,
dumpManager,
logger,
- mediaTttFlags,
uiEventLogger,
)
underTest.start()
@@ -183,30 +182,11 @@
}
@Test
- fun commandQueueCallback_flagOff_noCallbackAdded() {
- reset(commandQueue)
- whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(false)
- underTest =
- MediaTttSenderCoordinator(
- chipbarCoordinator,
- commandQueue,
- context,
- dumpManager,
- logger,
- mediaTttFlags,
- uiEventLogger,
- )
- underTest.start()
-
- verify(commandQueue, never()).addCallback(any())
- }
-
- @Test
fun commandQueueCallback_almostCloseToStartCast_triggersCorrectChip() {
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
routeInfo,
- null
+ null,
)
val chipbarView = getChipbarView()
@@ -220,13 +200,7 @@
assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST.id)
verify(vibratorHelper)
- .vibrate(
- any(),
- any(),
- any<VibrationEffect>(),
- any(),
- any<VibrationAttributes>(),
- )
+ .vibrate(any(), any(), any<VibrationEffect>(), any(), any<VibrationAttributes>())
}
@Test
@@ -249,7 +223,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
routeInfo,
- null
+ null,
)
val chipbarView = getChipbarView()
@@ -263,13 +237,7 @@
assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST.id)
verify(vibratorHelper)
- .vibrate(
- any(),
- any(),
- any<VibrationEffect>(),
- any(),
- any<VibrationAttributes>(),
- )
+ .vibrate(any(), any(), any<VibrationEffect>(), any(), any<VibrationAttributes>())
}
@Test
@@ -277,7 +245,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
routeInfo,
- null
+ null,
)
val chipbarView = getChipbarView()
@@ -291,13 +259,7 @@
assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED.id)
verify(vibratorHelper)
- .vibrate(
- any(),
- any(),
- any<VibrationEffect>(),
- any(),
- any<VibrationAttributes>(),
- )
+ .vibrate(any(), any(), any<VibrationEffect>(), any(), any<VibrationAttributes>())
}
@Test
@@ -320,7 +282,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
routeInfo,
- null
+ null,
)
val chipbarView = getChipbarView()
@@ -334,13 +296,7 @@
assertThat(uiEventLoggerFake.eventId(0))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED.id)
verify(vibratorHelper)
- .vibrate(
- any(),
- any(),
- any<VibrationEffect>(),
- any(),
- any<VibrationAttributes>(),
- )
+ .vibrate(any(), any(), any<VibrationEffect>(), any(), any<VibrationAttributes>())
}
@Test
@@ -350,7 +306,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
- null
+ null,
)
val chipbarView = getChipbarView()
@@ -364,13 +320,7 @@
assertThat(uiEventLoggerFake.eventId(2))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id)
verify(vibratorHelper, never())
- .vibrate(
- any(),
- any(),
- any<VibrationEffect>(),
- any(),
- any<VibrationAttributes>(),
- )
+ .vibrate(any(), any(), any<VibrationEffect>(), any(), any<VibrationAttributes>())
}
@Test
@@ -380,7 +330,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
- null
+ null,
)
// Event index 2 since initially displaying the triggered chip would also log two events.
@@ -397,7 +347,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
- /* undoCallback= */ null
+ /* undoCallback= */ null,
)
val chipbarView = getChipbarView()
@@ -452,7 +402,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
routeInfo,
- null
+ null,
)
val chipbarView = getChipbarView()
@@ -466,13 +416,7 @@
assertThat(uiEventLoggerFake.eventId(2))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id)
verify(vibratorHelper, never())
- .vibrate(
- any(),
- any(),
- any<VibrationEffect>(),
- any(),
- any<VibrationAttributes>(),
- )
+ .vibrate(any(), any(), any<VibrationEffect>(), any(), any<VibrationAttributes>())
}
@Test
@@ -481,7 +425,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
routeInfo,
- /* undoCallback= */ null
+ /* undoCallback= */ null,
)
val chipbarView = getChipbarView()
@@ -538,7 +482,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
routeInfo,
- null
+ null,
)
val chipbarView = getChipbarView()
@@ -553,13 +497,7 @@
assertThat(uiEventLoggerFake.eventId(2))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id)
verify(vibratorHelper)
- .vibrate(
- any(),
- any(),
- any<VibrationEffect>(),
- any(),
- any<VibrationAttributes>(),
- )
+ .vibrate(any(), any(), any<VibrationEffect>(), any(), any<VibrationAttributes>())
}
@Test
@@ -567,13 +505,13 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
routeInfo,
- null
+ null,
)
reset(vibratorHelper)
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED,
routeInfo,
- null
+ null,
)
val chipbarView = getChipbarView()
@@ -588,13 +526,7 @@
assertThat(uiEventLoggerFake.eventId(2))
.isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id)
verify(vibratorHelper)
- .vibrate(
- any(),
- any(),
- any<VibrationEffect>(),
- any(),
- any<VibrationAttributes>(),
- )
+ .vibrate(any(), any(), any<VibrationEffect>(), any(), any<VibrationAttributes>())
}
@Test
@@ -602,7 +534,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
verify(windowManager, never()).addView(any(), any())
@@ -615,13 +547,13 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
routeInfo,
- null
+ null,
)
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
val viewCaptor = ArgumentCaptor.forClass(View::class.java)
@@ -635,7 +567,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
routeInfo,
- null
+ null,
)
assertThat(fakeWakeLock.isHeld).isTrue()
@@ -643,7 +575,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
assertThat(fakeWakeLock.isHeld).isFalse()
@@ -654,7 +586,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
assertThat(fakeWakeLock.isHeld).isFalse()
@@ -672,7 +604,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
routeInfo,
- null
+ null,
)
verify(windowManager).addView(any(), any())
reset(windowManager)
@@ -680,7 +612,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
routeInfo,
- null
+ null,
)
verify(logger).logInvalidStateTransitionError(any(), any())
@@ -692,7 +624,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
routeInfo,
- null
+ null,
)
verify(windowManager).addView(any(), any())
reset(windowManager)
@@ -700,7 +632,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
routeInfo,
- null
+ null,
)
verify(logger).logInvalidStateTransitionError(any(), any())
@@ -713,14 +645,14 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
- null
+ null,
)
reset(windowManager)
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
routeInfo,
- null
+ null,
)
verify(logger).logInvalidStateTransitionError(any(), any())
@@ -733,14 +665,14 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
routeInfo,
- null
+ null,
)
reset(windowManager)
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
- null
+ null,
)
verify(logger).logInvalidStateTransitionError(any(), any())
@@ -752,7 +684,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
routeInfo,
- null
+ null,
)
verify(windowManager).addView(any(), any())
reset(windowManager)
@@ -760,7 +692,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
- null
+ null,
)
verify(logger).logInvalidStateTransitionError(any(), any())
@@ -772,7 +704,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
routeInfo,
- null
+ null,
)
verify(windowManager).addView(any(), any())
reset(windowManager)
@@ -780,7 +712,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
routeInfo,
- null
+ null,
)
verify(logger).logInvalidStateTransitionError(any(), any())
@@ -792,7 +724,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
routeInfo,
- null
+ null,
)
verify(windowManager).addView(any(), any())
reset(windowManager)
@@ -800,7 +732,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
routeInfo,
- null
+ null,
)
verify(logger).logInvalidStateTransitionError(any(), any())
@@ -812,7 +744,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
routeInfo,
- null
+ null,
)
verify(windowManager).addView(any(), any())
reset(windowManager)
@@ -820,7 +752,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED,
routeInfo,
- null
+ null,
)
verify(logger).logInvalidStateTransitionError(any(), any())
@@ -925,7 +857,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
routeInfo,
- null
+ null,
)
verify(logger).logStateChange(any(), any(), any())
@@ -936,13 +868,13 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
routeInfo,
- null
+ null,
)
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
fakeExecutor.runAllReady()
@@ -959,13 +891,13 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
routeInfo,
- null
+ null,
)
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
fakeExecutor.runAllReady()
@@ -983,13 +915,13 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
- null
+ null,
)
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
fakeExecutor.runAllReady()
@@ -1007,13 +939,13 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
routeInfo,
- null
+ null,
)
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
fakeExecutor.runAllReady()
@@ -1051,7 +983,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
fakeExecutor.runAllReady()
@@ -1091,7 +1023,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
fakeExecutor.runAllReady()
@@ -1116,7 +1048,6 @@
context,
dumpManager,
logger,
- mediaTttFlags,
uiEventLogger,
)
underTest.start()
@@ -1144,7 +1075,6 @@
context,
dumpManager,
logger,
- mediaTttFlags,
uiEventLogger,
)
underTest.start()
@@ -1178,7 +1108,6 @@
context,
dumpManager,
logger,
- mediaTttFlags,
uiEventLogger,
)
underTest.start()
@@ -1211,7 +1140,6 @@
context,
dumpManager,
logger,
- mediaTttFlags,
uiEventLogger,
)
underTest.start()
@@ -1230,7 +1158,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
routeInfo,
- null
+ null,
)
// THEN the media coordinator unregisters the listener
@@ -1248,7 +1176,6 @@
context,
dumpManager,
logger,
- mediaTttFlags,
uiEventLogger,
)
underTest.start()
@@ -1549,7 +1476,7 @@
private fun ViewGroup.getUndoButton(): View = this.requireViewById(R.id.end_button)
private fun ChipStateSender.getExpectedStateText(
- otherDeviceName: String = OTHER_DEVICE_NAME,
+ otherDeviceName: String = OTHER_DEVICE_NAME
): String? {
return this.getChipTextString(context, otherDeviceName).loadText(context)
}
@@ -1560,7 +1487,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
routeInfo,
- null
+ null,
)
}
@@ -1570,7 +1497,7 @@
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
routeInfo,
- null
+ null,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
index 3bfde68..9096808 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
@@ -59,6 +59,7 @@
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
+import com.android.wm.shell.back.BackAnimation
import com.android.wm.shell.sysui.ShellInterface
import com.google.common.util.concurrent.MoreExecutors
import java.util.Optional
@@ -120,6 +121,7 @@
private lateinit var unfoldTransitionProgressForwarder:
Optional<UnfoldTransitionProgressForwarder>
@Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
+ @Mock private lateinit var backAnimation: Optional<BackAnimation>
@Before
fun setUp() {
@@ -289,6 +291,7 @@
dumpManager,
unfoldTransitionProgressForwarder,
broadcastDispatcher,
+ backAnimation,
)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
index 9639735..991f78a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
@@ -27,7 +27,6 @@
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.flags.FeatureFlagsClassic
-import com.android.systemui.flags.Flags
import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
import com.android.systemui.mediaprojection.SessionCreationSource
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
@@ -56,7 +55,6 @@
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
-import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -150,8 +148,6 @@
@Test
fun screenCaptureDisabledDialog_isShown_whenFunctionalityIsDisabled() {
- whenever(flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES))
- .thenReturn(true)
whenever(devicePolicyResolver.isScreenCaptureCompletelyDisabled(any<UserHandle>()))
.thenReturn(true)
@@ -170,48 +166,6 @@
}
@Test
- fun screenCapturePermissionDialog_isShown_correctly() {
- whenever(flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES))
- .thenReturn(false)
- whenever(devicePolicyResolver.isScreenCaptureCompletelyDisabled(any<UserHandle>()))
- .thenReturn(false)
- whenever(state.hasUserApprovedScreenRecording).thenReturn(false)
-
- val screenRecordSwitch = dialog.requireViewById<Switch>(R.id.screenrecord_switch)
- screenRecordSwitch.isChecked = true
-
- bgExecutor.runAllReady()
- mainExecutor.runAllReady()
-
- verify(mediaProjectionMetricsLogger)
- .notifyProjectionInitiated(
- anyInt(),
- eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER),
- )
- verify(factory, times(2)).create(any(SystemUIDialog.Delegate::class.java))
- }
-
- @Test
- fun noDialogsAreShown_forScreenRecord_whenApprovalIsAlreadyGiven() {
- whenever(flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES))
- .thenReturn(false)
- whenever(devicePolicyResolver.isScreenCaptureCompletelyDisabled(any<UserHandle>()))
- .thenReturn(false)
-
- val screenRecordSwitch = dialog.requireViewById<Switch>(R.id.screenrecord_switch)
- screenRecordSwitch.isChecked = true
-
- bgExecutor.runAllReady()
-
- verify(mediaProjectionMetricsLogger)
- .notifyProjectionInitiated(
- anyInt(),
- eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER),
- )
- verify(factory, never()).create()
- }
-
- @Test
fun startButton_isDisabled_beforeIssueTypeIsSelected() {
assertThat(dialog.getButton(Dialog.BUTTON_POSITIVE).isEnabled).isFalse()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
index 6b16e78..afff485 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
@@ -42,15 +42,11 @@
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.animation.DialogTransitionAnimator;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.flags.FakeFeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger;
import com.android.systemui.mediaprojection.SessionCreationSource;
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver;
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialogDelegate;
-import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -79,10 +75,6 @@
@Mock
private ScreenCaptureDevicePolicyResolver mDevicePolicyResolver;
@Mock
- private DialogTransitionAnimator mDialogTransitionAnimator;
- @Mock
- private ActivityStarter mActivityStarter;
- @Mock
private UserTracker mUserTracker;
@Mock
private MediaProjectionMetricsLogger mMediaProjectionMetricsLogger;
@@ -92,10 +84,6 @@
@Mock
private SystemUIDialog mScreenCaptureDisabledDialog;
@Mock
- private ScreenRecordDialogDelegate.Factory mScreenRecordDialogFactory;
- @Mock
- private ScreenRecordDialogDelegate mScreenRecordDialogDelegate;
- @Mock
private ScreenRecordPermissionDialogDelegate.Factory
mScreenRecordPermissionDialogDelegateFactory;
@Mock
@@ -103,7 +91,6 @@
@Mock
private SystemUIDialog mScreenRecordSystemUIDialog;
- private FakeFeatureFlags mFeatureFlags;
private RecordingController mController;
private static final int USER_ID = 10;
@@ -114,12 +101,8 @@
Context spiedContext = spy(mContext);
when(spiedContext.getUserId()).thenReturn(TEST_USER_ID);
- mFeatureFlags = new FakeFeatureFlags();
when(mScreenCaptureDisabledDialogDelegate.createSysUIDialog())
.thenReturn(mScreenCaptureDisabledDialog);
- when(mScreenRecordDialogFactory.create(any(), any()))
- .thenReturn(mScreenRecordDialogDelegate);
- when(mScreenRecordDialogDelegate.createDialog()).thenReturn(mScreenRecordSystemUIDialog);
when(mScreenRecordPermissionDialogDelegateFactory.create(any(), any(), anyInt(), any()))
.thenReturn(mScreenRecordPermissionDialogDelegate);
when(mScreenRecordPermissionDialogDelegate.createDialog())
@@ -127,13 +110,11 @@
mController = new RecordingController(
mMainExecutor,
mBroadcastDispatcher,
- mFeatureFlags,
() -> mDevicePolicyResolver,
mUserTracker,
new RecordingControllerLogger(logcatLogBuffer("RecordingControllerTest")),
mMediaProjectionMetricsLogger,
mScreenCaptureDisabledDialogDelegate,
- mScreenRecordDialogFactory,
mScreenRecordPermissionDialogDelegateFactory
);
mController.addCallback(mCallback);
@@ -236,46 +217,19 @@
}
@Test
- public void testPoliciesFlagDisabled_screenCapturingNotAllowed_returnsNullDevicePolicyDialog() {
- mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES, false);
+ public void testScreenCapturingNotAllowed_returnsDevicePolicyDialog() {
when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(true);
- Dialog dialog =
- mController.createScreenRecordDialog(
- mContext,
- mFeatureFlags,
- mDialogTransitionAnimator,
- mActivityStarter,
- /* onStartRecordingClicked= */ null);
-
- assertThat(dialog).isSameInstanceAs(mScreenRecordSystemUIDialog);
- assertThat(mScreenRecordPermissionDialogDelegate)
- .isInstanceOf(ScreenRecordPermissionDialogDelegate.class);
- }
-
- @Test
- public void testPoliciesFlagEnabled_screenCapturingNotAllowed_returnsDevicePolicyDialog() {
- mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES, true);
- when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(true);
-
- Dialog dialog = mController.createScreenRecordDialog(mContext, mFeatureFlags,
- mDialogTransitionAnimator, mActivityStarter, /* onStartRecordingClicked= */ null);
+ Dialog dialog = mController.createScreenRecordDialog(/* onStartRecordingClicked= */ null);
assertThat(dialog).isEqualTo(mScreenCaptureDisabledDialog);
}
@Test
- public void testPoliciesFlagEnabled_screenCapturingAllowed_returnsNullDevicePolicyDialog() {
- mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES, true);
+ public void testScreenCapturingAllowed_returnsNullDevicePolicyDialog() {
when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(false);
- Dialog dialog =
- mController.createScreenRecordDialog(
- mContext,
- mFeatureFlags,
- mDialogTransitionAnimator,
- mActivityStarter,
- /* onStartRecordingClicked= */ null);
+ Dialog dialog = mController.createScreenRecordDialog(/* onStartRecordingClicked= */ null);
assertThat(dialog).isSameInstanceAs(mScreenRecordSystemUIDialog);
assertThat(mScreenRecordPermissionDialogDelegate)
@@ -283,12 +237,10 @@
}
@Test
- public void testPoliciesFlagEnabled_screenCapturingAllowed_logsProjectionInitiated() {
- mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES, true);
+ public void testScreenCapturingAllowed_logsProjectionInitiated() {
when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(false);
- mController.createScreenRecordDialog(mContext, mFeatureFlags,
- mDialogTransitionAnimator, mActivityStarter, /* onStartRecordingClicked= */ null);
+ mController.createScreenRecordDialog(/* onStartRecordingClicked= */ null);
verify(mMediaProjectionMetricsLogger)
.notifyProjectionInitiated(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt
index ae976a0..9fb752a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.settings
import android.hardware.display.DisplayManager
-import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+import android.hardware.display.DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS
import android.hardware.display.DisplayManagerGlobal
import android.os.Handler
import android.testing.AndroidTestingRunner
@@ -59,14 +59,14 @@
DisplayManagerGlobal.getInstance(),
Display.DEFAULT_DISPLAY,
DisplayInfo(),
- DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS,
)
mSecondaryDisplay =
Display(
DisplayManagerGlobal.getInstance(),
Display.DEFAULT_DISPLAY + 1,
DisplayInfo(),
- DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS,
)
`when`(displayManager.displays).thenReturn(arrayOf(mDefaultDisplay, mSecondaryDisplay))
@@ -94,7 +94,12 @@
fun registerBrightnessCallback_registersDisplayListener() {
tracker.addBrightnessChangeCallback(TestCallback(), executor)
verify(displayManager)
- .registerDisplayListener(any(), any(), eq(EVENT_FLAG_DISPLAY_BRIGHTNESS))
+ .registerDisplayListener(
+ any(),
+ any(),
+ eq(0L),
+ eq(PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS),
+ )
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
deleted file mode 100644
index 0427011..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar.notification.row;
-
-import static android.app.AppOpsManager.OP_CAMERA;
-import static android.app.AppOpsManager.OP_RECORD_AUDIO;
-import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
-
-import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
-
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-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.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.INotificationManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.content.Intent;
-import android.content.pm.LauncherApps;
-import android.content.pm.PackageManager;
-import android.content.pm.ShortcutManager;
-import android.graphics.Color;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.service.notification.StatusBarNotification;
-import android.testing.TestableLooper;
-import android.util.ArraySet;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
-import com.android.systemui.kosmos.KosmosJavaAdapter;
-import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.power.domain.interactor.PowerInteractorFactory;
-import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository;
-import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
-import com.android.systemui.settings.UserContextProvider;
-import com.android.systemui.shade.ShadeController;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.NotificationPresenter;
-import com.android.systemui.statusbar.notification.AssistantFeedbackController;
-import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
-import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.kotlin.JavaAdapter;
-import com.android.systemui.wmshell.BubblesManager;
-
-import kotlinx.coroutines.test.TestScope;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.Optional;
-
-/**
- * Tests for {@link NotificationGutsManager}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-@TestableLooper.RunWithLooper
-public class NotificationGutsManagerTest extends SysuiTestCase {
- private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
-
- private NotificationChannel mTestNotificationChannel = new NotificationChannel(
- TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
-
- private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
- private final TestScope mTestScope = mKosmos.getTestScope();
- private final JavaAdapter mJavaAdapter = new JavaAdapter(mTestScope.getBackgroundScope());
- private final FakeExecutor mExecutor = mKosmos.getFakeExecutor();
- private final Handler mHandler = mKosmos.getFakeExecutorHandler();
- private NotificationTestHelper mHelper;
- private NotificationGutsManager mGutsManager;
-
- @Rule public MockitoRule mockito = MockitoJUnit.rule();
- @Mock private MetricsLogger mMetricsLogger;
- @Mock private OnUserInteractionCallback mOnUserInteractionCallback;
- @Mock private NotificationPresenter mPresenter;
- @Mock private NotificationActivityStarter mNotificationActivityStarter;
- @Mock private NotificationListContainer mNotificationListContainer;
- @Mock private OnSettingsClickListener mOnSettingsClickListener;
- @Mock private DeviceProvisionedController mDeviceProvisionedController;
- @Mock private AccessibilityManager mAccessibilityManager;
- @Mock private HighPriorityProvider mHighPriorityProvider;
- @Mock private INotificationManager mINotificationManager;
- @Mock private IStatusBarService mBarService;
- @Mock private LauncherApps mLauncherApps;
- @Mock private ShortcutManager mShortcutManager;
- @Mock private ChannelEditorDialogController mChannelEditorDialogController;
- @Mock private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
- @Mock private UserContextProvider mContextTracker;
- @Mock private BubblesManager mBubblesManager;
- @Mock private ShadeController mShadeController;
- @Mock private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
- @Mock private AssistantFeedbackController mAssistantFeedbackController;
- @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
- @Mock private StatusBarStateController mStatusBarStateController;
- @Mock private HeadsUpManager mHeadsUpManager;
- @Mock private ActivityStarter mActivityStarter;
-
- @Mock private UserManager mUserManager;
-
- private WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor;
-
- @Before
- public void setUp() {
- allowTestableLooperAsMainThread();
- mHelper = new NotificationTestHelper(mContext, mDependency);
- when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
-
- mWindowRootViewVisibilityInteractor = new WindowRootViewVisibilityInteractor(
- mTestScope.getBackgroundScope(),
- new WindowRootViewVisibilityRepository(mBarService, mExecutor),
- new FakeKeyguardRepository(),
- mHeadsUpManager,
- PowerInteractorFactory.create().getPowerInteractor(),
- mKosmos.getActiveNotificationsInteractor(),
- () -> mKosmos.getSceneInteractor()
- );
-
- mGutsManager = new NotificationGutsManager(
- mContext,
- mHandler,
- mHandler,
- mJavaAdapter,
- mAccessibilityManager,
- mHighPriorityProvider,
- mINotificationManager,
- mUserManager,
- mPeopleSpaceWidgetManager,
- mLauncherApps,
- mShortcutManager,
- mChannelEditorDialogController,
- mContextTracker,
- mAssistantFeedbackController,
- Optional.of(mBubblesManager),
- new UiEventLoggerFake(),
- mOnUserInteractionCallback,
- mShadeController,
- mWindowRootViewVisibilityInteractor,
- mNotificationLockscreenUserManager,
- mStatusBarStateController,
- mBarService,
- mDeviceProvisionedController,
- mMetricsLogger,
- mHeadsUpManager,
- mActivityStarter);
- mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
- mOnSettingsClickListener);
- mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
- mGutsManager.start();
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Test methods:
-
- @Test
- public void testOpenAndCloseGuts() {
- NotificationGuts guts = spy(new NotificationGuts(mContext));
- when(guts.post(any())).thenAnswer(invocation -> {
- mHandler.post(((Runnable) invocation.getArguments()[0]));
- return null;
- });
-
- // Test doesn't support animation since the guts view is not attached.
- doNothing().when(guts).openControls(
- anyInt(),
- anyInt(),
- anyBoolean(),
- any(Runnable.class));
-
- ExpandableNotificationRow realRow = createTestNotificationRow();
- NotificationMenuRowPlugin.MenuItem menuItem = createTestMenuItem(realRow);
-
- ExpandableNotificationRow row = spy(realRow);
- when(row.getWindowToken()).thenReturn(new Binder());
- when(row.getGuts()).thenReturn(guts);
-
- assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem));
- assertEquals(View.INVISIBLE, guts.getVisibility());
- mExecutor.runAllReady();
- verify(guts).openControls(
- anyInt(),
- anyInt(),
- anyBoolean(),
- any(Runnable.class));
- verify(mHeadsUpManager).setGutsShown(realRow.getEntry(), true);
-
- assertEquals(View.VISIBLE, guts.getVisibility());
- mGutsManager.closeAndSaveGuts(false, false, true, 0, 0, false);
-
- verify(guts).closeControls(anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyBoolean());
- verify(row, times(1)).setGutsView(any());
- mExecutor.runAllReady();
- verify(mHeadsUpManager).setGutsShown(realRow.getEntry(), false);
- }
-
- @Test
- public void testLockscreenShadeVisible_visible_gutsNotClosed() {
- // First, start out lockscreen or shade as not visible
- mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(false);
- mTestScope.getTestScheduler().runCurrent();
-
- NotificationGuts guts = mock(NotificationGuts.class);
- mGutsManager.setExposedGuts(guts);
-
- // WHEN the lockscreen or shade becomes visible
- mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true);
- mTestScope.getTestScheduler().runCurrent();
-
- // THEN the guts are not closed
- verify(guts, never()).removeCallbacks(any());
- verify(guts, never()).closeControls(
- anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyBoolean());
- }
-
- @Test
- public void testLockscreenShadeVisible_notVisible_gutsClosed() {
- // First, start out lockscreen or shade as visible
- mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true);
- mTestScope.getTestScheduler().runCurrent();
-
- NotificationGuts guts = mock(NotificationGuts.class);
- mGutsManager.setExposedGuts(guts);
-
- // WHEN the lockscreen or shade is no longer visible
- mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(false);
- mTestScope.getTestScheduler().runCurrent();
-
- // THEN the guts are closed
- verify(guts).removeCallbacks(any());
- verify(guts).closeControls(
- /* leavebehinds= */ eq(true),
- /* controls= */ eq(true),
- /* x= */ anyInt(),
- /* y= */ anyInt(),
- /* force= */ eq(true));
- }
-
- @Test
- public void testLockscreenShadeVisible_notVisible_listContainerReset() {
- // First, start out lockscreen or shade as visible
- mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true);
- mTestScope.getTestScheduler().runCurrent();
-
- // WHEN the lockscreen or shade is no longer visible
- mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(false);
- mTestScope.getTestScheduler().runCurrent();
-
- // THEN the list container is reset
- verify(mNotificationListContainer).resetExposedMenuView(anyBoolean(), anyBoolean());
- }
-
- @Test
- public void testChangeDensityOrFontScale() {
- NotificationGuts guts = spy(new NotificationGuts(mContext));
- when(guts.post(any())).thenAnswer(invocation -> {
- mHandler.post(((Runnable) invocation.getArguments()[0]));
- return null;
- });
-
- // Test doesn't support animation since the guts view is not attached.
- doNothing().when(guts).openControls(
- anyInt(),
- anyInt(),
- anyBoolean(),
- any(Runnable.class));
-
- ExpandableNotificationRow realRow = createTestNotificationRow();
- NotificationMenuRowPlugin.MenuItem menuItem = createTestMenuItem(realRow);
-
- ExpandableNotificationRow row = spy(realRow);
-
- when(row.getWindowToken()).thenReturn(new Binder());
- when(row.getGuts()).thenReturn(guts);
- doNothing().when(row).ensureGutsInflated();
-
- NotificationEntry realEntry = realRow.getEntry();
- NotificationEntry entry = spy(realEntry);
-
- when(entry.getRow()).thenReturn(row);
- when(entry.getGuts()).thenReturn(guts);
-
- assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem));
- mExecutor.runAllReady();
- verify(guts).openControls(
- anyInt(),
- anyInt(),
- anyBoolean(),
- any(Runnable.class));
-
- // called once by mGutsManager.bindGuts() in mGutsManager.openGuts()
- verify(row).setGutsView(any());
-
- row.onDensityOrFontScaleChanged();
- mGutsManager.onDensityOrFontScaleChanged(entry);
-
- mExecutor.runAllReady();
-
- mGutsManager.closeAndSaveGuts(false, false, false, 0, 0, false);
-
- verify(guts).closeControls(anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyBoolean());
-
- // called again by mGutsManager.bindGuts(), in mGutsManager.onDensityOrFontScaleChanged()
- verify(row, times(2)).setGutsView(any());
- }
-
- @Test
- public void testAppOpsSettingsIntent_camera() {
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(OP_CAMERA);
- mGutsManager.startAppOpsSettingsActivity("", 0, ops, null);
- ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
- verify(mNotificationActivityStarter, times(1))
- .startNotificationGutsIntent(captor.capture(), anyInt(), any());
- assertEquals(Intent.ACTION_MANAGE_APP_PERMISSIONS, captor.getValue().getAction());
- }
-
- @Test
- public void testAppOpsSettingsIntent_mic() {
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(OP_RECORD_AUDIO);
- mGutsManager.startAppOpsSettingsActivity("", 0, ops, null);
- ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
- verify(mNotificationActivityStarter, times(1))
- .startNotificationGutsIntent(captor.capture(), anyInt(), any());
- assertEquals(Intent.ACTION_MANAGE_APP_PERMISSIONS, captor.getValue().getAction());
- }
-
- @Test
- public void testAppOpsSettingsIntent_camera_mic() {
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(OP_CAMERA);
- ops.add(OP_RECORD_AUDIO);
- mGutsManager.startAppOpsSettingsActivity("", 0, ops, null);
- ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
- verify(mNotificationActivityStarter, times(1))
- .startNotificationGutsIntent(captor.capture(), anyInt(), any());
- assertEquals(Intent.ACTION_MANAGE_APP_PERMISSIONS, captor.getValue().getAction());
- }
-
- @Test
- public void testAppOpsSettingsIntent_overlay() {
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(OP_SYSTEM_ALERT_WINDOW);
- mGutsManager.startAppOpsSettingsActivity("", 0, ops, null);
- ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
- verify(mNotificationActivityStarter, times(1))
- .startNotificationGutsIntent(captor.capture(), anyInt(), any());
- assertEquals(Settings.ACTION_MANAGE_APP_OVERLAY_PERMISSION, captor.getValue().getAction());
- }
-
- @Test
- public void testAppOpsSettingsIntent_camera_mic_overlay() {
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(OP_CAMERA);
- ops.add(OP_RECORD_AUDIO);
- ops.add(OP_SYSTEM_ALERT_WINDOW);
- mGutsManager.startAppOpsSettingsActivity("", 0, ops, null);
- ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
- verify(mNotificationActivityStarter, times(1))
- .startNotificationGutsIntent(captor.capture(), anyInt(), any());
- assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.getValue().getAction());
- }
-
- @Test
- public void testAppOpsSettingsIntent_camera_overlay() {
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(OP_CAMERA);
- ops.add(OP_SYSTEM_ALERT_WINDOW);
- mGutsManager.startAppOpsSettingsActivity("", 0, ops, null);
- ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
- verify(mNotificationActivityStarter, times(1))
- .startNotificationGutsIntent(captor.capture(), anyInt(), any());
- assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.getValue().getAction());
- }
-
- @Test
- public void testAppOpsSettingsIntent_mic_overlay() {
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(OP_RECORD_AUDIO);
- ops.add(OP_SYSTEM_ALERT_WINDOW);
- mGutsManager.startAppOpsSettingsActivity("", 0, ops, null);
- ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
- verify(mNotificationActivityStarter, times(1))
- .startNotificationGutsIntent(captor.capture(), anyInt(), any());
- assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.getValue().getAction());
- }
-
- @Test
- public void testInitializeNotificationInfoView_highPriority() throws Exception {
- NotificationInfo notificationInfoView = mock(NotificationInfo.class);
- ExpandableNotificationRow row = spy(mHelper.createRow());
- final NotificationEntry entry = row.getEntry();
- modifyRanking(entry)
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .setImportance(IMPORTANCE_HIGH)
- .build();
-
- when(row.getIsNonblockable()).thenReturn(false);
- when(mHighPriorityProvider.isHighPriority(entry)).thenReturn(true);
- StatusBarNotification statusBarNotification = entry.getSbn();
- mGutsManager.initializeNotificationInfo(row, notificationInfoView);
-
- verify(notificationInfoView).bindNotification(
- any(PackageManager.class),
- any(INotificationManager.class),
- eq(mOnUserInteractionCallback),
- eq(mChannelEditorDialogController),
- eq(statusBarNotification.getPackageName()),
- any(NotificationChannel.class),
- eq(entry),
- any(NotificationInfo.OnSettingsClickListener.class),
- any(NotificationInfo.OnAppSettingsClickListener.class),
- any(UiEventLogger.class),
- eq(false),
- eq(false),
- eq(true), /* wasShownHighPriority */
- eq(mAssistantFeedbackController),
- any(MetricsLogger.class));
- }
-
- @Test
- public void testInitializeNotificationInfoView_PassesAlongProvisionedState() throws Exception {
- NotificationInfo notificationInfoView = mock(NotificationInfo.class);
- ExpandableNotificationRow row = spy(mHelper.createRow());
- modifyRanking(row.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
- when(row.getIsNonblockable()).thenReturn(false);
- StatusBarNotification statusBarNotification = row.getEntry().getSbn();
- NotificationEntry entry = row.getEntry();
-
- when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
-
- mGutsManager.initializeNotificationInfo(row, notificationInfoView);
-
- verify(notificationInfoView).bindNotification(
- any(PackageManager.class),
- any(INotificationManager.class),
- eq(mOnUserInteractionCallback),
- eq(mChannelEditorDialogController),
- eq(statusBarNotification.getPackageName()),
- any(NotificationChannel.class),
- eq(entry),
- any(NotificationInfo.OnSettingsClickListener.class),
- any(NotificationInfo.OnAppSettingsClickListener.class),
- any(UiEventLogger.class),
- eq(true),
- eq(false),
- eq(false), /* wasShownHighPriority */
- eq(mAssistantFeedbackController),
- any(MetricsLogger.class));
- }
-
- @Test
- public void testInitializeNotificationInfoView_withInitialAction() throws Exception {
- NotificationInfo notificationInfoView = mock(NotificationInfo.class);
- ExpandableNotificationRow row = spy(mHelper.createRow());
- modifyRanking(row.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
- when(row.getIsNonblockable()).thenReturn(false);
- StatusBarNotification statusBarNotification = row.getEntry().getSbn();
- NotificationEntry entry = row.getEntry();
-
- mGutsManager.initializeNotificationInfo(row, notificationInfoView);
-
- verify(notificationInfoView).bindNotification(
- any(PackageManager.class),
- any(INotificationManager.class),
- eq(mOnUserInteractionCallback),
- eq(mChannelEditorDialogController),
- eq(statusBarNotification.getPackageName()),
- any(NotificationChannel.class),
- eq(entry),
- any(NotificationInfo.OnSettingsClickListener.class),
- any(NotificationInfo.OnAppSettingsClickListener.class),
- any(UiEventLogger.class),
- eq(false),
- eq(false),
- eq(false), /* wasShownHighPriority */
- eq(mAssistantFeedbackController),
- any(MetricsLogger.class));
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Utility methods:
-
- private ExpandableNotificationRow createTestNotificationRow() {
- Notification.Builder nb = new Notification.Builder(mContext,
- mTestNotificationChannel.getId())
- .setContentTitle("foo")
- .setColorized(true).setColor(Color.RED)
- .setFlag(Notification.FLAG_CAN_COLORIZE, true)
- .setSmallIcon(android.R.drawable.sym_def_app_icon);
-
- try {
- ExpandableNotificationRow row = mHelper.createRow(nb.build());
- modifyRanking(row.getEntry())
- .setChannel(mTestNotificationChannel)
- .build();
- return row;
- } catch (Exception e) {
- fail();
- return null;
- }
- }
-
- private NotificationMenuRowPlugin.MenuItem createTestMenuItem(ExpandableNotificationRow row) {
- NotificationMenuRowPlugin menuRow =
- new NotificationMenuRow(mContext, mPeopleNotificationIdentifier);
- menuRow.createMenu(row, row.getEntry().getSbn());
-
- NotificationMenuRowPlugin.MenuItem menuItem = menuRow.getLongpressMenuItem(mContext);
- assertNotNull(menuItem);
- return menuItem;
- }
-}
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 7d019bf..b142fc2 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
@@ -510,7 +510,7 @@
}
mShadeController.setNotificationPresenter(mNotificationPresenter);
- when(mOperatorNameViewControllerFactory.create(any()))
+ when(mOperatorNameViewControllerFactory.create(any(), any()))
.thenReturn(mOperatorNameViewController);
when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
when(mUserTracker.getUserHandle()).thenReturn(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index d01c1ca..4b648a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -1184,9 +1184,9 @@
mKeyguardStateController = mock(KeyguardStateController.class);
mOperatorNameViewController = mock(OperatorNameViewController.class);
mOperatorNameViewControllerFactory = mock(OperatorNameViewController.Factory.class);
- when(mOperatorNameViewControllerFactory.create(any()))
+ when(mOperatorNameViewControllerFactory.create(any(), any()))
.thenReturn(mOperatorNameViewController);
- when(mIconManagerFactory.create(any(), any())).thenReturn(mIconManager);
+ when(mIconManagerFactory.create(any(), any(), any())).thenReturn(mIconManager);
mSecureSettings = mock(SecureSettings.class);
mShadeExpansionStateManager = new ShadeExpansionStateManager();
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeScreenBrightnessRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeScreenBrightnessRepository.kt
index ad5242e..4546b99 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeScreenBrightnessRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeScreenBrightnessRepository.kt
@@ -26,7 +26,7 @@
class FakeScreenBrightnessRepository(
initialBrightnessInfo: BrightnessInfo =
- BrightnessInfo(0f, 0f, 1f, HIGH_BRIGHTNESS_MODE_OFF, 1f, BRIGHTNESS_MAX_REASON_NONE)
+ BrightnessInfo(0f, 0f, 1f, HIGH_BRIGHTNESS_MODE_OFF, 1f, BRIGHTNESS_MAX_REASON_NONE),
) : ScreenBrightnessRepository {
private val brightnessInfo = MutableStateFlow(initialBrightnessInfo)
@@ -36,6 +36,8 @@
override val linearBrightness = brightnessInfo.map { LinearBrightness(it.brightness) }
override val minLinearBrightness = brightnessInfo.map { LinearBrightness(it.brightnessMinimum) }
override val maxLinearBrightness = brightnessInfo.map { LinearBrightness(it.brightnessMaximum) }
+ override val isBrightnessOverriddenByWindow =
+ MutableStateFlow(initialBrightnessInfo.isBrightnessOverrideByWindow).asStateFlow()
override suspend fun getMinMaxLinearBrightness(): Pair<LinearBrightness, LinearBrightness> {
return minMaxLinearBrightness()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
index 52cdbed..2198e04 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
@@ -21,6 +21,7 @@
import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
+import com.android.systemui.kosmos.brightnessWarningToast
val Kosmos.brightnessSliderViewModelFactory: BrightnessSliderViewModel.Factory by
Kosmos.Fixture {
@@ -32,6 +33,7 @@
hapticsViewModelFactory = sliderHapticsViewModelFactory,
brightnessMirrorShowingInteractor = brightnessMirrorShowingInteractor,
supportsMirroring = allowsMirroring,
+ brightnessWarningToast = brightnessWarningToast,
)
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index c41493e..8022e6e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -31,8 +31,11 @@
import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
+import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutCustomizationInteractor
import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperCategoriesInteractor
import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperStateInteractor
+import com.android.systemui.keyboard.shortcut.ui.ShortcutCustomizationDialogStarter
+import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutCustomizationViewModel
import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutHelperViewModel
import com.android.systemui.keyguard.data.repository.fakeCommandQueue
import com.android.systemui.kosmos.Kosmos
@@ -42,6 +45,7 @@
import com.android.systemui.model.sysUiState
import com.android.systemui.settings.displayTracker
import com.android.systemui.settings.userTracker
+import com.android.systemui.statusbar.phone.systemUIDialogFactory
var Kosmos.shortcutHelperAppCategoriesShortcutsSource: KeyboardShortcutGroupsSource by
Kosmos.Fixture { AppCategoriesShortcutsSource(windowManager, testDispatcher) }
@@ -121,3 +125,26 @@
shortcutHelperCategoriesInteractor,
)
}
+
+val Kosmos.shortcutCustomizationDialogStarterFactory by
+ Kosmos.Fixture {
+ object : ShortcutCustomizationDialogStarter.Factory {
+ override fun create(): ShortcutCustomizationDialogStarter {
+ return ShortcutCustomizationDialogStarter(
+ shortcutCustomizationViewModelFactory,
+ systemUIDialogFactory,
+ )
+ }
+ }
+ }
+
+val Kosmos.shortcutCustomizationInteractor by Kosmos.Fixture { ShortcutCustomizationInteractor() }
+
+val Kosmos.shortcutCustomizationViewModelFactory by
+ Kosmos.Fixture {
+ object : ShortcutCustomizationViewModel.Factory {
+ override fun create(): ShortcutCustomizationViewModel {
+ return ShortcutCustomizationViewModel(shortcutCustomizationInteractor)
+ }
+ }
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
index 72cb1df..f43841b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
@@ -3,6 +3,9 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.settings.brightness.ui.BrightnessWarningToast
+
+import com.android.systemui.util.mockito.mock
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.test.StandardTestDispatcher
@@ -38,6 +41,9 @@
testScope.backgroundScope.coroutineContext
}
var Kosmos.mainCoroutineContext: CoroutineContext by Fixture { testScope.coroutineContext }
+var Kosmos.brightnessWarningToast: BrightnessWarningToast by Kosmos.Fixture {
+ mock<BrightnessWarningToast>()
+}
/**
* Run this test body with a [Kosmos] as receiver, and using the [testScope] currently installed in
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryKosmos.kt
index 7e7eea2..f49e377 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryKosmos.kt
@@ -16,7 +16,48 @@
package com.android.systemui.media.controls.domain.pipeline
+import android.content.applicationContext
+import android.os.Bundle
+import android.os.Handler
+import android.os.looper
+import androidx.media3.session.CommandButton
+import androidx.media3.session.MediaController
+import androidx.media3.session.SessionToken
+import com.android.systemui.Flags
+import com.android.systemui.graphics.imageLoader
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.media.controls.shared.mediaLogger
+import com.android.systemui.media.controls.util.fakeMediaControllerFactory
+import com.android.systemui.media.controls.util.fakeSessionTokenFactory
+import com.google.common.collect.ImmutableList
import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
-var Kosmos.media3ActionFactory: Media3ActionFactory by Kosmos.Fixture { mock {} }
+/**
+ * Set up fake [Media3ActionFactory]. Note that tests using this fake will need to be
+ * annotated @RunWithLooper
+ */
+var Kosmos.media3ActionFactory: Media3ActionFactory by
+ Kosmos.Fixture {
+ if (Flags.mediaControlsButtonMedia3()) {
+ val customLayout = ImmutableList.of<CommandButton>()
+ val media3Controller =
+ mock<MediaController>().also {
+ whenever(it.customLayout).thenReturn(customLayout)
+ whenever(it.sessionExtras).thenReturn(Bundle())
+ }
+ fakeMediaControllerFactory.setMedia3Controller(media3Controller)
+ fakeSessionTokenFactory.setMedia3SessionToken(mock<SessionToken>())
+ }
+ Media3ActionFactory(
+ context = applicationContext,
+ imageLoader = imageLoader,
+ controllerFactory = fakeMediaControllerFactory,
+ tokenFactory = fakeSessionTokenFactory,
+ logger = mediaLogger,
+ looper = looper,
+ handler = Handler(looper),
+ bgScope = testScope,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
index bda3192..4ed49123 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
@@ -29,6 +29,7 @@
import com.android.systemui.qs.footerActionsViewModelFactory
import com.android.systemui.qs.panels.domain.interactor.tileSquishinessInteractor
import com.android.systemui.qs.panels.ui.viewmodel.inFirstPageViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.mediaInRowInLandscapeViewModelFactory
import com.android.systemui.qs.ui.viewmodel.quickSettingsContainerViewModelFactory
import com.android.systemui.shade.largeScreenHeaderHelper
import com.android.systemui.shade.transition.largeScreenShadeInterpolator
@@ -57,6 +58,7 @@
largeScreenHeaderHelper,
tileSquishinessInteractor,
inFirstPageViewModel,
+ mediaInRowInLandscapeViewModelFactory,
qqsMediaHost,
qsMediaHost,
usingMediaInComposeFragment,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModelKosmos.kt
index 7613ea31..57aa20a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModelKosmos.kt
@@ -25,7 +25,7 @@
override fun create(): InfiniteGridViewModel {
return InfiniteGridViewModel(
dynamicIconTilesViewModelFactory,
- qsColumnsViewModel,
+ qsColumnsViewModelFactory,
tileSquishinessViewModel,
qsResetDialogDelegateKosmos,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelKosmos.kt
new file mode 100644
index 0000000..d1b613f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelKosmos.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs.panels.ui.viewmodel
+
+import android.content.res.Configuration
+import android.content.res.mainResources
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.media.controls.ui.controller.mediaHostStatesManager
+import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
+import com.android.systemui.shade.data.repository.shadeRepository
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
+
+val Kosmos.mediaInRowInLandscapeViewModelFactory by
+ Kosmos.Fixture {
+ object : MediaInRowInLandscapeViewModel.Factory {
+ override fun create(inLocation: Int): MediaInRowInLandscapeViewModel {
+ return MediaInRowInLandscapeViewModel(
+ mainResources,
+ configurationInteractor,
+ shadeModeInteractor,
+ mediaHostStatesManager,
+ usingMediaInComposeFragment,
+ inLocation,
+ )
+ }
+ }
+ }
+
+fun Kosmos.setConfigurationForMediaInRow(mediaInRow: Boolean) {
+ shadeRepository.setShadeLayoutWide(!mediaInRow) // media in row only in non wide
+ val config =
+ Configuration(mainResources.configuration).apply {
+ orientation =
+ if (mediaInRow) {
+ Configuration.ORIENTATION_LANDSCAPE
+ } else {
+ Configuration.ORIENTATION_PORTRAIT
+ }
+ screenLayout = Configuration.SCREENLAYOUT_LONG_YES
+ }
+ mainResources.configuration.updateFrom(config)
+ fakeConfigurationRepository.onConfigurationChange(config)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
index 5c8ca83..0e5edb7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
@@ -23,7 +23,7 @@
Kosmos.Fixture {
PaginatedGridViewModel(
iconTilesViewModel,
- qsColumnsViewModel,
+ qsColumnsViewModelFactory,
paginatedGridInteractor,
inFirstPageViewModel,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelKosmos.kt
index 16b2f54..d63b1b0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModelKosmos.kt
@@ -19,4 +19,15 @@
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.panels.domain.interactor.qsColumnsInteractor
-val Kosmos.qsColumnsViewModel by Kosmos.Fixture { QSColumnsSizeViewModelImpl(qsColumnsInteractor) }
+val Kosmos.qsColumnsViewModelFactory by
+ Kosmos.Fixture {
+ object : QSColumnsViewModel.Factory {
+ override fun create(mediaLocation: Int?): QSColumnsViewModel {
+ return QSColumnsViewModel(
+ qsColumnsInteractor,
+ mediaInRowInLandscapeViewModelFactory,
+ mediaLocation,
+ )
+ }
+ }
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
index 20be5c6..81beb20 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
@@ -27,8 +27,9 @@
override fun create(): QuickQuickSettingsViewModel {
return QuickQuickSettingsViewModel(
currentTilesInteractor,
- qsColumnsViewModel,
+ qsColumnsViewModelFactory,
quickQuickSettingsRowInteractor,
+ mediaInRowInLandscapeViewModelFactory,
tileSquishinessViewModel,
iconTilesViewModel,
tileHapticsViewModelFactoryProvider,
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/notes/NotesTileKosmos.kt
similarity index 67%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/notes/NotesTileKosmos.kt
index e21bf8f..75c98cb 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/notes/NotesTileKosmos.kt
@@ -14,6 +14,11 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package com.android.systemui.qs.tiles.impl.notes
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.notetask.NoteTaskModule
+import com.android.systemui.qs.qsEventLogger
+
+val Kosmos.qsNotesTileConfig by
+ Kosmos.Fixture { NoteTaskModule.provideNotesTileConfig(qsEventLogger) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
index 4228c3c..7e6a727 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
@@ -32,7 +32,6 @@
import com.android.systemui.keyguard.dismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.windowManagerLockscreenVisibilityInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.testScope
@@ -78,7 +77,6 @@
uiEventLogger = uiEventLogger,
sceneBackInteractor = sceneBackInteractor,
shadeSessionStorage = shadeSessionStorage,
- windowMgrLockscreenVisInteractor = windowManagerLockscreenVisibilityInteractor,
keyguardEnabledInteractor = keyguardEnabledInteractor,
dismissCallbackRegistry = dismissCallbackRegistry,
statusBarStateController = sysuiStatusBarStateController,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/BrightnessSliderControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/BrightnessSliderControllerKosmos.kt
index 88063c9..aac122c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/settings/BrightnessSliderControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/BrightnessSliderControllerKosmos.kt
@@ -21,6 +21,7 @@
import com.android.systemui.haptics.msdl.msdlPlayer
import com.android.systemui.haptics.vibratorHelper
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.brightnessWarningToast
import com.android.systemui.plugins.activityStarter
import com.android.systemui.settings.brightness.BrightnessSliderController
import com.android.systemui.util.time.systemClock
@@ -35,5 +36,6 @@
msdlPlayer,
systemClock,
activityStarter,
+ brightnessWarningToast,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeOverlayContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeOverlayContentViewModelKosmos.kt
index 718347f..20e4523 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeOverlayContentViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeOverlayContentViewModelKosmos.kt
@@ -21,6 +21,7 @@
import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModelFactory
val Kosmos.notificationsShadeOverlayContentViewModel:
@@ -30,5 +31,6 @@
notificationsPlaceholderViewModelFactory = notificationsPlaceholderViewModelFactory,
sceneInteractor = sceneInteractor,
shadeInteractor = shadeInteractor,
+ activeNotificationsInteractor = activeNotificationsInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
index ad2654a..45aab86 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
@@ -29,6 +29,7 @@
import com.android.systemui.shade.mockNotificationShadeWindowViewController
import com.android.systemui.shade.mockShadeSurface
import com.android.systemui.statusbar.data.repository.fakeStatusBarModePerDisplayRepository
+import com.android.systemui.statusbar.data.repository.lightBarControllerStore
import com.android.systemui.statusbar.data.repository.privacyDotWindowControllerStore
import com.android.systemui.statusbar.data.repository.statusBarModeRepository
import com.android.systemui.statusbar.mockNotificationRemoteInputManager
@@ -79,5 +80,6 @@
statusBarWindowControllerStore,
statusBarInitializerStore,
privacyDotWindowControllerStore,
+ lightBarControllerStore,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStoreKosmos.kt
new file mode 100644
index 0000000..34a8281
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStoreKosmos.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.data.repository
+
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.display.data.repository.displayWindowPropertiesRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import org.mockito.kotlin.mock
+
+val Kosmos.multiDisplayDarkIconDispatcherStore by
+ Kosmos.Fixture {
+ MultiDisplayDarkIconDispatcherStore(
+ backgroundApplicationScope = applicationCoroutineScope,
+ displayRepository = displayRepository,
+ factory = { _, _ -> mock() },
+ displayWindowPropertiesRepository = displayWindowPropertiesRepository,
+ )
+ }
+
+val Kosmos.fakeDarkIconDispatcherStore by Kosmos.Fixture { FakeDarkIconDispatcherStore() }
+
+var Kosmos.darkIconDispatcherStore by Kosmos.Fixture { fakeDarkIconDispatcherStore }
+
+val Kosmos.fakeSysUiDarkIconDispatcherStore by Kosmos.Fixture { FakeSysUiDarkIconDispatcherStore() }
+
+var Kosmos.sysUiDarkIconDispatcherStore by Kosmos.Fixture { fakeSysUiDarkIconDispatcherStore }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeDarkIconDispatcherStore.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeDarkIconDispatcherStore.kt
new file mode 100644
index 0000000..871b277
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeDarkIconDispatcherStore.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.data.repository
+
+import android.view.Display
+import com.android.systemui.plugins.DarkIconDispatcher
+import org.mockito.kotlin.mock
+
+class FakeDarkIconDispatcherStore : DarkIconDispatcherStore {
+
+ private val perDisplayMocks = mutableMapOf<Int, DarkIconDispatcher>()
+
+ override val defaultDisplay: DarkIconDispatcher
+ get() = forDisplay(Display.DEFAULT_DISPLAY)
+
+ override fun forDisplay(displayId: Int): DarkIconDispatcher {
+ return perDisplayMocks.computeIfAbsent(displayId) { mock() }
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeLightBarControllerStore.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeLightBarControllerStore.kt
new file mode 100644
index 0000000..2823246
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeLightBarControllerStore.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.data.repository
+
+import android.view.Display
+import com.android.systemui.statusbar.phone.LightBarController
+import org.mockito.kotlin.mock
+
+class FakeLightBarControllerStore : LightBarControllerStore {
+
+ val perDisplayMocks = mutableMapOf<Int, LightBarController>()
+
+ override val defaultDisplay: LightBarController
+ get() = forDisplay(Display.DEFAULT_DISPLAY)
+
+ override fun forDisplay(displayId: Int): LightBarController {
+ return perDisplayMocks.computeIfAbsent(displayId) { mock() }
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeSysUiDarkIconDispatcherStore.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeSysUiDarkIconDispatcherStore.kt
new file mode 100644
index 0000000..4ee323a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/FakeSysUiDarkIconDispatcherStore.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.data.repository
+
+import android.view.Display
+import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
+import org.mockito.kotlin.mock
+
+class FakeSysUiDarkIconDispatcherStore : SysuiDarkIconDispatcherStore {
+
+ private val perDisplayMocks = mutableMapOf<Int, SysuiDarkIconDispatcher>()
+
+ override val defaultDisplay: SysuiDarkIconDispatcher
+ get() = forDisplay(Display.DEFAULT_DISPLAY)
+
+ override fun forDisplay(displayId: Int): SysuiDarkIconDispatcher {
+ return perDisplayMocks.computeIfAbsent(displayId) { mock() }
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreKosmos.kt
index 5f33732..13fa3fe 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreKosmos.kt
@@ -27,8 +27,13 @@
LightBarControllerStoreImpl(
backgroundApplicationScope = applicationCoroutineScope,
displayRepository = displayRepository,
- factory = { _, _, _ -> mock() },
+ factory = { _, _, _, _ -> mock() },
displayScopeRepository = displayScopeRepository,
statusBarModeRepositoryStore = statusBarModeRepository,
+ darkIconDispatcherStore = darkIconDispatcherStore,
)
}
+
+val Kosmos.fakeLightBarControllerStore by Kosmos.Fixture { FakeLightBarControllerStore() }
+
+var Kosmos.lightBarControllerStore by Kosmos.Fixture { fakeLightBarControllerStore }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/data/repository/FakeDarkIconRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/data/repository/FakeDarkIconRepository.kt
index 282e2e8..cb092ce 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/data/repository/FakeDarkIconRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/data/repository/FakeDarkIconRepository.kt
@@ -24,7 +24,10 @@
@SysUISingleton
class FakeDarkIconRepository @Inject constructor() : DarkIconRepository {
- override val darkState = MutableStateFlow(DarkChange.EMPTY)
+ private val perDisplayStates = mutableMapOf<Int, MutableStateFlow<DarkChange>>()
+
+ override fun darkState(displayId: Int) =
+ perDisplayStates.computeIfAbsent(displayId) { MutableStateFlow(DarkChange.EMPTY) }
}
@Module
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
index ed335f9..1808a5f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
@@ -29,6 +29,7 @@
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.yield
@@ -67,6 +68,10 @@
)
override val selectedUserInfo: Flow<UserInfo> = selectedUser.map { it.userInfo }
+ private val _isSecondaryUserLogoutEnabled = MutableStateFlow<Boolean>(false)
+ override val isSecondaryUserLogoutEnabled: StateFlow<Boolean> =
+ _isSecondaryUserLogoutEnabled.asStateFlow()
+
override var mainUserId: Int = MAIN_USER_ID
override var lastSelectedNonGuestUserId: Int = mainUserId
@@ -107,6 +112,17 @@
return _userSwitcherSettings.value.isUserSwitcherEnabled
}
+ fun setSecondaryUserLogoutEnabled(logoutEnabled: Boolean) {
+ _isSecondaryUserLogoutEnabled.value = logoutEnabled
+ }
+
+ var logOutSecondaryUserCallCount: Int = 0
+ private set
+
+ override suspend fun logOutSecondaryUser() {
+ logOutSecondaryUserCallCount++
+ }
+
fun setUserInfos(infos: List<UserInfo>) {
_userInfos.value = infos
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorKosmos.kt
new file mode 100644
index 0000000..d06e744
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.user.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.user.data.repository.userRepository
+
+val Kosmos.userLogoutInteractor by
+ Kosmos.Fixture {
+ UserLogoutInteractor(
+ userRepository = userRepository,
+ applicationScope = applicationCoroutineScope,
+ )
+ }
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 57b58d8..3a0f8c0 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
@@ -306,7 +306,7 @@
}
private fun isOnLargeScreen(): Boolean {
- return context.resources.configuration.smallestScreenWidthDp >
+ return context.applicationContext.resources.configuration.smallestScreenWidthDp >
INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP
}
diff --git a/packages/Vcn/framework-b/Android.bp b/packages/Vcn/framework-b/Android.bp
new file mode 100644
index 0000000..be64bb1
--- /dev/null
+++ b/packages/Vcn/framework-b/Android.bp
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ default_team: "trendy_team_enigma",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_defaults {
+ name: "framework-connectivity-b-defaults",
+ sdk_version: "module_current",
+ min_sdk_version: "35", // TODO: Make it Android 25Q2 when this is included in mainline
+ defaults: ["framework-module-defaults"], // This is a boot jar
+
+ srcs: [
+ "src/**/*.java",
+ ],
+}
+
+java_sdk_library {
+ name: "framework-connectivity-b",
+ defaults: [
+ "framework-connectivity-b-defaults",
+ ],
+
+ permitted_packages: [
+ "android.net.vcn",
+ ],
+
+ // TODO: b/375213246 Expose this library to Tethering module
+}
diff --git a/packages/Vcn/framework-b/api/current.txt b/packages/Vcn/framework-b/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Vcn/framework-b/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Vcn/framework-b/api/module-lib-current.txt b/packages/Vcn/framework-b/api/module-lib-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Vcn/framework-b/api/module-lib-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Vcn/framework-b/api/module-lib-removed.txt b/packages/Vcn/framework-b/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Vcn/framework-b/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Vcn/framework-b/api/removed.txt b/packages/Vcn/framework-b/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Vcn/framework-b/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Vcn/framework-b/api/system-current.txt b/packages/Vcn/framework-b/api/system-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Vcn/framework-b/api/system-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Vcn/framework-b/api/system-removed.txt b/packages/Vcn/framework-b/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Vcn/framework-b/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/Vcn/framework-b/src/android/net/vcn/Placeholder.java
similarity index 76%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/Vcn/framework-b/src/android/net/vcn/Placeholder.java
index e21bf8f..fb5e153 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/Vcn/framework-b/src/android/net/vcn/Placeholder.java
@@ -14,6 +14,12 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package android.net.vcn;
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+/**
+ * Placeholder class so new framework-vcn isn't empty
+ *
+ * @hide
+ */
+// This class will be removed once source code is migrated
+public class Placeholder {}
diff --git a/packages/Vcn/service-b/Android.bp b/packages/Vcn/service-b/Android.bp
new file mode 100644
index 0000000..a462297
--- /dev/null
+++ b/packages/Vcn/service-b/Android.bp
@@ -0,0 +1,36 @@
+//
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ default_team: "trendy_team_enigma",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+ name: "service-connectivity-b-pre-jarjar",
+ sdk_version: "system_server_current",
+ min_sdk_version: "35", // TODO: Make it Android 25Q2 when this is included in mainline
+ defaults: ["framework-system-server-module-defaults"], // This is a system server jar
+
+ srcs: [
+ "src/**/*.java",
+ ],
+
+ // TODO: b/375213246 Expose this library to Tethering module
+ visibility: [
+ "//frameworks/base/services",
+ ],
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl b/packages/Vcn/service-b/src/com/android/server/vcn/Placeholder.java
similarity index 75%
copy from libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
copy to packages/Vcn/service-b/src/com/android/server/vcn/Placeholder.java
index e21bf8f..e799145 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedRecentTaskInfo.aidl
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/Placeholder.java
@@ -14,6 +14,12 @@
* limitations under the License.
*/
-package com.android.wm.shell.shared;
+package com.android.server.vcn;
-parcelable GroupedRecentTaskInfo;
\ No newline at end of file
+/**
+ * Placeholder class so new service-vcn isn't empty
+ *
+ * @hide
+ */
+// This class will be removed once source code is migrated
+public class Placeholder {}
diff --git a/packages/overlays/Android.bp b/packages/overlays/Android.bp
index 5075f63..44abb9f 100644
--- a/packages/overlays/Android.bp
+++ b/packages/overlays/Android.bp
@@ -21,6 +21,7 @@
phony {
name: "frameworks-base-overlays",
+ product_specific: true,
required: [
"DisplayCutoutEmulationCornerOverlay",
"DisplayCutoutEmulationDoubleOverlay",
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index b3f78ab..0c2ce8d 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -279,6 +279,15 @@
shared_libs: [
"liblog",
],
+ visibility: ["//visibility:private"],
+}
+
+cc_library_host_shared {
+ name: "libravenwood_initializer",
+ defaults: ["ravenwood_jni_defaults"],
+ srcs: [
+ "runtime-jni/ravenwood_initializer.cpp",
+ ],
}
// We need this as a separate library because we need to overload the
@@ -301,7 +310,6 @@
"libutils",
"libcutils",
],
- visibility: ["//frameworks/base"],
}
// For collecting the *stats.csv files in a known directory under out/host/linux-x86/testcases/.
@@ -368,6 +376,7 @@
":ravenwood-empty-res",
":framework-platform-compat-config",
":services-platform-compat-config",
+ "texts/ravenwood-build.prop",
],
device_first_srcs: [
":apex_icu.dat",
@@ -659,6 +668,7 @@
],
jni_libs: [
// Libraries has to be loaded in the following order
+ "libravenwood_initializer",
"libravenwood_sysprop",
"libravenwood_runtime",
"libandroid_runtime",
diff --git a/ravenwood/Framework.bp b/ravenwood/Framework.bp
index d207738..99fc31b 100644
--- a/ravenwood/Framework.bp
+++ b/ravenwood/Framework.bp
@@ -214,7 +214,8 @@
java_genrule {
name: "services.core.ravenwood",
- defaults: ["ravenwood-internal-only-visibility-genrule"],
+ // This is used by unit tests too (so tests will be able to access HSG-processed implementation)
+ // so it's visible to all.
cmd: "cp $(in) $(out)",
srcs: [
":services.core.ravenwood-base{ravenwood.jar}",
diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING
index a1243e3..607592b 100644
--- a/ravenwood/TEST_MAPPING
+++ b/ravenwood/TEST_MAPPING
@@ -117,7 +117,11 @@
"host": true
},
{
- "name": "FrameworksServicesTestsRavenwood",
+ "name": "FrameworksServicesTestsRavenwood_Compat",
+ "host": true
+ },
+ {
+ "name": "FrameworksServicesTestsRavenwood_Uri",
"host": true
},
{
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java
index d29b93c..a208d6d 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java
@@ -40,7 +40,7 @@
* See frameworks/base/core/jni/platform/host/HostRuntime.cpp
*/
private static final Class<?>[] sLibandroidClasses = {
- android.util.Log.class,
+// android.util.Log.class, // Not using native log: b/377377826
android.os.Parcel.class,
android.os.Binder.class,
android.os.SystemProperties.class,
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index 28c262d..678a97b 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -22,7 +22,6 @@
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERSION_JAVA_SYSPROP;
-import static com.android.ravenwood.common.RavenwoodCommonUtils.getRavenwoodRuntimePath;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
@@ -31,9 +30,12 @@
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.AppCompatCallbacks;
import android.app.Instrumentation;
import android.app.ResourcesManager;
import android.app.UiAutomation;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.os.Binder;
import android.os.Build;
@@ -42,6 +44,7 @@
import android.os.Looper;
import android.os.Process_ravenwood;
import android.os.ServiceManager;
+import android.os.ServiceManager.ServiceNotFoundException;
import android.os.SystemProperties;
import android.provider.DeviceConfig_host;
import android.system.ErrnoException;
@@ -51,6 +54,7 @@
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.hoststubgen.hosthelper.HostTestUtils;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.RuntimeInit;
import com.android.ravenwood.RavenwoodRuntimeNative;
import com.android.ravenwood.RavenwoodRuntimeState;
@@ -58,6 +62,7 @@
import com.android.ravenwood.common.RavenwoodRuntimeException;
import com.android.ravenwood.common.SneakyThrow;
import com.android.server.LocalServices;
+import com.android.server.compat.PlatformCompat;
import org.junit.runner.Description;
@@ -86,10 +91,9 @@
}
private static final String MAIN_THREAD_NAME = "RavenwoodMain";
+ private static final String LIBRAVENWOOD_INITIALIZER_NAME = "ravenwood_initializer";
private static final String RAVENWOOD_NATIVE_SYSPROP_NAME = "ravenwood_sysprop";
private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime";
- private static final String RAVENWOOD_BUILD_PROP =
- getRavenwoodRuntimePath() + "ravenwood-data/build.prop";
/**
* When enabled, attempt to dump all thread stacks just before we hit the
@@ -139,23 +143,61 @@
return res;
}
+ private static final Object sInitializationLock = new Object();
+
+ @GuardedBy("sInitializationLock")
+ private static boolean sInitialized = false;
+
+ @GuardedBy("sInitializationLock")
+ private static Throwable sExceptionFromGlobalInit;
+
private static RavenwoodAwareTestRunner sRunner;
private static RavenwoodSystemProperties sProps;
- private static boolean sInitialized = false;
/**
* Initialize the global environment.
*/
public static void globalInitOnce() {
- if (sInitialized) {
- return;
+ synchronized (sInitializationLock) {
+ if (!sInitialized) {
+ // globalInitOnce() is called from class initializer, which cause
+ // this method to be called recursively,
+ sInitialized = true;
+
+ // This is the first call.
+ try {
+ globalInitInner();
+ } catch (Throwable th) {
+ Log.e(TAG, "globalInit() failed", th);
+
+ sExceptionFromGlobalInit = th;
+ throw th;
+ }
+ } else {
+ // Subsequent calls. If the first call threw, just throw the same error, to prevent
+ // the test from running.
+ if (sExceptionFromGlobalInit != null) {
+ Log.e(TAG, "globalInit() failed re-throwing the same exception",
+ sExceptionFromGlobalInit);
+
+ SneakyThrow.sneakyThrow(sExceptionFromGlobalInit);
+ }
+ }
}
- sInitialized = true;
+ }
+
+ private static void globalInitInner() {
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ Log.v(TAG, "globalInit() called here...", new RuntimeException("NOT A CRASH"));
+ }
+
+ // Some process-wide initialization. (maybe redirect stdout/stderr)
+ RavenwoodCommonUtils.loadJniLibrary(LIBRAVENWOOD_INITIALIZER_NAME);
// We haven't initialized liblog yet, so directly write to System.out here.
- RavenwoodCommonUtils.log(TAG, "globalInit()");
+ RavenwoodCommonUtils.log(TAG, "globalInitInner()");
- // Load libravenwood_sysprop first
+ // Load libravenwood_sysprop before other libraries that may use SystemProperties.
var libProp = RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_SYSPROP_NAME);
System.load(libProp);
RavenwoodRuntimeNative.reloadNativeLibrary(libProp);
@@ -164,7 +206,7 @@
System.load(RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_RUNTIME_NAME));
// Do the basic set up for the android sysprops.
- RavenwoodSystemProperties.initialize(RAVENWOOD_BUILD_PROP);
+ RavenwoodSystemProperties.initialize();
setSystemProperties(null);
// Do this after loading RAVENWOOD_NATIVE_RUNTIME_NAME (which backs Os.setenv()),
@@ -294,6 +336,8 @@
RavenwoodSystemServer.init(config);
+ initializeCompatIds(config);
+
if (ENABLE_TIMEOUT_STACKS) {
sPendingTimeout = sTimeoutExecutor.schedule(
RavenwoodRuntimeEnvironmentController::dumpStacks,
@@ -309,6 +353,31 @@
Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid));
}
+ private static void initializeCompatIds(RavenwoodConfig config) {
+ // Set up compat-IDs for the app side.
+ // TODO: Inside the system server, all the compat-IDs should be enabled,
+ // Due to the `AppCompatCallbacks.install(new long[0], new long[0])` call in
+ // SystemServer.
+
+ // Compat framework only uses the package name and the target SDK level.
+ ApplicationInfo appInfo = new ApplicationInfo();
+ appInfo.packageName = config.mTargetPackageName;
+ appInfo.targetSdkVersion = config.mTargetSdkLevel;
+
+ PlatformCompat platformCompat = null;
+ try {
+ platformCompat = (PlatformCompat) ServiceManager.getServiceOrThrow(
+ Context.PLATFORM_COMPAT_SERVICE);
+ } catch (ServiceNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ var disabledChanges = platformCompat.getDisabledChanges(appInfo);
+ var loggableChanges = platformCompat.getLoggableChanges(appInfo);
+
+ AppCompatCallbacks.install(disabledChanges, loggableChanges);
+ }
+
/**
* De-initialize.
*/
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
index f198a08..438a2bf 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
@@ -17,7 +17,9 @@
package android.platform.test.ravenwood;
import android.content.ClipboardManager;
+import android.content.Context;
import android.hardware.SerialManager;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.ravenwood.example.BlueManager;
import android.ravenwood.example.RedManager;
@@ -27,6 +29,8 @@
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
+import com.android.server.compat.PlatformCompat;
+import com.android.server.compat.PlatformCompatNative;
import com.android.server.utils.TimingsTraceAndSlog;
import java.util.List;
@@ -65,6 +69,14 @@
private static SystemServiceManager sServiceManager;
public static void init(RavenwoodConfig config) {
+ // Always start PlatformCompat, regardless of the requested services.
+ // PlatformCompat is not really a SystemService, so it won't receive boot phases / etc.
+ // This initialization code is copied from SystemServer.java.
+ PlatformCompat platformCompat = new PlatformCompat(config.mState.mSystemServerContext);
+ ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat);
+ ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE,
+ new PlatformCompatNative(platformCompat));
+
// Avoid overhead if no services required
if (config.mServicesRequired.isEmpty()) return;
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index 9bc45be..3e4619f 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -16,21 +16,30 @@
package android.platform.test.ravenwood;
-import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_SYSPROP;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.getRavenwoodRuntimePath;
-import com.android.ravenwood.common.RavenwoodCommonUtils;
+import android.util.Log;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class RavenwoodSystemProperties {
private static final String TAG = "RavenwoodSystemProperties";
+ /** We pull in propeties from this file. */
+ private static final String RAVENWOOD_BUILD_PROP = "ravenwood-data/ravenwood-build.prop";
+
+ /** This is the actual build.prop we use to build the device (contents depends on lunch). */
+ private static final String DEVICE_BUILD_PROP = "ravenwood-data/build.prop";
+
+ /** The default values. */
private static final Map<String, String> sDefaultValues = new HashMap<>();
private static final String[] PARTITIONS = {
@@ -43,52 +52,54 @@
"vendor_dlkm",
};
- /**
- * More info about property file loading: system/core/init/property_service.cpp
- * In the following logic, the only partition we would need to consider is "system",
- * since we only read from system-build.prop
- */
- static void initialize(String propFile) {
- // Load all properties from build.prop
+ private static Map<String, String> readProperties(String propFile) {
+ // Use an ordered map just for cleaner dump log.
+ final Map<String, String> ret = new LinkedHashMap<>();
try {
Files.readAllLines(Path.of(propFile)).stream()
.map(String::trim)
.filter(s -> !s.startsWith("#"))
.map(s -> s.split("\\s*=\\s*", 2))
.filter(a -> a.length == 2)
- .forEach(a -> sDefaultValues.put(a[0], a[1]));
+ .forEach(a -> ret.put(a[0], a[1]));
} catch (IOException e) {
throw new RuntimeException(e);
}
+ return ret;
+ }
- // If ro.product.${name} is not set, derive from ro.product.${partition}.${name}
- // If ro.product.cpu.abilist* is not set, derive from ro.${partition}.product.cpu.abilist*
- for (var entry : Set.copyOf(sDefaultValues.entrySet())) {
- final String key;
- if (entry.getKey().startsWith("ro.product.system.")) {
- var name = entry.getKey().substring(18);
- key = "ro.product." + name;
+ /**
+ * Load default sysprops from {@link #RAVENWOOD_BUILD_PROP}. We also pull in
+ * certain properties from the acutual device's build.prop {@link #DEVICE_BUILD_PROP} too.
+ *
+ * More info about property file loading: system/core/init/property_service.cpp
+ * In the following logic, the only partition we would need to consider is "system",
+ * since we only read from system-build.prop
+ */
+ static void initialize() {
+ var path = getRavenwoodRuntimePath();
+ var ravenwoodProps = readProperties(path + RAVENWOOD_BUILD_PROP);
+ var deviceProps = readProperties(path + DEVICE_BUILD_PROP);
- } else if (entry.getKey().startsWith("ro.system.product.cpu.abilist")) {
- var name = entry.getKey().substring(22);
- key = "ro.product.cpu." + name;
+ Log.i(TAG, "Default system properties:");
+ ravenwoodProps.forEach((key, origValue) -> {
+ final String value;
+
+ // If a value starts with "$$$", then this is a reference to the device-side value.
+ if (origValue.startsWith("$$$")) {
+ var deviceKey = origValue.substring(3);
+ var deviceValue = deviceProps.get(deviceKey);
+ if (deviceValue == null) {
+ throw new RuntimeException("Failed to initialize system properties. Key '"
+ + deviceKey + "' doesn't exist in the device side build.prop");
+ }
+ value = deviceValue;
} else {
- continue;
+ value = origValue;
}
- if (!sDefaultValues.containsKey(key)) {
- sDefaultValues.put(key, entry.getValue());
- }
- }
-
- // Some other custom values
- sDefaultValues.put("ro.board.first_api_level", "1");
- sDefaultValues.put("ro.product.first_api_level", "1");
- sDefaultValues.put("ro.soc.manufacturer", "Android");
- sDefaultValues.put("ro.soc.model", "Ravenwood");
- sDefaultValues.put(RAVENWOOD_SYSPROP, "1");
-
- // Log all values
- sDefaultValues.forEach((key, value) -> RavenwoodCommonUtils.log(TAG, key + "=" + value));
+ Log.i(TAG, key + "=" + value);
+ sDefaultValues.put(key, value);
+ });
// Copy ro.product.* and ro.build.* to all partitions, just in case
// We don't want to log these because these are just a lot of duplicate values
@@ -104,6 +115,13 @@
}
}
}
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ // Dump all properties for local debugging.
+ Log.v(TAG, "All system properties:");
+ for (var key : sDefaultValues.keySet().stream().sorted().toList()) {
+ Log.v(TAG, "" + key + "=" + sDefaultValues.get(key));
+ }
+ }
}
private volatile boolean mIsImmutable;
diff --git a/ravenwood/runtime-jni/ravenwood_initializer.cpp b/ravenwood/runtime-jni/ravenwood_initializer.cpp
new file mode 100644
index 0000000..89fb7c3
--- /dev/null
+++ b/ravenwood/runtime-jni/ravenwood_initializer.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /*
+ * This file is compiled into a single SO file, which we load at the very first.
+ * We can do process-wide initialization here.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "jni_helper.h"
+
+static void maybeRedirectLog() {
+ auto ravenwoodLogOut = getenv("RAVENWOOD_LOG_OUT");
+ if (ravenwoodLogOut == NULL) {
+ return;
+ }
+ ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to %s", ravenwoodLogOut);
+
+ // Redirect stdin / stdout to /dev/tty.
+ int ttyFd = open(ravenwoodLogOut, O_WRONLY | O_APPEND);
+ if (ttyFd == -1) {
+ ALOGW("$RAVENWOOD_LOG_OUT is set to %s, but failed to open: %s ", ravenwoodLogOut,
+ strerror(errno));
+ return;
+ }
+ dup2(ttyFd, 1);
+ dup2(ttyFd, 2);
+}
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
+ ALOGI("%s: JNI_OnLoad", __FILE__);
+
+ maybeRedirectLog();
+ return JNI_VERSION_1_4;
+}
diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp
index 5b75e98..c1993f6 100644
--- a/ravenwood/runtime-jni/ravenwood_runtime.cpp
+++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp
@@ -180,24 +180,6 @@
return syscall(__NR_gettid);
}
-static void maybeRedirectLog() {
- auto ravenwoodLogOut = getenv("RAVENWOOD_LOG_OUT");
- if (ravenwoodLogOut == NULL) {
- return;
- }
- ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to %s", ravenwoodLogOut);
-
- // Redirect stdin / stdout to /dev/tty.
- int ttyFd = open(ravenwoodLogOut, O_WRONLY);
- if (ttyFd == -1) {
- ALOGW("$RAVENWOOD_LOG_OUT is set to %s, but failed to open: %s ", ravenwoodLogOut,
- strerror(errno));
- return;
- }
- dup2(ttyFd, 1);
- dup2(ttyFd, 2);
-}
-
// ---- Registration ----
extern void register_android_system_OsConstants(JNIEnv* env);
@@ -218,8 +200,6 @@
};
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
- maybeRedirectLog();
-
ALOGI("%s: JNI_OnLoad", __FILE__);
JNIEnv* env = GetJNIEnvOrDie(vm);
diff --git a/ravenwood/scripts/run-ravenwood-tests.sh b/ravenwood/scripts/run-ravenwood-tests.sh
index 672c685..fe2269a 100755
--- a/ravenwood/scripts/run-ravenwood-tests.sh
+++ b/ravenwood/scripts/run-ravenwood-tests.sh
@@ -26,14 +26,14 @@
# Regex to identify slow tests, in PCRE
-SLOW_TEST_RE='^(SystemUiRavenTests|CtsIcuTestCasesRavenwood)$'
+SLOW_TEST_RE='^(SystemUiRavenTests|CtsIcuTestCasesRavenwood|CarSystemUIRavenTests)$'
smoke=0
include_re=""
exclude_re=""
smoke_exclude_re=""
dry_run=""
-while getopts "sx:f:d" opt; do
+while getopts "sx:f:dt" opt; do
case "$opt" in
s)
# Remove slow tests.
@@ -51,6 +51,9 @@
# Dry run
dry_run="echo"
;;
+ t)
+ export RAVENWOOD_LOG_OUT=$(tty)
+ ;;
'?')
exit 1
;;
@@ -67,7 +70,7 @@
if [[ "$re" == "" ]] ; then
cat # No filtering
else
- grep $grep_arg -P "$re"
+ grep $grep_arg -iP "$re"
fi
}
diff --git a/ravenwood/tests/bivalenttest/Android.bp b/ravenwood/tests/bivalenttest/Android.bp
index 4895a1a..40e6672 100644
--- a/ravenwood/tests/bivalenttest/Android.bp
+++ b/ravenwood/tests/bivalenttest/Android.bp
@@ -58,6 +58,9 @@
java_defaults {
name: "ravenwood-bivalent-device-defaults",
defaults: ["ravenwood-bivalent-defaults"],
+
+ target_sdk_version: "34", // For compat-framework tests
+
// TODO(b/371215487): migrate bivalenttest.ravenizer tests to another architecture
exclude_srcs: [
"test/**/ravenizer/*.java",
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
new file mode 100644
index 0000000..a95760d
--- /dev/null
+++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.ravenwoodtest.bivalenttest.compat
+
+import android.app.compat.CompatChanges
+import android.os.Build
+import android.platform.test.ravenwood.RavenwoodConfig
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.internal.ravenwood.RavenwoodEnvironment.CompatIdsForTest
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class RavenwoodCompatFrameworkTest {
+ companion object {
+ @JvmField // Expose as a raw field, not as a property.
+ @RavenwoodConfig.Config
+ val config = RavenwoodConfig.Builder()
+ .setTargetSdkLevel(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ .build()
+ }
+
+ @Test
+ fun testEnabled() {
+ Assert.assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_1))
+ }
+
+ @Test
+ fun testDisabled() {
+ Assert.assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_2))
+ }
+
+ @Test
+ fun testEnabledAfterSForUApps() {
+ Assert.assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_3))
+ }
+
+ @Test
+ fun testEnabledAfterUForUApps() {
+ Assert.assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_4))
+ }
+}
\ No newline at end of file
diff --git a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java
index b3d3963..4aae1e1 100644
--- a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java
+++ b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java
@@ -19,17 +19,22 @@
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
import android.content.Context;
import android.hardware.SerialManager;
import android.hardware.SerialManagerInternal;
-import android.platform.test.ravenwood.RavenwoodRule;
+import android.platform.test.ravenwood.RavenwoodConfig;
+import android.platform.test.ravenwood.RavenwoodConfig.Config;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.server.LocalServices;
-import org.junit.Rule;
+import com.google.common.collect.Lists;
+
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,18 +42,25 @@
public class RavenwoodServicesTest {
private static final String TEST_VIRTUAL_PORT = "virtual:example";
- @Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
+ @Config
+ public static final RavenwoodConfig sRavenwood = new RavenwoodConfig.Builder()
.setProcessSystem()
.setServicesRequired(SerialManager.class)
.build();
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ }
+
@Test
public void testDefined() {
final SerialManager fromName = (SerialManager)
- mRavenwood.getContext().getSystemService(Context.SERIAL_SERVICE);
+ mContext.getSystemService(Context.SERIAL_SERVICE);
final SerialManager fromClass =
- mRavenwood.getContext().getSystemService(SerialManager.class);
+ mContext.getSystemService(SerialManager.class);
assertNotNull(fromName);
assertNotNull(fromClass);
assertEquals(fromName, fromClass);
@@ -61,9 +73,9 @@
// Verify that we can obtain a manager, and talk to the backend service, and that no
// serial ports are configured by default
final SerialManager service = (SerialManager)
- mRavenwood.getContext().getSystemService(Context.SERIAL_SERVICE);
+ mContext.getSystemService(Context.SERIAL_SERVICE);
final String[] ports = service.getSerialPorts();
- final String[] refPorts = mRavenwood.getContext().getResources().getStringArray(
+ final String[] refPorts = mContext.getResources().getStringArray(
com.android.internal.R.array.config_serialPorts);
assertArrayEquals(refPorts, ports);
}
@@ -71,7 +83,7 @@
@Test
public void testDriven() {
final SerialManager service = (SerialManager)
- mRavenwood.getContext().getSystemService(Context.SERIAL_SERVICE);
+ mContext.getSystemService(Context.SERIAL_SERVICE);
final SerialManagerInternal internal = LocalServices.getService(
SerialManagerInternal.class);
@@ -79,8 +91,17 @@
throw new UnsupportedOperationException(
"Needs socketpair() to offer accurate emulation");
});
- final String[] ports = service.getSerialPorts();
- assertEquals(1, ports.length);
- assertEquals(TEST_VIRTUAL_PORT, ports[0]);
+ try {
+ final String[] ports = service.getSerialPorts();
+ for (var port : ports) {
+ if (TEST_VIRTUAL_PORT.equals(port)) {
+ return; // Pass
+ }
+ }
+ fail("Virtual port " + TEST_VIRTUAL_PORT + " not found. Actual="
+ + Lists.newArrayList(ports));
+ } finally {
+ internal.removeVirtualSerialPortForTest(TEST_VIRTUAL_PORT);
+ }
}
}
diff --git a/ravenwood/texts/build.prop-sample-cuttlefish b/ravenwood/texts/build.prop-sample-cuttlefish
new file mode 100644
index 0000000..f78b727
--- /dev/null
+++ b/ravenwood/texts/build.prop-sample-cuttlefish
@@ -0,0 +1,132 @@
+# This is file is generated with `aosp_cf_x86_64_phone-trunk_staging-eng` on 2024-11-06.
+# We have this file here only as a reference. We don't actually use this file anywhere.
+
+####################################
+# from generate_common_build_props
+# These properties identify this partition image.
+####################################
+ro.product.system.brand=Android
+ro.product.system.device=generic
+ro.product.system.manufacturer=Android
+ro.product.system.model=mainline
+ro.product.system.name=mainline
+ro.system.product.cpu.abilist=x86_64,x86,arm64-v8a,armeabi-v7a,armeabi
+ro.system.product.cpu.abilist32=x86,armeabi-v7a,armeabi
+ro.system.product.cpu.abilist64=x86_64,arm64-v8a
+ro.system.build.date=Tue Nov 5 13:25:43 PST 2024
+ro.system.build.date.utc=1730841943
+ro.system.build.fingerprint=generic/aosp_cf_x86_64_phone/vsoc_x86_64:Baklava/MAIN/eng.omakot:eng/test-keys
+ro.system.build.id=MAIN
+ro.system.build.tags=test-keys
+ro.system.build.type=eng
+ro.system.build.version.incremental=eng.omakot
+ro.system.build.version.release=15
+ro.system.build.version.release_or_codename=Baklava
+ro.system.build.version.sdk=35
+####################################
+# from gen_build_prop.py:generate_build_info
+####################################
+# begin build properties
+ro.build.legacy.id=MAIN
+ro.build.display.id=aosp_cf_x86_64_phone-eng Baklava MAIN eng.omakot test-keys
+ro.build.version.incremental=eng.omakot
+ro.build.version.sdk=35
+ro.build.version.preview_sdk=1
+ro.build.version.preview_sdk_fingerprint=2ef06129940d459014cf4dede3950d71
+ro.build.version.codename=Baklava
+ro.build.version.all_codenames=Baklava
+ro.build.version.known_codenames=Base,Base11,Cupcake,Donut,Eclair,Eclair01,EclairMr1,Froyo,Gingerbread,GingerbreadMr1,Honeycomb,HoneycombMr1,HoneycombMr2,IceCreamSandwich,IceCreamSandwichMr1,JellyBean,JellyBeanMr1,JellyBeanMr2,Kitkat,KitkatWatch,Lollipop,LollipopMr1,M,N,NMr1,O,OMr1,P,Q,R,S,Sv2,Tiramisu,UpsideDownCake,VanillaIceCream,Baklava
+ro.build.version.release=15
+ro.build.version.release_or_codename=Baklava
+ro.build.version.release_or_preview_display=Baklava
+ro.build.version.security_patch=2024-08-05
+ro.build.version.base_os=
+ro.build.version.min_supported_target_sdk=28
+ro.build.date=Tue Nov 5 13:25:43 PST 2024
+ro.build.date.utc=1730841943
+ro.build.type=eng
+ro.build.user=omakoto
+ro.build.host=omakoto-ct1.c.googlers.com
+ro.build.tags=test-keys
+ro.build.flavor=aosp_cf_x86_64_phone-eng
+# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,
+# use ro.product.cpu.abilist instead.
+ro.product.cpu.abi=x86_64
+ro.product.locale=en-US
+ro.wifi.channels=
+# ro.build.product is obsolete; use ro.product.device
+ro.build.product=vsoc_x86_64
+# Do not try to parse description or thumbprint
+ro.build.description=aosp_cf_x86_64_phone-eng Baklava MAIN eng.omakot test-keys
+# end build properties
+####################################
+# from variable ADDITIONAL_SYSTEM_PROPERTIES
+####################################
+ro.treble.enabled=true
+ro.llndk.api_level=202504
+ro.actionable_compatible_property.enabled=true
+persist.debug.dalvik.vm.core_platform_api_policy=just-warn
+ro.postinstall.fstab.prefix=/system
+ro.kernel.android.checkjni=1
+ro.secure=0
+ro.allow.mock.location=1
+dalvik.vm.lockprof.threshold=500
+ro.debuggable=1
+dalvik.vm.image-dex2oat-filter=extract
+init.svc_debug.no_fatal.zygote=true
+net.bt.name=Android
+ro.force.debuggable=0
+####################################
+# from variable PRODUCT_SYSTEM_PROPERTIES
+####################################
+debug.atrace.tags.enableflags=0
+persist.traced.enable=1
+dalvik.vm.image-dex2oat-Xms=64m
+dalvik.vm.image-dex2oat-Xmx=64m
+dalvik.vm.dex2oat-Xms=64m
+dalvik.vm.dex2oat-Xmx=512m
+dalvik.vm.usejit=true
+dalvik.vm.dexopt.secondary=true
+dalvik.vm.dexopt.thermal-cutoff=2
+dalvik.vm.appimageformat=lz4
+ro.dalvik.vm.native.bridge=0
+pm.dexopt.post-boot=verify
+pm.dexopt.first-boot=verify
+pm.dexopt.boot-after-ota=verify
+pm.dexopt.boot-after-mainline-update=verify
+pm.dexopt.install=speed-profile
+pm.dexopt.install-fast=skip
+pm.dexopt.install-bulk=speed-profile
+pm.dexopt.install-bulk-secondary=verify
+pm.dexopt.install-bulk-downgraded=verify
+pm.dexopt.install-bulk-secondary-downgraded=verify
+pm.dexopt.bg-dexopt=speed-profile
+pm.dexopt.ab-ota=speed-profile
+pm.dexopt.inactive=verify
+pm.dexopt.cmdline=verify
+pm.dexopt.shared=speed
+dalvik.vm.disable-art-service-dexopt=true
+dalvik.vm.disable-odrefresh=true
+dalvik.vm.dex2oat-resolve-startup-strings=true
+dalvik.vm.dex2oat-max-image-block-size=524288
+dalvik.vm.minidebuginfo=true
+dalvik.vm.dex2oat-minidebuginfo=true
+dalvik.vm.madvise.vdexfile.size=104857600
+dalvik.vm.madvise.odexfile.size=104857600
+dalvik.vm.madvise.artfile.size=4294967295
+dalvik.vm.usap_pool_enabled=false
+dalvik.vm.usap_refill_threshold=1
+dalvik.vm.usap_pool_size_max=3
+dalvik.vm.usap_pool_size_min=1
+dalvik.vm.usap_pool_refill_delay_ms=3000
+dalvik.vm.useartservice=true
+dalvik.vm.enable_pr_dexopt=true
+ro.cp_system_other_odex=1
+ro.apex.updatable=true
+ro.launcher.depth.widget=0
+####################################
+# from variable PRODUCT_SYSTEM_DEFAULT_PROPERTIES
+####################################
+# Auto-added by post_process_props.py
+persist.sys.usb.config=adb
+# end of file
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index 70c1d78..82be2c0 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -365,3 +365,9 @@
android.os.IpcDataCache
android.app.PropertyInvalidatedCache
+
+android.app.compat.*
+com.android.server.compat.*
+com.android.internal.compat.*
+android.app.AppCompatCallbacks
+
diff --git a/ravenwood/texts/ravenwood-build.prop b/ravenwood/texts/ravenwood-build.prop
new file mode 100644
index 0000000..93a18cf
--- /dev/null
+++ b/ravenwood/texts/ravenwood-build.prop
@@ -0,0 +1,44 @@
+# This file contains system properties used on ravenwood.
+
+ro.is_on_ravenwood=1
+
+ro.board.first_api_level=1
+ro.product.first_api_level=1
+ro.soc.manufacturer=Android
+ro.soc.model=Ravenwood
+ro.debuggable=1
+
+# The ones starting with "ro.product" or "ro.bild" will be copied to all "partitions" too.
+# See RavenwoodSystemProperties.
+ro.product.brand=Android
+ro.product.device=Ravenwood
+ro.product.manufacturer=Android
+ro.product.model=Ravenwood
+ro.product.name=Ravenwood
+ro.product.cpu.abilist=x86_64
+ro.product.cpu.abilist32=
+ro.product.cpu.abilist64=x86_64
+
+ro.build.date=Thu Jan 01 00:00:00 GMT 2024
+ro.build.date.utc=1704092400
+ro.build.id=MAIN
+ro.build.tags=dev-keys
+ro.build.type=userdebug
+ro.build.version.incremental=userdebug.ravenwood.20240101
+
+# These are what we used to use on Ravenwood, copied here as a reference.
+#ro.build.version.codename=REL
+#ro.build.version.all_codenames=REL
+#ro.build.version.known_codenames=REL
+#ro.build.version.release=14
+#ro.build.version.release_or_codename=VanillaIceCream
+#ro.build.version.sdk=34
+
+# We pull in the following values from the real build.prop file.
+ro.build.version.codename=$$$ro.build.version.codename
+ro.build.version.all_codenames=$$$ro.build.version.codename
+ro.build.version.known_codenames=$$$ro.build.version.codename
+ro.build.version.release=$$$ro.build.version.release
+ro.build.version.release_or_codename=$$$ro.build.version.release_or_codename
+ro.build.version.release_or_preview_display=$$$ro.build.version.release_or_preview_display
+ro.build.version.sdk=$$$ro.build.version.sdk
diff --git a/ravenwood/texts/ravenwood-services-policies.txt b/ravenwood/texts/ravenwood-services-policies.txt
index cc2fa60..530e5c8 100644
--- a/ravenwood/texts/ravenwood-services-policies.txt
+++ b/ravenwood/texts/ravenwood-services-policies.txt
@@ -1 +1,12 @@
# Ravenwood "policy" file for services.core.
+
+# Auto-generated from XSD
+class com.android.server.compat.config.Change keepclass
+class com.android.server.compat.config.Config keepclass
+class com.android.server.compat.config.XmlParser keepclass
+class com.android.server.compat.overrides.ChangeOverrides keepclass
+class com.android.server.compat.overrides.OverrideValue keepclass
+class com.android.server.compat.overrides.Overrides keepclass
+class com.android.server.compat.overrides.RawOverrideValue keepclass
+class com.android.server.compat.overrides.XmlParser keepclass
+class com.android.server.compat.overrides.XmlWriter keepclass
\ No newline at end of file
diff --git a/services/Android.bp b/services/Android.bp
index 899e224..fc0bb33 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -282,6 +282,7 @@
"services.wifi",
"service-blobstore",
"service-jobscheduler",
+ "service-connectivity-b-pre-jarjar", // Move it to mainline module
"android.hidl.base-V1.0-java",
],
diff --git a/services/art-profile b/services/art-profile
index 6fa4c88..ce1e2c6 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -5657,7 +5657,7 @@
Lcom/android/server/utils/Watcher;
Lcom/android/server/vibrator/VibratorController$NativeWrapper;
Lcom/android/server/vibrator/VibratorController$OnVibrationCompleteListener;
-Lcom/android/server/vibrator/VibratorManagerService$OnSyncedVibrationCompleteListener;
+Lcom/android/server/vibrator/VibratorManagerService$VibratorManagerNativeCallbacks;
Lcom/android/server/vibrator/VibratorManagerService;
Lcom/android/server/vr/EnabledComponentsObserver$EnabledComponentChangeListener;
Lcom/android/server/vr/VrManagerService;
diff --git a/services/art-wear-profile b/services/art-wear-profile
index 47bdb13..1e3090f 100644
--- a/services/art-wear-profile
+++ b/services/art-wear-profile
@@ -1330,7 +1330,7 @@
Lcom/android/server/utils/Watcher;
Lcom/android/server/vibrator/VibratorController$NativeWrapper;
Lcom/android/server/vibrator/VibratorController$OnVibrationCompleteListener;
-Lcom/android/server/vibrator/VibratorManagerService$OnSyncedVibrationCompleteListener;
+Lcom/android/server/vibrator/VibratorManagerService$VibratorManagerNativeCallbacks;
Lcom/android/server/vibrator/VibratorManagerService;
Lcom/android/server/vr/EnabledComponentsObserver$EnabledComponentChangeListener;
Lcom/android/server/vr/VrManagerService;
@@ -24948,7 +24948,7 @@
PLcom/android/server/vibrator/VibratorManagerService$NativeWrapper;->cancelSynced()V
PLcom/android/server/vibrator/VibratorManagerService$NativeWrapper;->getCapabilities()J
PLcom/android/server/vibrator/VibratorManagerService$NativeWrapper;->getVibratorIds()[I
-PLcom/android/server/vibrator/VibratorManagerService$NativeWrapper;->init(Lcom/android/server/vibrator/VibratorManagerService$OnSyncedVibrationCompleteListener;)V
+PLcom/android/server/vibrator/VibratorManagerService$NativeWrapper;->init(Lcom/android/server/vibrator/VibratorManagerService$VibratorManagerNativeCallbacks;)V
PLcom/android/server/vibrator/VibratorManagerService$VibrationCompleteListener;-><init>(Lcom/android/server/vibrator/VibratorManagerService;)V
PLcom/android/server/vibrator/VibratorManagerService$VibrationCompleteListener;->onComplete(IJ)V
PLcom/android/server/vibrator/VibratorManagerService$VibrationRecords;-><init>(II)V
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 51034d2..7cba9e0 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -31,16 +31,13 @@
import static com.android.internal.util.CollectionUtils.any;
import static com.android.internal.util.Preconditions.checkState;
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.server.companion.utils.PackageUtils.enforceUsesCompanionDeviceFeature;
-import static com.android.server.companion.utils.PackageUtils.getPackageInfo;
import static com.android.server.companion.utils.PackageUtils.isRestrictedSettingsAllowed;
import static com.android.server.companion.utils.PermissionsUtils.enforceCallerCanManageAssociationsForPackage;
import static com.android.server.companion.utils.PermissionsUtils.enforceCallerIsSystemOr;
import static com.android.server.companion.utils.PermissionsUtils.enforceCallerIsSystemOrCanInteractWithUserId;
import static java.util.Objects.requireNonNull;
-import static java.util.concurrent.TimeUnit.MINUTES;
import android.annotation.EnforcePermission;
import android.annotation.NonNull;
@@ -69,31 +66,22 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.net.MacAddress;
-import android.net.NetworkPolicyManager;
import android.os.Binder;
-import android.os.Environment;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.PowerExemptionManager;
import android.os.PowerManagerInternal;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.flags.Flags;
-import android.util.ArraySet;
import android.util.ExceptionUtils;
import android.util.Slog;
-import com.android.internal.app.IAppOpsService;
import com.android.internal.content.PackageMonitor;
import com.android.internal.notification.NotificationAccessConfirmationActivityContract;
-import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.server.FgThread;
@@ -114,35 +102,25 @@
import com.android.server.companion.devicepresence.ObservableUuid;
import com.android.server.companion.devicepresence.ObservableUuidStore;
import com.android.server.companion.transport.CompanionTransportManager;
-import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
-import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.List;
-import java.util.Set;
@SuppressLint("LongLogTag")
public class CompanionDeviceManagerService extends SystemService {
private static final String TAG = "CDM_CompanionDeviceManagerService";
private static final long PAIR_WITHOUT_PROMPT_WINDOW_MS = 10 * 60 * 1000; // 10 min
-
- private static final String PREF_FILE_NAME = "companion_device_preferences.xml";
- private static final String PREF_KEY_AUTO_REVOKE_GRANTS_DONE = "auto_revoke_grants_done";
private static final int MAX_CN_LENGTH = 500;
- private final ActivityTaskManagerInternal mAtmInternal;
- private final ActivityManagerInternal mAmInternal;
- private final IAppOpsService mAppOpsManager;
- private final PowerExemptionManager mPowerExemptionManager;
- private final PackageManagerInternal mPackageManagerInternal;
-
private final AssociationStore mAssociationStore;
private final SystemDataTransferRequestStore mSystemDataTransferRequestStore;
private final ObservableUuidStore mObservableUuidStore;
+
+ private final CompanionExemptionProcessor mCompanionExemptionProcessor;
private final AssociationRequestsProcessor mAssociationRequestsProcessor;
private final SystemDataTransferProcessor mSystemDataTransferProcessor;
private final BackupRestoreProcessor mBackupRestoreProcessor;
@@ -156,12 +134,15 @@
super(context);
final ActivityManager activityManager = context.getSystemService(ActivityManager.class);
- mPowerExemptionManager = context.getSystemService(PowerExemptionManager.class);
- mAppOpsManager = IAppOpsService.Stub.asInterface(
- ServiceManager.getService(Context.APP_OPS_SERVICE));
- mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
- mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
- mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
+ final PowerExemptionManager powerExemptionManager = context.getSystemService(
+ PowerExemptionManager.class);
+ final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+ final ActivityTaskManagerInternal atmInternal = LocalServices.getService(
+ ActivityTaskManagerInternal.class);
+ final ActivityManagerInternal amInternal = LocalServices.getService(
+ ActivityManagerInternal.class);
+ final PackageManagerInternal packageManagerInternal = LocalServices.getService(
+ PackageManagerInternal.class);
final UserManager userManager = context.getSystemService(UserManager.class);
final PowerManagerInternal powerManagerInternal = LocalServices.getService(
PowerManagerInternal.class);
@@ -173,25 +154,29 @@
// Init processors
mAssociationRequestsProcessor = new AssociationRequestsProcessor(context,
- mPackageManagerInternal, mAssociationStore);
- mBackupRestoreProcessor = new BackupRestoreProcessor(context, mPackageManagerInternal,
+ packageManagerInternal, mAssociationStore);
+ mBackupRestoreProcessor = new BackupRestoreProcessor(context, packageManagerInternal,
mAssociationStore, associationDiskStore, mSystemDataTransferRequestStore,
mAssociationRequestsProcessor);
mCompanionAppBinder = new CompanionAppBinder(context);
+ mCompanionExemptionProcessor = new CompanionExemptionProcessor(context,
+ powerExemptionManager, appOpsManager, packageManagerInternal, atmInternal,
+ amInternal, mAssociationStore);
+
mDevicePresenceProcessor = new DevicePresenceProcessor(context,
mCompanionAppBinder, userManager, mAssociationStore, mObservableUuidStore,
- powerManagerInternal);
+ powerManagerInternal, mCompanionExemptionProcessor);
mTransportManager = new CompanionTransportManager(context, mAssociationStore);
mDisassociationProcessor = new DisassociationProcessor(context, activityManager,
- mAssociationStore, mPackageManagerInternal, mDevicePresenceProcessor,
+ mAssociationStore, packageManagerInternal, mDevicePresenceProcessor,
mCompanionAppBinder, mSystemDataTransferRequestStore, mTransportManager);
mSystemDataTransferProcessor = new SystemDataTransferProcessor(this,
- mPackageManagerInternal, mAssociationStore,
+ packageManagerInternal, mAssociationStore,
mSystemDataTransferRequestStore, mTransportManager);
// TODO(b/279663946): move context sync to a dedicated system service
@@ -202,7 +187,6 @@
public void onStart() {
// Init association stores
mAssociationStore.refreshCache();
- mAssociationStore.registerLocalListener(mAssociationStoreChangeListener);
// Init UUID store
mObservableUuidStore.getObservableUuidsForUser(getContext().getUserId());
@@ -240,11 +224,8 @@
if (associations.isEmpty()) return;
- updateAtm(userId, associations);
-
- BackgroundThread.getHandler().sendMessageDelayed(
- obtainMessage(CompanionDeviceManagerService::maybeGrantAutoRevokeExemptions, this),
- MINUTES.toMillis(10));
+ mCompanionExemptionProcessor.updateAtm(userId, associations);
+ mCompanionExemptionProcessor.updateAutoRevokeExemptions();
}
@Override
@@ -262,9 +243,12 @@
if (!associationsForPackage.isEmpty()) {
Slog.i(TAG, "Package removed or data cleared for user=[" + userId + "], package=["
+ packageName + "]. Cleaning up CDM data...");
- }
- for (AssociationInfo association : associationsForPackage) {
- mDisassociationProcessor.disassociate(association.getId());
+
+ for (AssociationInfo association : associationsForPackage) {
+ mDisassociationProcessor.disassociate(association.getId());
+ }
+
+ mCompanionAppBinder.onPackageChanged(userId);
}
// Clear observable UUIDs for the package.
@@ -273,19 +257,16 @@
for (ObservableUuid uuid : uuidsTobeObserved) {
mObservableUuidStore.removeObservableUuid(userId, uuid.getUuid(), packageName);
}
-
- mCompanionAppBinder.onPackagesChanged(userId);
}
private void onPackageModifiedInternal(@UserIdInt int userId, @NonNull String packageName) {
- final List<AssociationInfo> associationsForPackage =
+ final List<AssociationInfo> associations =
mAssociationStore.getAssociationsByPackage(userId, packageName);
- for (AssociationInfo association : associationsForPackage) {
- updateSpecialAccessPermissionForAssociatedPackage(association.getUserId(),
- association.getPackageName());
- }
+ if (!associations.isEmpty()) {
+ mCompanionExemptionProcessor.exemptPackage(userId, packageName, false);
- mCompanionAppBinder.onPackagesChanged(userId);
+ mCompanionAppBinder.onPackageChanged(userId);
+ }
}
private void onPackageAddedInternal(@UserIdInt int userId, @NonNull String packageName) {
@@ -765,130 +746,6 @@
}
}
- /**
- * Update special access for the association's package
- */
- public void updateSpecialAccessPermissionForAssociatedPackage(int userId, String packageName) {
- final PackageInfo packageInfo =
- getPackageInfo(getContext(), userId, packageName);
-
- Binder.withCleanCallingIdentity(() -> updateSpecialAccessPermissionAsSystem(packageInfo));
- }
-
- private void updateSpecialAccessPermissionAsSystem(PackageInfo packageInfo) {
- if (packageInfo == null) {
- return;
- }
-
- if (containsEither(packageInfo.requestedPermissions,
- android.Manifest.permission.RUN_IN_BACKGROUND,
- android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND)) {
- mPowerExemptionManager.addToPermanentAllowList(packageInfo.packageName);
- } else {
- try {
- mPowerExemptionManager.removeFromPermanentAllowList(packageInfo.packageName);
- } catch (UnsupportedOperationException e) {
- Slog.w(TAG, packageInfo.packageName + " can't be removed from power save"
- + " whitelist. It might due to the package is whitelisted by the system.");
- }
- }
-
- NetworkPolicyManager networkPolicyManager = NetworkPolicyManager.from(getContext());
- try {
- if (containsEither(packageInfo.requestedPermissions,
- android.Manifest.permission.USE_DATA_IN_BACKGROUND,
- android.Manifest.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND)) {
- networkPolicyManager.addUidPolicy(
- packageInfo.applicationInfo.uid,
- NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
- } else {
- networkPolicyManager.removeUidPolicy(
- packageInfo.applicationInfo.uid,
- NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
- }
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, e.getMessage());
- }
-
- exemptFromAutoRevoke(packageInfo.packageName, packageInfo.applicationInfo.uid);
- }
-
- private void exemptFromAutoRevoke(String packageName, int uid) {
- try {
- mAppOpsManager.setMode(
- AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
- uid,
- packageName,
- AppOpsManager.MODE_IGNORED);
- } catch (RemoteException e) {
- Slog.w(TAG, "Error while granting auto revoke exemption for " + packageName, e);
- }
- }
-
- private void updateAtm(int userId, List<AssociationInfo> associations) {
- final Set<Integer> companionAppUids = new ArraySet<>();
- for (AssociationInfo association : associations) {
- final int uid = mPackageManagerInternal.getPackageUid(association.getPackageName(),
- 0, userId);
- if (uid >= 0) {
- companionAppUids.add(uid);
- }
- }
- if (mAtmInternal != null) {
- mAtmInternal.setCompanionAppUids(userId, companionAppUids);
- }
- if (mAmInternal != null) {
- // Make a copy of the set and send it to ActivityManager.
- mAmInternal.setCompanionAppUids(userId, new ArraySet<>(companionAppUids));
- }
- }
-
- private void maybeGrantAutoRevokeExemptions() {
- Slog.d(TAG, "maybeGrantAutoRevokeExemptions()");
-
- PackageManager pm = getContext().getPackageManager();
- for (int userId : LocalServices.getService(UserManagerInternal.class).getUserIds()) {
- SharedPreferences pref = getContext().getSharedPreferences(
- new File(Environment.getUserSystemDirectory(userId), PREF_FILE_NAME),
- Context.MODE_PRIVATE);
- if (pref.getBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, false)) {
- continue;
- }
-
- try {
- final List<AssociationInfo> associations =
- mAssociationStore.getActiveAssociationsByUser(userId);
- for (AssociationInfo a : associations) {
- try {
- int uid = pm.getPackageUidAsUser(a.getPackageName(), userId);
- exemptFromAutoRevoke(a.getPackageName(), uid);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Unknown companion package: " + a.getPackageName(), e);
- }
- }
- } finally {
- pref.edit().putBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, true).apply();
- }
- }
- }
-
- private final AssociationStore.OnChangeListener mAssociationStoreChangeListener =
- new AssociationStore.OnChangeListener() {
- @Override
- public void onAssociationChanged(int changeType, AssociationInfo association) {
- Slog.d(TAG, "onAssociationChanged changeType=[" + changeType
- + "], association=[" + association);
-
- final int userId = association.getUserId();
- final List<AssociationInfo> updatedAssociations =
- mAssociationStore.getActiveAssociationsByUser(userId);
-
- updateAtm(userId, updatedAssociations);
- updateSpecialAccessPermissionForAssociatedPackage(association.getUserId(),
- association.getPackageName());
- }
- };
-
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override
public void onPackageRemoved(String packageName, int uid) {
@@ -911,10 +768,6 @@
}
};
- private static <T> boolean containsEither(T[] array, T a, T b) {
- return ArrayUtils.contains(array, a) || ArrayUtils.contains(array, b);
- }
-
private class LocalService implements CompanionDeviceManagerServiceInternal {
@Override
diff --git a/services/companion/java/com/android/server/companion/CompanionExemptionProcessor.java b/services/companion/java/com/android/server/companion/CompanionExemptionProcessor.java
new file mode 100644
index 0000000..ea2bc17
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/CompanionExemptionProcessor.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_IGNORED;
+
+import static com.android.server.companion.utils.PackageUtils.getPackageInfo;
+
+import android.annotation.SuppressLint;
+import android.app.ActivityManagerInternal;
+import android.app.AppOpsManager;
+import android.companion.AssociationInfo;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.net.NetworkPolicyManager;
+import android.os.Binder;
+import android.os.Environment;
+import android.os.PowerExemptionManager;
+import android.util.ArraySet;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.server.LocalServices;
+import com.android.server.companion.association.AssociationStore;
+import com.android.server.pm.UserManagerInternal;
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@SuppressLint("LongLogTag")
+public class CompanionExemptionProcessor {
+
+ private static final String TAG = "CDM_CompanionExemptionProcessor";
+
+ private static final String PREF_FILE_NAME = "companion_device_preferences.xml";
+ private static final String PREF_KEY_AUTO_REVOKE_GRANTS_DONE = "auto_revoke_grants_done";
+
+ private final Context mContext;
+ private final PowerExemptionManager mPowerExemptionManager;
+ private final AppOpsManager mAppOpsManager;
+ private final PackageManagerInternal mPackageManager;
+ private final ActivityTaskManagerInternal mAtmInternal;
+ private final ActivityManagerInternal mAmInternal;
+ private final AssociationStore mAssociationStore;
+
+ public CompanionExemptionProcessor(Context context, PowerExemptionManager powerExemptionManager,
+ AppOpsManager appOpsManager, PackageManagerInternal packageManager,
+ ActivityTaskManagerInternal atmInternal, ActivityManagerInternal amInternal,
+ AssociationStore associationStore) {
+ mContext = context;
+ mPowerExemptionManager = powerExemptionManager;
+ mAppOpsManager = appOpsManager;
+ mPackageManager = packageManager;
+ mAtmInternal = atmInternal;
+ mAmInternal = amInternal;
+ mAssociationStore = associationStore;
+
+ mAssociationStore.registerLocalListener(new AssociationStore.OnChangeListener() {
+ @Override
+ public void onAssociationChanged(int changeType, AssociationInfo association) {
+ final int userId = association.getUserId();
+ final List<AssociationInfo> updatedAssociations =
+ mAssociationStore.getActiveAssociationsByUser(userId);
+
+ updateAtm(userId, updatedAssociations);
+ }
+ });
+ }
+
+ /**
+ * Update ActivityManager and ActivityTaskManager exemptions
+ */
+ public void updateAtm(int userId, List<AssociationInfo> associations) {
+ final Set<Integer> companionAppUids = new ArraySet<>();
+ for (AssociationInfo association : associations) {
+ int uid = mPackageManager.getPackageUid(association.getPackageName(), 0, userId);
+ if (uid >= 0) {
+ companionAppUids.add(uid);
+ }
+ }
+ if (mAtmInternal != null) {
+ mAtmInternal.setCompanionAppUids(userId, companionAppUids);
+ }
+ if (mAmInternal != null) {
+ // Make a copy of the set and send it to ActivityManager.
+ mAmInternal.setCompanionAppUids(userId, new ArraySet<>(companionAppUids));
+ }
+ }
+
+ /**
+ * Update special access for the association's package
+ */
+ public void exemptPackage(int userId, String packageName, boolean hasPresentDevices) {
+ Slog.i(TAG, "Exempting package [" + packageName + "]...");
+
+ final PackageInfo packageInfo = getPackageInfo(mContext, userId, packageName);
+
+ Binder.withCleanCallingIdentity(
+ () -> exemptPackageAsSystem(userId, packageInfo, hasPresentDevices));
+ }
+
+ @SuppressLint("MissingPermission")
+ private void exemptPackageAsSystem(int userId, PackageInfo packageInfo,
+ boolean hasPresentDevices) {
+ if (packageInfo == null) {
+ return;
+ }
+
+ // If the app has run-in-bg permission and present devices, add it to power saver allowlist.
+ if (containsEither(packageInfo.requestedPermissions,
+ android.Manifest.permission.RUN_IN_BACKGROUND,
+ android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND)
+ && hasPresentDevices) {
+ mPowerExemptionManager.addToPermanentAllowList(packageInfo.packageName);
+ } else {
+ try {
+ mPowerExemptionManager.removeFromPermanentAllowList(packageInfo.packageName);
+ } catch (UnsupportedOperationException e) {
+ Slog.w(TAG, packageInfo.packageName + " can't be removed from power save"
+ + " allowlist. It might be due to the package being allowlisted by the"
+ + " system.");
+ }
+ }
+
+ // If the app has run-in-bg permission and present device, allow metered network use.
+ NetworkPolicyManager networkPolicyManager = NetworkPolicyManager.from(mContext);
+ try {
+ if (containsEither(packageInfo.requestedPermissions,
+ android.Manifest.permission.USE_DATA_IN_BACKGROUND,
+ android.Manifest.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND)
+ && hasPresentDevices) {
+ networkPolicyManager.addUidPolicy(
+ packageInfo.applicationInfo.uid,
+ NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+ } else {
+ networkPolicyManager.removeUidPolicy(
+ packageInfo.applicationInfo.uid,
+ NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+ }
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, e.getMessage());
+ }
+
+ updateAutoRevokeExemption(packageInfo.packageName, packageInfo.applicationInfo.uid,
+ !mAssociationStore.getActiveAssociationsByPackage(userId,
+ packageInfo.packageName).isEmpty());
+ }
+
+ /**
+ * Update auto revoke exemptions.
+ * If the app has any association, exempt it from permission auto revoke.
+ */
+ public void updateAutoRevokeExemptions() {
+ Slog.d(TAG, "maybeGrantAutoRevokeExemptions()");
+
+ PackageManager pm = mContext.getPackageManager();
+ for (int userId : LocalServices.getService(UserManagerInternal.class).getUserIds()) {
+ SharedPreferences pref = mContext.getSharedPreferences(
+ new File(Environment.getUserSystemDirectory(userId), PREF_FILE_NAME),
+ Context.MODE_PRIVATE);
+ if (pref.getBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, false)) {
+ continue;
+ }
+
+ try {
+ final List<AssociationInfo> associations =
+ mAssociationStore.getActiveAssociationsByUser(userId);
+ Set<Pair<String, Integer>> exemptedPackages = new HashSet<>();
+ for (AssociationInfo a : associations) {
+ try {
+ int uid = pm.getPackageUidAsUser(a.getPackageName(), userId);
+ exemptedPackages.add(new Pair<>(a.getPackageName(), uid));
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Unknown companion package: " + a.getPackageName(), e);
+ }
+ }
+ for (Pair<String, Integer> exemptedPackage : exemptedPackages) {
+ updateAutoRevokeExemption(exemptedPackage.first, exemptedPackage.second, true);
+ }
+ } finally {
+ pref.edit().putBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, true).apply();
+ }
+ }
+ }
+
+ @SuppressLint("MissingPermission")
+ private void updateAutoRevokeExemption(String packageName, int uid, boolean hasAssociations) {
+ try {
+ mAppOpsManager.setMode(
+ AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
+ uid,
+ packageName,
+ hasAssociations ? MODE_IGNORED : MODE_ALLOWED);
+ } catch (Exception e) {
+ Slog.e(TAG, "Error while granting auto revoke exemption for " + packageName, e);
+ }
+ }
+
+ private <T> boolean containsEither(T[] array, T a, T b) {
+ return ArrayUtils.contains(array, a) || ArrayUtils.contains(array, b);
+ }
+
+}
diff --git a/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java b/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java
index 60f4688..8307da5 100644
--- a/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java
@@ -95,7 +95,9 @@
/**
* On package changed.
*/
- public void onPackagesChanged(@UserIdInt int userId) {
+ public void onPackageChanged(@UserIdInt int userId) {
+ // Note: To invalidate the user space for simplicity. We could alternatively manage each
+ // package, but that would easily cause errors if one case is mis-handled.
mCompanionServicesRegister.invalidate(userId);
}
@@ -299,12 +301,14 @@
private class CompanionServicesRegister extends PerUser<Map<String, List<ComponentName>>> {
@Override
- public synchronized @NonNull Map<String, List<ComponentName>> forUser(
+ @NonNull
+ public synchronized Map<String, List<ComponentName>> forUser(
@UserIdInt int userId) {
return super.forUser(userId);
}
- synchronized @NonNull List<ComponentName> forPackage(
+ @NonNull
+ synchronized List<ComponentName> forPackage(
@UserIdInt int userId, @NonNull String packageName) {
return forUser(userId).getOrDefault(packageName, Collections.emptyList());
}
@@ -314,7 +318,8 @@
}
@Override
- protected final @NonNull Map<String, List<ComponentName>> create(@UserIdInt int userId) {
+ @NonNull
+ protected final Map<String, List<ComponentName>> create(@UserIdInt int userId) {
return PackageUtils.getCompanionServicesForUser(mContext, userId);
}
}
diff --git a/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java b/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java
index a374d27..7b4dd7d 100644
--- a/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java
@@ -57,6 +57,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.CollectionUtils;
+import com.android.server.companion.CompanionExemptionProcessor;
import com.android.server.companion.association.AssociationStore;
import java.io.PrintWriter;
@@ -101,6 +102,8 @@
private final PowerManagerInternal mPowerManagerInternal;
@NonNull
private final UserManager mUserManager;
+ @NonNull
+ private final CompanionExemptionProcessor mCompanionExemptionProcessor;
// NOTE: Same association may appear in more than one of the following sets at the same time.
// (E.g. self-managed devices that have MAC addresses, could be reported as present by their
@@ -111,7 +114,7 @@
@NonNull
private final Set<Integer> mNearbyBleDevices = new HashSet<>();
@NonNull
- private final Set<Integer> mReportedSelfManagedDevices = new HashSet<>();
+ private final Set<Integer> mConnectedSelfManagedDevices = new HashSet<>();
@NonNull
private final Set<ParcelUuid> mConnectedUuidDevices = new HashSet<>();
@NonNull
@@ -146,7 +149,8 @@
@NonNull UserManager userManager,
@NonNull AssociationStore associationStore,
@NonNull ObservableUuidStore observableUuidStore,
- @NonNull PowerManagerInternal powerManagerInternal) {
+ @NonNull PowerManagerInternal powerManagerInternal,
+ @NonNull CompanionExemptionProcessor companionExemptionProcessor) {
mContext = context;
mCompanionAppBinder = companionAppBinder;
mAssociationStore = associationStore;
@@ -156,6 +160,7 @@
mObservableUuidStore, this);
mBleDeviceProcessor = new BleDeviceProcessor(associationStore, this);
mPowerManagerInternal = powerManagerInternal;
+ mCompanionExemptionProcessor = companionExemptionProcessor;
}
/** Initialize {@link DevicePresenceProcessor} */
@@ -404,7 +409,7 @@
* nearby (for "self-managed" associations).
*/
public boolean isDevicePresent(int associationId) {
- return mReportedSelfManagedDevices.contains(associationId)
+ return mConnectedSelfManagedDevices.contains(associationId)
|| mConnectedBtDevices.contains(associationId)
|| mNearbyBleDevices.contains(associationId)
|| mSimulated.contains(associationId);
@@ -451,7 +456,7 @@
* notifyDeviceAppeared()}
*/
public void onSelfManagedDeviceConnected(int associationId) {
- onDevicePresenceEvent(mReportedSelfManagedDevices,
+ onDevicePresenceEvent(mConnectedSelfManagedDevices,
associationId, EVENT_SELF_MANAGED_APPEARED);
}
@@ -467,7 +472,7 @@
* notifyDeviceDisappeared()}
*/
public void onSelfManagedDeviceDisconnected(int associationId) {
- onDevicePresenceEvent(mReportedSelfManagedDevices,
+ onDevicePresenceEvent(mConnectedSelfManagedDevices,
associationId, EVENT_SELF_MANAGED_DISAPPEARED);
}
@@ -475,7 +480,7 @@
* Marks a "self-managed" device as disconnected when binderDied.
*/
public void onSelfManagedDeviceReporterBinderDied(int associationId) {
- onDevicePresenceEvent(mReportedSelfManagedDevices,
+ onDevicePresenceEvent(mConnectedSelfManagedDevices,
associationId, EVENT_SELF_MANAGED_DISAPPEARED);
}
@@ -683,6 +688,7 @@
if (association.shouldBindWhenPresent()) {
bindApplicationIfNeeded(userId, packageName, association.isSelfManaged());
+ mCompanionExemptionProcessor.exemptPackage(userId, packageName, true);
} else {
return;
}
@@ -715,6 +721,7 @@
// Check if there are other devices associated to the app that are present.
if (!shouldBindPackage(userId, packageName)) {
mCompanionAppBinder.unbindCompanionApp(userId, packageName);
+ mCompanionExemptionProcessor.exemptPackage(userId, packageName, false);
}
break;
default:
@@ -940,7 +947,7 @@
mConnectedBtDevices.remove(id);
mNearbyBleDevices.remove(id);
- mReportedSelfManagedDevices.remove(id);
+ mConnectedSelfManagedDevices.remove(id);
mSimulated.remove(id);
synchronized (mBtDisconnectedDevices) {
mBtDisconnectedDevices.remove(id);
@@ -1100,7 +1107,7 @@
out.append("Companion Device Present: ");
if (mConnectedBtDevices.isEmpty()
&& mNearbyBleDevices.isEmpty()
- && mReportedSelfManagedDevices.isEmpty()) {
+ && mConnectedSelfManagedDevices.isEmpty()) {
out.append("<empty>\n");
return;
} else {
@@ -1130,11 +1137,11 @@
}
out.append(" Self-Reported Devices: ");
- if (mReportedSelfManagedDevices.isEmpty()) {
+ if (mConnectedSelfManagedDevices.isEmpty()) {
out.append("<empty>\n");
} else {
out.append("\n");
- for (int associationId : mReportedSelfManagedDevices) {
+ for (int associationId : mConnectedSelfManagedDevices) {
AssociationInfo a = mAssociationStore.getAssociationById(associationId);
out.append(" ").append(a.toShortString()).append('\n');
}
diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
index ea6351b..fd18fa8 100644
--- a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
+++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
@@ -24,7 +24,8 @@
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
-import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
@@ -261,24 +262,28 @@
}
}
- private Intent getResolvedLaunchIntent() {
+ private Intent getResolvedLaunchIntent(int userId) {
synchronized (this) {
+ if(DEBUG_USER) Log.d(TAG, "Attempting to getResolvedLaunchIntent");
// If mTemporaryPackage is not null, use it to get the ContextualSearch intent.
String csPkgName = getContextualSearchPackageName();
if (csPkgName.isEmpty()) {
// Return null if csPackageName is not specified.
+ if (DEBUG_USER) Log.w(TAG, "getContextualSearchPackageName is empty");
return null;
}
Intent launchIntent = new Intent(
ContextualSearchManager.ACTION_LAUNCH_CONTEXTUAL_SEARCH);
launchIntent.setPackage(csPkgName);
- ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(
- launchIntent, MATCH_FACTORY_ONLY);
+ ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivityAsUser(
+ launchIntent, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
if (resolveInfo == null) {
+ if (DEBUG_USER) Log.w(TAG, "resolveInfo is null");
return null;
}
ComponentName componentName = resolveInfo.getComponentInfo().getComponentName();
if (componentName == null) {
+ if (DEBUG_USER) Log.w(TAG, "componentName is null");
return null;
}
launchIntent.setComponent(componentName);
@@ -286,9 +291,10 @@
}
}
- private Intent getContextualSearchIntent(int entrypoint, CallbackToken mToken) {
- final Intent launchIntent = getResolvedLaunchIntent();
+ private Intent getContextualSearchIntent(int entrypoint, int userId, CallbackToken mToken) {
+ final Intent launchIntent = getResolvedLaunchIntent(userId);
if (launchIntent == null) {
+ if (DEBUG_USER) Log.w(TAG, "Failed getContextualSearchIntent: launchIntent is null");
return null;
}
@@ -341,6 +347,7 @@
TYPE_NAVIGATION_BAR_PANEL,
TYPE_POINTER));
} else {
+ if (DEBUG_USER) Log.w(TAG, "Can't capture contextual screenshot: mWmInternal is null");
shb = null;
}
final Bitmap bm = shb != null ? shb.asBitmap() : null;
@@ -444,7 +451,7 @@
@Override
public void startContextualSearch(int entrypoint) {
synchronized (this) {
- if (DEBUG_USER) Log.d(TAG, "startContextualSearch");
+ if (DEBUG_USER) Log.d(TAG, "startContextualSearch entrypoint: " + entrypoint);
enforcePermission("startContextualSearch");
final int callingUserId = Binder.getCallingUserHandle().getIdentifier();
@@ -455,7 +462,8 @@
// server has READ_FRAME_BUFFER permission to get the screenshot and because only
// the system server can invoke non-exported activities.
Binder.withCleanCallingIdentity(() -> {
- Intent launchIntent = getContextualSearchIntent(entrypoint, mToken);
+ Intent launchIntent =
+ getContextualSearchIntent(entrypoint, callingUserId, mToken);
if (launchIntent != null) {
int result = invokeContextualSearchIntent(launchIntent, callingUserId);
if (DEBUG_USER) Log.d(TAG, "Launch result: " + result);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 6cfd44b..3ccad160 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -240,6 +240,7 @@
"aconfig_new_storage_flags_lib",
"powerstats_flags_lib",
"locksettings_flags_lib",
+ "profiling_flags_lib",
],
javac_shard_size: 50,
javacflags: [
@@ -255,6 +256,13 @@
"FlaggedApi",
],
},
+ jarjar_rules: ":services-jarjar-rules",
+ apex_available: ["//apex_available:platform"],
+}
+
+filegroup {
+ name: "services-jarjar-rules",
+ srcs: ["services-jarjar-rules.txt"],
}
java_genrule {
diff --git a/services/core/java/android/os/BatteryStatsInternal.java b/services/core/java/android/os/BatteryStatsInternal.java
index 60b826b..289935a 100644
--- a/services/core/java/android/os/BatteryStatsInternal.java
+++ b/services/core/java/android/os/BatteryStatsInternal.java
@@ -132,4 +132,7 @@
* @param uids the uids of all apps that have any alarm in this batch.
*/
public abstract void noteWakingAlarmBatch(long elapsedMillis, int... uids);
+
+ /** See PowerStatsUidResolver.mapUid(). */
+ public abstract int getOwnerUid(int uid);
}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 78bc658..3dcca14 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -22,6 +22,9 @@
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import static com.android.server.health.Utils.copyV1Battery;
+import static java.lang.Math.abs;
+
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
@@ -48,6 +51,7 @@
import android.os.Handler;
import android.os.IBatteryPropertiesRegistrar;
import android.os.IBinder;
+import android.os.Looper;
import android.os.OsProtoEnums;
import android.os.PowerManager;
import android.os.RemoteException;
@@ -67,6 +71,7 @@
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.SomeArgs;
@@ -84,6 +89,7 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.NoSuchElementException;
+import java.util.Objects;
import java.util.concurrent.CopyOnWriteArraySet;
/**
@@ -149,19 +155,112 @@
private HealthInfo mHealthInfo;
private final HealthInfo mLastHealthInfo = new HealthInfo();
private boolean mBatteryLevelCritical;
- private int mLastBatteryStatus;
- private int mLastBatteryHealth;
- private boolean mLastBatteryPresent;
- private int mLastBatteryLevel;
- private int mLastBatteryVoltage;
- private int mLastBatteryTemperature;
- private boolean mLastBatteryLevelCritical;
- private int mLastMaxChargingCurrent;
- private int mLastMaxChargingVoltage;
- private int mLastChargeCounter;
- private int mLastBatteryCycleCount;
- private int mLastChargingState;
- private int mLastBatteryCapacityLevel;
+
+ /**
+ * {@link HealthInfo#batteryStatus} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastBatteryStatus;
+ /**
+ * {@link HealthInfo#batteryHealth} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastBatteryHealth;
+ /**
+ * {@link HealthInfo#batteryPresent} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private boolean mLastBroadcastBatteryPresent;
+ /**
+ * {@link HealthInfo#batteryLevel} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastBatteryLevel;
+ /**
+ * {@link HealthInfo#batteryVoltageMillivolts} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastBatteryVoltage;
+ /**
+ * {@link HealthInfo#batteryTemperatureTenthsCelsius} value when
+ * {@link Intent#ACTION_BATTERY_CHANGED} broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastBatteryTemperature;
+ /**
+ * {@link #mBatteryLevelCritical} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: These values may be used for internal operations and/or to determine whether to trigger
+ * the broadcast or not.
+ */
+ private boolean mLastBroadcastBatteryLevelCritical;
+ /**
+ * {@link HealthInfo#maxChargingCurrentMicroamps} value when
+ * {@link Intent#ACTION_BATTERY_CHANGED} broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastMaxChargingCurrent;
+ /**
+ * {@link HealthInfo#maxChargingVoltageMicrovolts} value when
+ * {@link Intent#ACTION_BATTERY_CHANGED} broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastMaxChargingVoltage;
+ /**
+ * {@link HealthInfo#batteryChargeCounterUah} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastChargeCounter;
+ /**
+ * {@link HealthInfo#batteryCycleCount} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastBatteryCycleCount;
+ /**
+ * {@link HealthInfo#chargingState} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastChargingState;
+ /**
+ * {@link HealthInfo#batteryCapacityLevel} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: This value may be used for internal operations and/or to determine whether to trigger
+ * the {@link Intent#ACTION_BATTERY_CHANGED} broadcast or not.
+ */
+ private int mLastBroadcastBatteryCapacityLevel;
+ /**
+ * {@link #mPlugType} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: These values may be used for internal operations and/or to determine whether to trigger
+ * the broadcast or not.
+ */
+ private int mLastBroadcastPlugType = -1; // Extra state so we can detect first run
+ /**
+ * {@link #mInvalidCharger} value when {@link Intent#ACTION_BATTERY_CHANGED}
+ * broadcast was sent last.
+ * Note: These values may be used for internal operations and/or to determine whether to trigger
+ * the broadcast or not.
+ */
+ private int mLastBroadcastInvalidCharger;
/**
* The last seen charging policy. This requires the
* {@link android.Manifest.permission#BATTERY_STATS} permission and should therefore not be
@@ -172,7 +271,6 @@
private int mSequence = 1;
private int mInvalidCharger;
- private int mLastInvalidCharger;
private int mLowBatteryWarningLevel;
private int mLastLowBatteryWarningLevel;
@@ -184,7 +282,6 @@
private static String sSystemUiPackage;
private int mPlugType;
- private int mLastPlugType = -1; // Extra state so we can detect first run
private boolean mBatteryLevelLow;
@@ -197,6 +294,16 @@
private boolean mUpdatesStopped;
private boolean mBatteryInputSuspended;
+ /**
+ * Time when the voltage was updated last by HAL and we sent the
+ * {@link Intent#ACTION_BATTERY_CHANGED} broadcast.
+ * Note: This value is used to rate limit the {@link Intent#ACTION_BATTERY_CHANGED} broadcast
+ * so it is possible that voltage was updated but we did not send the broadcast so in that
+ * case we do not update the time.
+ */
+ @VisibleForTesting
+ public long mLastBroadcastVoltageUpdateTime;
+
private Led mLed;
private boolean mSentLowBatteryBroadcast = false;
@@ -211,7 +318,8 @@
private final CopyOnWriteArraySet<BatteryManagerInternal.ChargingPolicyChangeListener>
mChargingPolicyChangeListeners = new CopyOnWriteArraySet<>();
- private static final Bundle BATTERY_CHANGED_OPTIONS = BroadcastOptions.makeBasic()
+ @VisibleForTesting
+ public static final Bundle BATTERY_CHANGED_OPTIONS = BroadcastOptions.makeBasic()
.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE)
.toBundle();
@@ -234,6 +342,25 @@
private static final int MSG_BROADCAST_POWER_CONNECTION_CHANGED = 2;
private static final int MSG_BROADCAST_BATTERY_LOW_OKAY = 3;
+ /**
+ * This value is used to rate limit the {@link Intent#ACTION_BATTERY_CHANGED} broadcast. We
+ * only send the broadcast and update the temperature value when the temp change is greater or
+ * equals to 1 degree celsius.
+ */
+ private static final int ABSOLUTE_DECI_CELSIUS_DIFF_FOR_TEMP_UPDATE = 10;
+ /**
+ * This value is used to rate limit the {@link Intent#ACTION_BATTERY_CHANGED} broadcast. We
+ * only send the broadcast if the last voltage was updated at least 20s seconds back and has a
+ * fluctuation of at least 1%.
+ */
+ private static final int TIME_DIFF_FOR_VOLTAGE_UPDATE_MS = 20000;
+ /**
+ * The value is used to rate limit the {@link Intent#ACTION_BATTERY_CHANGED} broadcast. We
+ * only send the broadcast if the last voltage was updated at least 20s seconds back and has a
+ * fluctuation of at least 1%.
+ */
+ private static final float BASE_POINT_DIFF_FOR_VOLTAGE_UPDATE = 0.01f;
+
private final Handler.Callback mLocalCallback = msg -> {
switch (msg.what) {
case MSG_BROADCAST_BATTERY_CHANGED: {
@@ -283,10 +410,19 @@
};
public BatteryService(Context context) {
+ this(context, Objects.requireNonNull(Looper.myLooper(),
+ "BatteryService uses handler!! Can't create handler inside thread that has not "
+ + "called Looper.prepare()"));
+ }
+
+ @VisibleForTesting
+ public BatteryService(Context context, @NonNull Looper looper) {
super(context);
+ Objects.requireNonNull(looper);
+
mContext = context;
- mHandler = new Handler(mLocalCallback, true /*async*/);
+ mHandler = new Handler(looper, mLocalCallback, true /*async*/);
mLed = new Led(context, getLocalService(LightsManager.class));
mBatteryStats = BatteryStatsService.getService();
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
@@ -436,7 +572,7 @@
private boolean shouldSendBatteryLowLocked() {
final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;
- final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;
+ final boolean oldPlugged = mLastBroadcastPlugType != BATTERY_PLUGGED_NONE;
/* The ACTION_BATTERY_LOW broadcast is sent in these situations:
* - is just un-plugged (previously was plugged) and battery level is
@@ -447,7 +583,7 @@
return !plugged
&& mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
&& mHealthInfo.batteryLevel <= mLowBatteryWarningLevel
- && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel
+ && (oldPlugged || mLastBroadcastBatteryLevel > mLowBatteryWarningLevel
|| mHealthInfo.batteryLevel > mLastLowBatteryWarningLevel);
}
@@ -515,7 +651,13 @@
}
}
- private void update(android.hardware.health.HealthInfo info) {
+ /**
+ * Updates the healthInfo and triggers the broadcast.
+ *
+ * @param info the new health info
+ */
+ @VisibleForTesting
+ public void update(android.hardware.health.HealthInfo info) {
traceBegin("HealthInfoUpdate");
Trace.traceCounter(
@@ -556,8 +698,8 @@
long dischargeDuration = 0;
mBatteryLevelCritical =
- mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
- && mHealthInfo.batteryLevel <= mCriticalBatteryLevel;
+ mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
+ && mHealthInfo.batteryLevel <= mCriticalBatteryLevel;
mPlugType = plugType(mHealthInfo);
if (DEBUG) {
@@ -591,24 +733,28 @@
mHandler.post(this::notifyChargingPolicyChanged);
}
- if (force
- || (mHealthInfo.batteryStatus != mLastBatteryStatus
- || mHealthInfo.batteryHealth != mLastBatteryHealth
- || mHealthInfo.batteryPresent != mLastBatteryPresent
- || mHealthInfo.batteryLevel != mLastBatteryLevel
- || mPlugType != mLastPlugType
- || mHealthInfo.batteryVoltageMillivolts != mLastBatteryVoltage
- || mHealthInfo.batteryTemperatureTenthsCelsius != mLastBatteryTemperature
- || mHealthInfo.maxChargingCurrentMicroamps != mLastMaxChargingCurrent
- || mHealthInfo.maxChargingVoltageMicrovolts != mLastMaxChargingVoltage
- || mHealthInfo.batteryChargeCounterUah != mLastChargeCounter
- || mInvalidCharger != mLastInvalidCharger
- || mHealthInfo.batteryCycleCount != mLastBatteryCycleCount
- || mHealthInfo.chargingState != mLastChargingState
- || mHealthInfo.batteryCapacityLevel != mLastBatteryCapacityLevel)) {
+ final boolean includeChargeCounter =
+ !com.android.server.flags.Flags.rateLimitBatteryChangedBroadcast()
+ && mHealthInfo.batteryChargeCounterUah != mLastBroadcastChargeCounter;
- if (mPlugType != mLastPlugType) {
- if (mLastPlugType == BATTERY_PLUGGED_NONE) {
+ if (force
+ || (mHealthInfo.batteryStatus != mLastBroadcastBatteryStatus
+ || mHealthInfo.batteryHealth != mLastBroadcastBatteryHealth
+ || mHealthInfo.batteryPresent != mLastBroadcastBatteryPresent
+ || mHealthInfo.batteryLevel != mLastBroadcastBatteryLevel
+ || mPlugType != mLastBroadcastPlugType
+ || mHealthInfo.batteryVoltageMillivolts != mLastBroadcastBatteryVoltage
+ || mHealthInfo.batteryTemperatureTenthsCelsius != mLastBroadcastBatteryTemperature
+ || mHealthInfo.maxChargingCurrentMicroamps != mLastBroadcastMaxChargingCurrent
+ || mHealthInfo.maxChargingVoltageMicrovolts != mLastBroadcastMaxChargingVoltage
+ || includeChargeCounter
+ || mInvalidCharger != mLastBroadcastInvalidCharger
+ || mHealthInfo.batteryCycleCount != mLastBroadcastBatteryCycleCount
+ || mHealthInfo.chargingState != mLastBroadcastChargingState
+ || mHealthInfo.batteryCapacityLevel != mLastBroadcastBatteryCapacityLevel)) {
+
+ if (mPlugType != mLastBroadcastPlugType) {
+ if (mLastBroadcastPlugType == BATTERY_PLUGGED_NONE) {
// discharging -> charging
mChargeStartLevel = mHealthInfo.batteryLevel;
mChargeStartTime = SystemClock.elapsedRealtime();
@@ -622,7 +768,8 @@
// There's no value in this data unless we've discharged at least once and the
// battery level has changed; so don't log until it does.
- if (mDischargeStartTime != 0 && mDischargeStartLevel != mHealthInfo.batteryLevel) {
+ if (mDischargeStartTime != 0
+ && mDischargeStartLevel != mHealthInfo.batteryLevel) {
dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
logOutlier = true;
EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration,
@@ -639,7 +786,7 @@
if (mChargeStartTime != 0 && chargeDuration != 0) {
final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE);
builder.setType(MetricsEvent.TYPE_DISMISS);
- builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mLastPlugType);
+ builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mLastBroadcastPlugType);
builder.addTaggedData(MetricsEvent.FIELD_CHARGING_DURATION_MILLIS,
chargeDuration);
builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START,
@@ -651,19 +798,20 @@
mChargeStartTime = 0;
}
}
- if (mHealthInfo.batteryStatus != mLastBatteryStatus ||
- mHealthInfo.batteryHealth != mLastBatteryHealth ||
- mHealthInfo.batteryPresent != mLastBatteryPresent ||
- mPlugType != mLastPlugType) {
+ if (mHealthInfo.batteryStatus != mLastBroadcastBatteryStatus
+ || mHealthInfo.batteryHealth != mLastBroadcastBatteryHealth
+ || mHealthInfo.batteryPresent != mLastBroadcastBatteryPresent
+ || mPlugType != mLastBroadcastPlugType) {
EventLog.writeEvent(EventLogTags.BATTERY_STATUS,
- mHealthInfo.batteryStatus, mHealthInfo.batteryHealth, mHealthInfo.batteryPresent ? 1 : 0,
+ mHealthInfo.batteryStatus, mHealthInfo.batteryHealth,
+ mHealthInfo.batteryPresent ? 1 : 0,
mPlugType, mHealthInfo.batteryTechnology);
SystemProperties.set(
"debug.tracing.battery_status",
Integer.toString(mHealthInfo.batteryStatus));
SystemProperties.set("debug.tracing.plug_type", Integer.toString(mPlugType));
}
- if (mHealthInfo.batteryLevel != mLastBatteryLevel) {
+ if (mHealthInfo.batteryLevel != mLastBroadcastBatteryLevel) {
// Don't do this just from voltage or temperature changes, that is
// too noisy.
EventLog.writeEvent(
@@ -672,8 +820,8 @@
mHealthInfo.batteryVoltageMillivolts,
mHealthInfo.batteryTemperatureTenthsCelsius);
}
- if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
- mPlugType == BATTERY_PLUGGED_NONE) {
+ if (mBatteryLevelCritical && !mLastBroadcastBatteryLevelCritical
+ && mPlugType == BATTERY_PLUGGED_NONE) {
// We want to make sure we log discharge cycle outliers
// if the battery is about to die.
dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
@@ -684,7 +832,7 @@
// Should we now switch in to low battery mode?
if (mPlugType == BATTERY_PLUGGED_NONE
&& mHealthInfo.batteryStatus !=
- BatteryManager.BATTERY_STATUS_UNKNOWN
+ BatteryManager.BATTERY_STATUS_UNKNOWN
&& mHealthInfo.batteryLevel <= mLowBatteryWarningLevel) {
mBatteryLevelLow = true;
}
@@ -692,7 +840,7 @@
// Should we now switch out of low battery mode?
if (mPlugType != BATTERY_PLUGGED_NONE) {
mBatteryLevelLow = false;
- } else if (mHealthInfo.batteryLevel >= mLowBatteryCloseWarningLevel) {
+ } else if (mHealthInfo.batteryLevel >= mLowBatteryCloseWarningLevel) {
mBatteryLevelLow = false;
} else if (force && mHealthInfo.batteryLevel >= mLowBatteryWarningLevel) {
// If being forced, the previous state doesn't matter, we will just
@@ -706,7 +854,7 @@
// Separate broadcast is sent for power connected / not connected
// since the standard intent will not wake any applications and some
// applications may want to have smart behavior based on this.
- if (mPlugType != 0 && mLastPlugType == 0) {
+ if (mPlugType != 0 && mLastBroadcastPlugType == 0) {
final Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
@@ -726,8 +874,7 @@
}
});
}
- }
- else if (mPlugType == 0 && mLastPlugType != 0) {
+ } else if (mPlugType == 0 && mLastBroadcastPlugType != 0) {
final Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
@@ -797,8 +944,14 @@
// We are doing this after sending the above broadcasts, so anything processing
// them will get the new sequence number at that point. (See for example how testing
// of JobScheduler's BatteryController works.)
- sendBatteryChangedIntentLocked(force);
- if (mLastBatteryLevel != mHealthInfo.batteryLevel || mLastPlugType != mPlugType) {
+
+ boolean rateLimitBatteryChangedBroadcast = rateLimitBatteryChangedBroadcast(force);
+
+ if (!rateLimitBatteryChangedBroadcast) {
+ sendBatteryChangedIntentLocked(force);
+ }
+ if (mLastBroadcastBatteryLevel != mHealthInfo.batteryLevel
+ || mLastBroadcastPlugType != mPlugType) {
sendBatteryLevelChangedIntentLocked();
}
@@ -811,21 +964,24 @@
logOutlierLocked(dischargeDuration);
}
- mLastBatteryStatus = mHealthInfo.batteryStatus;
- mLastBatteryHealth = mHealthInfo.batteryHealth;
- mLastBatteryPresent = mHealthInfo.batteryPresent;
- mLastBatteryLevel = mHealthInfo.batteryLevel;
- mLastPlugType = mPlugType;
- mLastBatteryVoltage = mHealthInfo.batteryVoltageMillivolts;
- mLastBatteryTemperature = mHealthInfo.batteryTemperatureTenthsCelsius;
- mLastMaxChargingCurrent = mHealthInfo.maxChargingCurrentMicroamps;
- mLastMaxChargingVoltage = mHealthInfo.maxChargingVoltageMicrovolts;
- mLastChargeCounter = mHealthInfo.batteryChargeCounterUah;
- mLastBatteryLevelCritical = mBatteryLevelCritical;
- mLastInvalidCharger = mInvalidCharger;
- mLastBatteryCycleCount = mHealthInfo.batteryCycleCount;
- mLastChargingState = mHealthInfo.chargingState;
- mLastBatteryCapacityLevel = mHealthInfo.batteryCapacityLevel;
+ // Only update the values when we send the broadcast
+ if (!rateLimitBatteryChangedBroadcast) {
+ mLastBroadcastBatteryStatus = mHealthInfo.batteryStatus;
+ mLastBroadcastBatteryHealth = mHealthInfo.batteryHealth;
+ mLastBroadcastBatteryPresent = mHealthInfo.batteryPresent;
+ mLastBroadcastBatteryLevel = mHealthInfo.batteryLevel;
+ mLastBroadcastPlugType = mPlugType;
+ mLastBroadcastBatteryVoltage = mHealthInfo.batteryVoltageMillivolts;
+ mLastBroadcastBatteryTemperature = mHealthInfo.batteryTemperatureTenthsCelsius;
+ mLastBroadcastMaxChargingCurrent = mHealthInfo.maxChargingCurrentMicroamps;
+ mLastBroadcastMaxChargingVoltage = mHealthInfo.maxChargingVoltageMicrovolts;
+ mLastBroadcastChargeCounter = mHealthInfo.batteryChargeCounterUah;
+ mLastBroadcastBatteryLevelCritical = mBatteryLevelCritical;
+ mLastBroadcastInvalidCharger = mInvalidCharger;
+ mLastBroadcastBatteryCycleCount = mHealthInfo.batteryCycleCount;
+ mLastBroadcastChargingState = mHealthInfo.chargingState;
+ mLastBroadcastBatteryCapacityLevel = mHealthInfo.batteryCapacityLevel;
+ }
}
}
@@ -1089,6 +1245,74 @@
}
}
+ /**
+ * Rate limit's the broadcast based on the changes in temp, voltage and chargeCounter.
+ */
+ private boolean rateLimitBatteryChangedBroadcast(boolean forceUpdate) {
+ if (!com.android.server.flags.Flags.rateLimitBatteryChangedBroadcast()) {
+ return false;
+ }
+ if (mLastBroadcastBatteryVoltage == 0 || mLastBroadcastBatteryTemperature == 0) {
+ mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime();
+ return false;
+ }
+
+ final boolean voltageUpdated =
+ mLastBroadcastBatteryVoltage != mHealthInfo.batteryVoltageMillivolts;
+ final boolean temperatureUpdated =
+ mLastBroadcastBatteryTemperature != mHealthInfo.batteryTemperatureTenthsCelsius;
+ final boolean otherStatesUpdated = forceUpdate
+ || mHealthInfo.batteryStatus != mLastBroadcastBatteryStatus
+ || mHealthInfo.batteryHealth != mLastBroadcastBatteryHealth
+ || mHealthInfo.batteryPresent != mLastBroadcastBatteryPresent
+ || mHealthInfo.batteryLevel != mLastBroadcastBatteryLevel
+ || mPlugType != mLastBroadcastPlugType
+ || mHealthInfo.maxChargingCurrentMicroamps != mLastBroadcastMaxChargingCurrent
+ || mHealthInfo.maxChargingVoltageMicrovolts != mLastBroadcastMaxChargingVoltage
+ || mInvalidCharger != mLastBroadcastInvalidCharger
+ || mHealthInfo.batteryCycleCount != mLastBroadcastBatteryCycleCount
+ || mHealthInfo.chargingState != mLastBroadcastChargingState
+ || mHealthInfo.batteryCapacityLevel != mLastBroadcastBatteryCapacityLevel;
+
+ // We only rate limit based on changes in the temp, voltage.
+ if (otherStatesUpdated) {
+
+ if (voltageUpdated) {
+ mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime();
+ }
+ return false;
+ }
+
+ final float basePointDiff =
+ (float) (mLastBroadcastBatteryVoltage - mHealthInfo.batteryVoltageMillivolts)
+ / mLastBroadcastBatteryVoltage;
+
+ // We only send the broadcast if voltage change is greater than 1% and last voltage
+ // update was sent at least 20 seconds back.
+ if (voltageUpdated
+ && abs(basePointDiff) >= BASE_POINT_DIFF_FOR_VOLTAGE_UPDATE
+ && SystemClock.elapsedRealtime() - mLastBroadcastVoltageUpdateTime
+ >= TIME_DIFF_FOR_VOLTAGE_UPDATE_MS) {
+ mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime();
+
+ return false;
+ }
+
+ // Only send the broadcast if the temperature update is greater than 1 degree celsius.
+ if (temperatureUpdated
+ && abs(
+ mLastBroadcastBatteryTemperature - mHealthInfo.batteryTemperatureTenthsCelsius)
+ >= ABSOLUTE_DECI_CELSIUS_DIFF_FOR_TEMP_UPDATE) {
+
+ if (voltageUpdated) {
+ mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime();
+ }
+ return false;
+ }
+
+ return true;
+ }
+
class Shell extends ShellCommand {
@Override
public int onCommand(String cmd) {
@@ -1399,6 +1623,10 @@
pw.println(" level: " + mHealthInfo.batteryLevel);
pw.println(" scale: " + BATTERY_SCALE);
pw.println(" voltage: " + mHealthInfo.batteryVoltageMillivolts);
+ pw.println(" Time when the latest updated value of the voltage was sent via "
+ + "battery changed broadcast: " + mLastBroadcastVoltageUpdateTime);
+ pw.println(" The last voltage value sent via the battery changed broadcast: "
+ + mLastBroadcastBatteryVoltage);
pw.println(" temperature: " + mHealthInfo.batteryTemperatureTenthsCelsius);
pw.println(" technology: " + mHealthInfo.batteryTechnology);
pw.println(" Charging state: " + mHealthInfo.chargingState);
@@ -1457,6 +1685,11 @@
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
+ @VisibleForTesting
+ public Handler getHandlerForTest() {
+ return mHandler;
+ }
+
@SuppressLint("AndroidFrameworkRequiresPermission")
private static void sendBroadcastToAllUsers(Context context, Intent intent,
Bundle options) {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 9d27731..b7bc4e4 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -96,6 +96,7 @@
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.ParcelableException;
+import android.os.PermissionEnforcer;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteCallbackList;
@@ -3653,10 +3654,16 @@
return mInternalStorageSize;
}
- @EnforcePermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@Override
public int getInternalStorageRemainingLifetime() throws RemoteException {
- super.getInternalStorageRemainingLifetime_enforcePermission();
+ PermissionEnforcer.fromContext(mContext)
+ .enforcePermissionAnyOf(
+ new String[] {
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+ android.Manifest.permission.ALLOCATE_AGGRESSIVE
+ },
+ getCallingPid(),
+ getCallingUid());
return mVold.getStorageRemainingLifetime();
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3e7bcb8..0826c53 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -337,6 +337,8 @@
import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
import android.os.Process;
+import android.os.ProfilingServiceHelper;
+import android.os.ProfilingTrigger;
import android.os.RemoteCallback;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -1089,7 +1091,18 @@
@Override
public void onReportFullyDrawn(long id, long timestampNanos) {
- mProcessList.getAppStartInfoTracker().onActivityReportFullyDrawn(id, timestampNanos);
+ ApplicationStartInfo startInfo = mProcessList.getAppStartInfoTracker()
+ .onActivityReportFullyDrawn(id, timestampNanos);
+
+ if (android.os.profiling.Flags.systemTriggeredProfilingNew()
+ && startInfo != null
+ && startInfo.getStartType() == ApplicationStartInfo.START_TYPE_COLD
+ && startInfo.getPackageName() != null) {
+ ProfilingServiceHelper.getInstance().onProfilingTriggerOccurred(
+ startInfo.getRealUid(),
+ startInfo.getPackageName(),
+ ProfilingTrigger.TRIGGER_TYPE_APP_FULLY_DRAWN);
+ }
}
};
@@ -11337,7 +11350,9 @@
}
pw.println(" mFgsStartTempAllowList:");
final long currentTimeNow = System.currentTimeMillis();
- final long elapsedRealtimeNow = SystemClock.elapsedRealtime();
+ final long tempAllowlistCurrentTime =
+ com.android.server.deviceidle.Flags.useCpuTimeForTempAllowlist()
+ ? SystemClock.uptimeMillis() : SystemClock.elapsedRealtime();
mFgsStartTempAllowList.forEach((uid, entry) -> {
pw.print(" " + UserHandle.formatUid(uid) + ": ");
entry.second.dump(pw);
@@ -11345,7 +11360,7 @@
// Convert entry.mExpirationTime, which is an elapsed time since boot,
// to a time since epoch (i.e. System.currentTimeMillis()-based time.)
final long expirationInCurrentTime =
- currentTimeNow - elapsedRealtimeNow + entry.first;
+ currentTimeNow - tempAllowlistCurrentTime + entry.first;
TimeUtils.dumpTimeWithDelta(pw, expirationInCurrentTime, currentTimeNow);
pw.println();
});
diff --git a/services/core/java/com/android/server/am/AnrHelper.java b/services/core/java/com/android/server/am/AnrHelper.java
index 9fc0bf9..6d594ac 100644
--- a/services/core/java/com/android/server/am/AnrHelper.java
+++ b/services/core/java/com/android/server/am/AnrHelper.java
@@ -20,7 +20,8 @@
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import android.content.pm.ApplicationInfo;
-import android.os.Process;
+import android.os.ProfilingServiceHelper;
+import android.os.ProfilingTrigger;
import android.os.SystemClock;
import android.os.Trace;
import android.util.ArraySet;
@@ -240,6 +241,15 @@
|| startTime < SELF_ONLY_AFTER_BOOT_MS;
r.appNotResponding(onlyDumpSelf);
final long endTime = SystemClock.uptimeMillis();
+
+ if (android.os.profiling.Flags.systemTriggeredProfilingNew() && r.mAppInfo != null
+ && r.mAppInfo.packageName != null) {
+ ProfilingServiceHelper.getInstance().onProfilingTriggerOccurred(
+ r.mUid,
+ r.mAppInfo.packageName,
+ ProfilingTrigger.TRIGGER_TYPE_ANR);
+ }
+
Slog.d(TAG, "Completed ANR of " + r.mApp.processName + " in "
+ (endTime - startTime) + "ms, latency " + reportLatency
+ (onlyDumpSelf ? "ms (expired, only dump ANR app)" : "ms"));
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index aca6d0b..3913d2f 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -22,6 +22,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ApplicationStartInfo;
import android.app.Flags;
import android.app.IApplicationStartInfoCompleteListener;
@@ -419,23 +420,25 @@
* Should only be called for Activity launch sequences from an instance of
* {@link ActivityMetricsLaunchObserver}.
*/
- void onActivityReportFullyDrawn(long id, long timestampNanos) {
+ @Nullable
+ ApplicationStartInfo onActivityReportFullyDrawn(long id, long timestampNanos) {
synchronized (mLock) {
if (!mEnabled) {
- return;
+ return null;
}
int index = mInProgressRecords.indexOfKey(id);
if (index < 0) {
- return;
+ return null;
}
ApplicationStartInfo info = mInProgressRecords.valueAt(index);
if (info == null) {
mInProgressRecords.removeAt(index);
- return;
+ return null;
}
info.addStartupTimestamp(ApplicationStartInfo.START_TIMESTAMP_FULLY_DRAWN,
timestampNanos);
mInProgressRecords.removeAt(index);
+ return info;
}
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 7c563ab..aa9ac6c 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -453,7 +453,8 @@
com.android.internal.R.integer.config_accumulatedBatteryUsageStatsSpanSize);
mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context,
mPowerAttributor, mPowerProfile, mCpuScalingPolicies,
- mPowerStatsStore, accumulatedBatteryUsageStatsSpanSize, Clock.SYSTEM_CLOCK);
+ mPowerStatsStore, accumulatedBatteryUsageStatsSpanSize, Clock.SYSTEM_CLOCK,
+ mMonotonicClock);
mDumpHelper = new BatteryStatsDumpHelperImpl(mBatteryUsageStatsProvider);
mCpuWakeupStats = new CpuWakeupStats(context, R.xml.irq_device_map, mHandler);
mConfigFile = new AtomicFile(new File(systemDir, "battery_usage_stats_config"));
@@ -759,6 +760,14 @@
public void noteWakingAlarmBatch(long elapsedMillis, int... uids) {
noteCpuWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM, elapsedMillis, uids);
}
+
+ @Override
+ public int getOwnerUid(int uid) {
+ if (Process.isSdkSandboxUid(uid)) {
+ return Process.getAppUidForSdkSandboxUid(uid);
+ }
+ return mPowerStatsUidResolver.mapUid(uid);
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/FgsTempAllowList.java b/services/core/java/com/android/server/am/FgsTempAllowList.java
index c286556..5569b6d 100644
--- a/services/core/java/com/android/server/am/FgsTempAllowList.java
+++ b/services/core/java/com/android/server/am/FgsTempAllowList.java
@@ -29,7 +29,7 @@
/**
* List of keys that have expiration time.
- * If the expiration time is less than current elapsedRealtime, the key has expired.
+ * If the expiration time is less than current uptime, the key has expired.
* Otherwise it is valid (or allowed).
*
* <p>This is used for both FGS-BG-start restriction, and FGS-while-in-use permissions check.</p>
@@ -42,7 +42,7 @@
private static final int DEFAULT_MAX_SIZE = 100;
/**
- * The value is Pair type, Pair.first is the expirationTime(an elapsedRealtime),
+ * The value is Pair type, Pair.first is the expirationTime(in cpu uptime),
* Pair.second is the optional information entry about this key.
*/
private final SparseArray<Pair<Long, E>> mTempAllowList = new SparseArray<>();
@@ -82,7 +82,9 @@
}
// The temp allowlist should be a short list with only a few entries in it.
// for a very large list, HashMap structure should be used.
- final long now = SystemClock.elapsedRealtime();
+ final long now = com.android.server.deviceidle.Flags.useCpuTimeForTempAllowlist()
+ ? SystemClock.uptimeMillis()
+ : SystemClock.elapsedRealtime();
final int size = mTempAllowList.size();
if (size > mMaxSize) {
Slog.w(TAG_AM, "FgsTempAllowList length:" + size + " exceeds maxSize"
@@ -112,12 +114,15 @@
final int index = mTempAllowList.indexOfKey(uid);
if (index < 0) {
return null;
- } else if (mTempAllowList.valueAt(index).first < SystemClock.elapsedRealtime()) {
+ }
+ final long timeNow = com.android.server.deviceidle.Flags.useCpuTimeForTempAllowlist()
+ ? SystemClock.uptimeMillis()
+ : SystemClock.elapsedRealtime();
+ if (mTempAllowList.valueAt(index).first < timeNow) {
mTempAllowList.removeAt(index);
return null;
- } else {
- return mTempAllowList.valueAt(index);
}
+ return mTempAllowList.valueAt(index);
}
}
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index c1d5597..ab7cd5f 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -63,6 +63,9 @@
per-file SettingsToPropertiesMapper.java = omakoto@google.com, yamasani@google.com, dzshen@google.com, zhidou@google.com, tedbauer@google.com
per-file CarUserSwitchingDialog.java = file:platform/packages/services/Car:/OWNERS
+# Activity Security
+per-file ActivityManager* = file:/ACTIVITY_SECURITY_OWNERS
+
# Londoners
michaelwr@google.com #{LAST_RESORT_SUGGESTION}
narayan@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 08632fe..c067662 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -514,27 +514,11 @@
mLogger = new OomAdjusterDebugLogger(this, mService.mConstants);
mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> {
- final int pid = msg.arg1;
- final int group = msg.arg2;
- if (pid == ActivityManagerService.MY_PID) {
- // Skip setting the process group for system_server, keep it as default.
- return true;
- }
- final boolean traceEnabled = Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- if (traceEnabled) {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setProcessGroup "
- + msg.obj + " to " + group);
- }
- try {
- android.os.Process.setProcessGroup(pid, group);
- } catch (Exception e) {
- if (DEBUG_ALL) {
- Slog.w(TAG, "Failed setting process group of " + pid + " to " + group, e);
- }
- } finally {
- if (traceEnabled) {
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- }
+ final int group = msg.what;
+ final ProcessRecord app = (ProcessRecord) msg.obj;
+ setProcessGroup(app.getPid(), group, app.processName);
+ if (Flags.phantomProcessesFix()) {
+ mService.mPhantomProcessList.setProcessGroupForPhantomProcessOfApp(app, group);
}
return true;
});
@@ -545,8 +529,31 @@
}
void setProcessGroup(int pid, int group, String processName) {
+ if (pid == ActivityManagerService.MY_PID) {
+ // Skip setting the process group for system_server, keep it as default.
+ return;
+ }
+ final boolean traceEnabled = Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ if (traceEnabled) {
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setProcessGroup "
+ + processName + " to " + group);
+ }
+ try {
+ android.os.Process.setProcessGroup(pid, group);
+ } catch (Exception e) {
+ if (DEBUG_ALL) {
+ Slog.w(TAG, "Failed setting process group of " + pid + " to " + group, e);
+ }
+ } finally {
+ if (traceEnabled) {
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ }
+ }
+ }
+
+ void setAppAndChildProcessGroup(ProcessRecord app, int group) {
mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage(
- 0 /* unused */, pid, group, processName));
+ group, app));
}
void initSettings() {
@@ -3503,8 +3510,7 @@
processGroup = THREAD_GROUP_DEFAULT;
break;
}
- setProcessGroup(app.getPid(), processGroup, app.processName);
- mService.mPhantomProcessList.setProcessGroupForPhantomProcessOfApp(app, processGroup);
+ setAppAndChildProcessGroup(app, processGroup);
try {
final int renderThreadTid = app.getRenderThreadTid();
if (curSchedGroup == SCHED_GROUP_TOP_APP) {
diff --git a/services/core/java/com/android/server/am/PhantomProcessList.java b/services/core/java/com/android/server/am/PhantomProcessList.java
index bfdced7..123780f 100644
--- a/services/core/java/com/android/server/am/PhantomProcessList.java
+++ b/services/core/java/com/android/server/am/PhantomProcessList.java
@@ -548,6 +548,7 @@
*/
void setProcessGroupForPhantomProcessOfApp(final ProcessRecord app, final int group) {
synchronized (mLock) {
+ lookForPhantomProcessesLocked(app);
final SparseArray<PhantomProcessRecord> array = getPhantomProcessOfAppLocked(app);
if (array == null) {
return;
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index 7b4d6c7..5d5b35b 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -250,4 +250,14 @@
is_fixed_read_only: true
description: "Add +X to the prev scores according to their positions in the process LRU list"
bug: "359912586"
-}
\ No newline at end of file
+}
+
+flag {
+ name: "phantom_processes_fix"
+ namespace: "backstage_power"
+ description: "Make sure setProcessGroupForPhantomProcessOfApp deals with phantom processes properly"
+ bug: "375058190"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/services/core/java/com/android/server/appop/AppOpsRestrictionsImpl.java b/services/core/java/com/android/server/appop/AppOpsRestrictionsImpl.java
index ae93991..0855815b 100644
--- a/services/core/java/com/android/server/appop/AppOpsRestrictionsImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsRestrictionsImpl.java
@@ -65,27 +65,31 @@
@Override
public boolean setGlobalRestriction(Object clientToken, int code, boolean restricted) {
+ boolean changed;
if (restricted) {
if (!mGlobalRestrictions.containsKey(clientToken)) {
mGlobalRestrictions.put(clientToken, new SparseBooleanArray());
}
SparseBooleanArray restrictedCodes = mGlobalRestrictions.get(clientToken);
Objects.requireNonNull(restrictedCodes);
- boolean changed = !restrictedCodes.get(code);
+ changed = !restrictedCodes.get(code);
restrictedCodes.put(code, true);
- return changed;
} else {
SparseBooleanArray restrictedCodes = mGlobalRestrictions.get(clientToken);
if (restrictedCodes == null) {
return false;
}
- boolean changed = restrictedCodes.get(code);
+ changed = restrictedCodes.get(code);
restrictedCodes.delete(code);
if (restrictedCodes.size() == 0) {
mGlobalRestrictions.remove(clientToken);
}
- return changed;
}
+
+ if (changed) {
+ AppOpsManager.invalidateAppOpModeCache();
+ }
+ return changed;
}
@Override
@@ -104,7 +108,11 @@
@Override
public boolean clearGlobalRestrictions(Object clientToken) {
- return mGlobalRestrictions.remove(clientToken) != null;
+ boolean changed = mGlobalRestrictions.remove(clientToken) != null;
+ if (changed) {
+ AppOpsManager.invalidateAppOpModeCache();
+ }
+ return changed;
}
@RequiresPermission(anyOf = {
@@ -122,6 +130,9 @@
changed |= putUserRestrictionExclusions(clientToken, userIds[i],
excludedPackageTags);
}
+ if (changed) {
+ AppOpsManager.invalidateAppOpModeCache();
+ }
return changed;
}
@@ -191,6 +202,9 @@
changed |= mUserRestrictions.remove(clientToken) != null;
changed |= mUserRestrictionExcludedPackageTags.remove(clientToken) != null;
notifyAllUserRestrictions(allUserRestrictedCodes);
+ if (changed) {
+ AppOpsManager.invalidateAppOpModeCache();
+ }
return changed;
}
@@ -244,6 +258,9 @@
}
}
+ if (changed) {
+ AppOpsManager.invalidateAppOpModeCache();
+ }
return changed;
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 702ad95..5e74d67 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -998,6 +998,7 @@
@Override
public void onUidModeChanged(int uid, int code, int mode,
String persistentDeviceId) {
+ AppOpsManager.invalidateAppOpModeCache();
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyOpChangedForAllPkgsInUid, AppOpsService.this,
code, uid, false, persistentDeviceId));
@@ -1006,6 +1007,7 @@
@Override
public void onPackageModeChanged(String packageName, int userId, int code,
int mode) {
+ AppOpsManager.invalidateAppOpModeCache();
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyOpChangedForPkg, AppOpsService.this,
packageName, code, mode, userId));
@@ -1032,6 +1034,11 @@
// To migrate storageFile to recentAccessesFile, these reads must be called in this order.
readRecentAccesses();
mAppOpsCheckingService.readState();
+ // The system property used by the cache is created the first time it is written, that only
+ // happens inside invalidateCache(). Until the service calls invalidateCache() the property
+ // will not exist and the nonce will be UNSET.
+ AppOpsManager.invalidateAppOpModeCache();
+ AppOpsManager.disableAppOpModeCache();
}
public void publish() {
@@ -2830,6 +2837,13 @@
@Override
public int checkOperationRaw(int code, int uid, String packageName,
@Nullable String attributionTag) {
+ if (Binder.getCallingPid() != Process.myPid()
+ && Flags.appopAccessTrackingLoggingEnabled()) {
+ FrameworkStatsLog.write(
+ APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED, uid, code,
+ APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED__BINDER_API__CHECK_OPERATION,
+ false);
+ }
return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, attributionTag,
Context.DEVICE_ID_DEFAULT, true /*raw*/);
}
@@ -2837,6 +2851,13 @@
@Override
public int checkOperationRawForDevice(int code, int uid, @Nullable String packageName,
@Nullable String attributionTag, int virtualDeviceId) {
+ if (Binder.getCallingPid() != Process.myPid()
+ && Flags.appopAccessTrackingLoggingEnabled()) {
+ FrameworkStatsLog.write(
+ APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED, uid, code,
+ APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED__BINDER_API__CHECK_OPERATION,
+ false);
+ }
return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, attributionTag,
virtualDeviceId, true /*raw*/);
}
@@ -2894,8 +2915,14 @@
return AppOpsManager.MODE_IGNORED;
}
}
- return checkOperationUnchecked(code, uid, resolvedPackageName, attributionTag,
- virtualDeviceId, raw);
+
+ if (Flags.appopModeCachingEnabled()) {
+ return getAppOpMode(code, uid, resolvedPackageName, attributionTag, virtualDeviceId,
+ raw, true);
+ } else {
+ return checkOperationUnchecked(code, uid, resolvedPackageName, attributionTag,
+ virtualDeviceId, raw);
+ }
}
/**
@@ -2961,6 +2988,54 @@
}
}
+ /**
+ * This method unifies mode checking logic between checkOperationUnchecked and
+ * noteOperationUnchecked. It can replace those two methods once the flag is fully rolled out.
+ *
+ * @param isCheckOp This param is only used in user's op restriction. When checking if a package
+ * can bypass user's restriction we should account for attributionTag as well.
+ * But existing checkOp APIs don't accept attributionTag so we added a hack to
+ * skip attributionTag check for checkOp. After we add an overload of checkOp
+ * that accepts attributionTag we should remove this param.
+ */
+ private @Mode int getAppOpMode(int code, int uid, @NonNull String packageName,
+ @Nullable String attributionTag, int virtualDeviceId, boolean raw, boolean isCheckOp) {
+ PackageVerificationResult pvr;
+ try {
+ pvr = verifyAndGetBypass(uid, packageName, attributionTag);
+ } catch (SecurityException e) {
+ logVerifyAndGetBypassFailure(uid, e, "getAppOpMode");
+ return MODE_IGNORED;
+ }
+
+ if (isOpRestrictedDueToSuspend(code, packageName, uid)) {
+ return MODE_IGNORED;
+ }
+
+ synchronized (this) {
+ if (isOpRestrictedLocked(uid, code, packageName, attributionTag, virtualDeviceId,
+ pvr.bypass, isCheckOp)) {
+ return MODE_IGNORED;
+ }
+ if (isOpAllowedForUid(uid)) {
+ return MODE_ALLOWED;
+ }
+
+ int switchCode = AppOpsManager.opToSwitch(code);
+ int rawUidMode = mAppOpsCheckingService.getUidMode(uid,
+ getPersistentId(virtualDeviceId), switchCode);
+
+ if (rawUidMode != AppOpsManager.opToDefaultMode(switchCode)) {
+ return raw ? rawUidMode : evaluateForegroundMode(uid, switchCode, rawUidMode);
+ }
+
+ int rawPackageMode = mAppOpsCheckingService.getPackageMode(packageName, switchCode,
+ UserHandle.getUserId(uid));
+ return raw ? rawPackageMode : evaluateForegroundMode(uid, switchCode, rawPackageMode);
+ }
+ }
+
+
@Override
public int checkAudioOperation(int code, int usage, int uid, String packageName) {
return mCheckOpsDelegateDispatcher.checkAudioOperation(code, usage, uid, packageName);
@@ -3213,7 +3288,6 @@
PackageVerificationResult pvr;
try {
pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName);
- boolean wasNull = attributionTag == null;
if (!pvr.isAttributionTagValid) {
attributionTag = null;
}
diff --git a/services/core/java/com/android/server/audio/InputDeviceVolumeHelper.java b/services/core/java/com/android/server/audio/InputDeviceVolumeHelper.java
index d094629..d7d1ac9 100644
--- a/services/core/java/com/android/server/audio/InputDeviceVolumeHelper.java
+++ b/services/core/java/com/android/server/audio/InputDeviceVolumeHelper.java
@@ -23,10 +23,10 @@
import android.content.ContentResolver;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
-import android.media.AudioManager;
import android.media.AudioSystem;
import android.os.UserHandle;
import android.util.IntArray;
+import android.util.Log;
import android.util.SparseIntArray;
import java.util.HashSet;
@@ -48,7 +48,7 @@
// A map between device internal type (e.g. AudioSystem.DEVICE_IN_BUILTIN_MIC) to its input gain
// index.
private final SparseIntArray mInputGainIndexMap;
- private final Set<Integer> mSupportedDeviceTypes;
+ private final Set<Integer> mSupportedDeviceTypes = new HashSet<>();
InputDeviceVolumeHelper(
SettingsAdapter settings,
@@ -60,20 +60,16 @@
IntArray internalDeviceTypes = new IntArray();
int status = AudioSystem.getSupportedDeviceTypes(GET_DEVICES_INPUTS, internalDeviceTypes);
- mInputGainIndexMap =
- new SparseIntArray(
- status == AudioManager.SUCCESS
- ? internalDeviceTypes.size()
- : AudioSystem.DEVICE_IN_ALL_SET.size());
+ if (status != AudioSystem.SUCCESS) {
+ Log.e(TAG, "AudioSystem.getSupportedDeviceTypes(GET_DEVICES_INPUTS) failed. status:"
+ + status);
+ }
- if (status == AudioManager.SUCCESS) {
- Set<Integer> supportedDeviceTypes = new HashSet<>();
- for (int i = 0; i < internalDeviceTypes.size(); i++) {
- supportedDeviceTypes.add(internalDeviceTypes.get(i));
- }
- mSupportedDeviceTypes = supportedDeviceTypes;
- } else {
- mSupportedDeviceTypes = AudioSystem.DEVICE_IN_ALL_SET;
+ // Note that in a rare case, if AudioSystem.getSupportedDeviceTypes call fails, both
+ // mInputGainIndexMap and mSupportedDeviceTypes will be empty.
+ mInputGainIndexMap = new SparseIntArray(internalDeviceTypes.size());
+ for (int i = 0; i < internalDeviceTypes.size(); i++) {
+ mSupportedDeviceTypes.add(internalDeviceTypes.get(i));
}
readSettings();
diff --git a/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java b/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
index 6c93366..394b561 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
@@ -77,6 +77,16 @@
}
@Override
+ public void cancel() {
+ super.cancel();
+ try {
+ mInvalidationCallback.onCompleted();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to complete invalidation client due to exception: " + e);
+ }
+ }
+
+ @Override
public int getProtoEnum() {
return BiometricsProto.CM_INVALIDATE;
}
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index a40dd79..c3d88e3 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -50,6 +50,7 @@
*
* <p>Note, this class is not thread safe so callers must ensure thread safety.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatChange extends CompatibilityChangeInfo {
/**
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 79025d0..e89f43b 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -42,6 +42,7 @@
import com.android.internal.compat.CompatibilityOverridesToRemoveConfig;
import com.android.internal.compat.IOverrideValidator;
import com.android.internal.compat.OverrideAllowedState;
+import com.android.internal.ravenwood.RavenwoodEnvironment;
import com.android.server.compat.config.Change;
import com.android.server.compat.config.Config;
import com.android.server.compat.overrides.ChangeOverrides;
@@ -63,6 +64,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Predicate;
import javax.xml.datatype.DatatypeConfigurationException;
@@ -72,12 +74,16 @@
* <p>It stores the default configuration for each change, and any per-package overrides that have
* been configured.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
final class CompatConfig {
private static final String TAG = "CompatConfig";
private static final String APP_COMPAT_DATA_DIR = "/data/misc/appcompat";
private static final String STATIC_OVERRIDES_PRODUCT_DIR = "/product/etc/appcompat";
private static final String OVERRIDES_FILE = "compat_framework_overrides.xml";
+ private static final String APP_COMPAT_DATA_DIR_RAVENWOOD = "/ravenwood-data/";
+ private static final String OVERRIDES_FILE_RAVENWOOD = "compat-config.xml";
+
private final ConcurrentHashMap<Long, CompatChange> mChanges = new ConcurrentHashMap<>();
private final OverrideValidatorImpl mOverrideValidator;
@@ -98,19 +104,32 @@
static CompatConfig create(AndroidBuildClassifier androidBuildClassifier, Context context) {
CompatConfig config = new CompatConfig(androidBuildClassifier, context);
- config.initConfigFromLib(Environment.buildPath(
+ config.loadConfigFiles();
+ config.initOverrides();
+ config.invalidateCache();
+ return config;
+ }
+
+ @android.ravenwood.annotation.RavenwoodReplace
+ private void loadConfigFiles() {
+ initConfigFromLib(Environment.buildPath(
Environment.getRootDirectory(), "etc", "compatconfig"));
- config.initConfigFromLib(Environment.buildPath(
+ initConfigFromLib(Environment.buildPath(
Environment.getRootDirectory(), "system_ext", "etc", "compatconfig"));
List<ApexManager.ActiveApexInfo> apexes = ApexManager.getInstance().getActiveApexInfos();
for (ApexManager.ActiveApexInfo apex : apexes) {
- config.initConfigFromLib(Environment.buildPath(
+ initConfigFromLib(Environment.buildPath(
apex.apexDirectory, "etc", "compatconfig"));
}
- config.initOverrides();
- config.invalidateCache();
- return config;
+ }
+
+ @SuppressWarnings("unused")
+ private void loadConfigFiles$ravenwood() {
+ final var configDir = new File(
+ RavenwoodEnvironment.getInstance().getRavenwoodRuntimePath()
+ + APP_COMPAT_DATA_DIR_RAVENWOOD);
+ initConfigFromLib(configDir, (file) -> file.getName().endsWith(OVERRIDES_FILE_RAVENWOOD));
}
/**
@@ -678,12 +697,25 @@
return changeInfos;
}
+ /**
+ * Load all config files in a given directory.
+ */
void initConfigFromLib(File libraryDir) {
+ initConfigFromLib(libraryDir, (file) -> true);
+ }
+
+ /**
+ * Load config files in a given directory, but only the ones that match {@code includingFilter}.
+ */
+ void initConfigFromLib(File libraryDir, Predicate<File> includingFilter) {
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Slog.d(TAG, "No directory " + libraryDir + ", skipping");
return;
}
for (File f : libraryDir.listFiles()) {
+ if (!includingFilter.test(f)) {
+ continue;
+ }
Slog.d(TAG, "Found a config file: " + f.getPath());
//TODO(b/138222363): Handle duplicate ids across config files.
readConfig(f);
diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
index e3b6d03..362c697 100644
--- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
+++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
@@ -45,6 +45,7 @@
/**
* Implementation of the policy for allowing compat change overrides.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class OverrideValidatorImpl extends IOverrideValidator.Stub {
private AndroidBuildClassifier mAndroidBuildClassifier;
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 8d64383..97f4a5c 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -36,6 +36,7 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
+import android.os.PermissionEnforcer;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -65,6 +66,7 @@
/**
* System server internal API for gating and reporting compatibility changes.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class PlatformCompat extends IPlatformCompat.Stub {
private static final String TAG = "Compatibility";
@@ -75,6 +77,7 @@
private final AndroidBuildClassifier mBuildClassifier;
public PlatformCompat(Context context) {
+ super(PermissionEnforcer.fromContext(context));
mContext = context;
mChangeReporter = new ChangeReporter(ChangeReporter.SOURCE_SYSTEM_SERVER);
mBuildClassifier = new AndroidBuildClassifier();
@@ -85,6 +88,7 @@
PlatformCompat(Context context, CompatConfig compatConfig,
AndroidBuildClassifier buildClassifier,
ChangeReporter changeReporter) {
+ super(PermissionEnforcer.fromContext(context));
mContext = context;
mChangeReporter = changeReporter;
mCompatConfig = compatConfig;
@@ -515,6 +519,7 @@
return appInfo;
}
+ @android.ravenwood.annotation.RavenwoodReplace
private void killPackage(String packageName) {
int uid = LocalServices.getService(PackageManagerInternal.class).getPackageUid(packageName,
0, UserHandle.myUserId());
@@ -528,6 +533,13 @@
killUid(UserHandle.getAppId(uid));
}
+ @SuppressWarnings("unused")
+ private void killPackage$ravenwood(String packageName) {
+ // TODO Maybe crash if the package is the self.
+ Slog.w(TAG, "killPackage() is ignored on Ravenwood: packageName=" + packageName);
+ }
+
+ @android.ravenwood.annotation.RavenwoodReplace
private void killUid(int appId) {
final long identity = Binder.clearCallingIdentity();
try {
@@ -542,6 +554,12 @@
}
}
+ @SuppressWarnings("unused")
+ private void killUid$ravenwood(int appId) {
+ // TODO Maybe crash if the UID is the self.
+ Slog.w(TAG, "killUid() is ignored on Ravenwood: appId=" + appId);
+ }
+
private void checkAllCompatOverridesAreOverridable(Collection<Long> changeIds) {
for (Long changeId : changeIds) {
if (isKnownChangeId(changeId) && !mCompatConfig.isOverridable(changeId)) {
diff --git a/services/core/java/com/android/server/compat/PlatformCompatNative.java b/services/core/java/com/android/server/compat/PlatformCompatNative.java
index 5d7af65..7a3feb5 100644
--- a/services/core/java/com/android/server/compat/PlatformCompatNative.java
+++ b/services/core/java/com/android/server/compat/PlatformCompatNative.java
@@ -23,6 +23,7 @@
/**
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class PlatformCompatNative extends IPlatformCompatNative.Stub {
private final PlatformCompat mPlatformCompat;
diff --git a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesParser.java b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesParser.java
index e8762a3..0ec6879 100644
--- a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesParser.java
+++ b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesParser.java
@@ -46,6 +46,7 @@
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
final class AppCompatOverridesParser {
/**
* Flag for specifying all compat change IDs owned by a namespace. See {@link
diff --git a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java
index fe002ce..8637d2d 100644
--- a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java
+++ b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java
@@ -68,6 +68,7 @@
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class AppCompatOverridesService {
private static final String TAG = "AppCompatOverridesService";
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index f5a75c7d..0e77040 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -25,7 +25,7 @@
import static android.Manifest.permission.RESTRICT_DISPLAY_MODES;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
-import static android.hardware.display.DisplayManager.EventFlag;
+import static android.hardware.display.DisplayManagerGlobal.InternalEventFlag;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
@@ -1390,16 +1390,16 @@
}
private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid,
- int callingUid, @EventFlag long eventFlagsMask) {
+ int callingUid, @InternalEventFlag long internalEventFlagsMask) {
synchronized (mSyncRoot) {
CallbackRecord record = mCallbacks.get(callingPid);
if (record != null) {
- record.updateEventFlagsMask(eventFlagsMask);
+ record.updateEventFlagsMask(internalEventFlagsMask);
return;
}
- record = new CallbackRecord(callingPid, callingUid, callback, eventFlagsMask);
+ record = new CallbackRecord(callingPid, callingUid, callback, internalEventFlagsMask);
try {
IBinder binder = callback.asBinder();
binder.linkToDeath(record, 0);
@@ -4009,7 +4009,7 @@
public final int mPid;
public final int mUid;
private final IDisplayManagerCallback mCallback;
- private @DisplayManager.EventFlag AtomicLong mEventFlagsMask;
+ private @InternalEventFlag AtomicLong mInternalEventFlagsMask;
private final String mPackageName;
public boolean mWifiDisplayScanRequested;
@@ -4030,11 +4030,11 @@
private boolean mFrozen;
CallbackRecord(int pid, int uid, @NonNull IDisplayManagerCallback callback,
- @EventFlag long eventFlagsMask) {
+ @InternalEventFlag long internalEventFlagsMask) {
mPid = pid;
mUid = uid;
mCallback = callback;
- mEventFlagsMask = new AtomicLong(eventFlagsMask);
+ mInternalEventFlagsMask = new AtomicLong(internalEventFlagsMask);
mCached = false;
mFrozen = false;
@@ -4056,8 +4056,8 @@
mPackageName = packageNames == null ? null : packageNames[0];
}
- public void updateEventFlagsMask(@EventFlag long eventFlag) {
- mEventFlagsMask.set(eventFlag);
+ public void updateEventFlagsMask(@InternalEventFlag long internalEventFlag) {
+ mInternalEventFlagsMask.set(internalEventFlag);
}
/**
@@ -4121,13 +4121,13 @@
if (!shouldSendEvent(event)) {
if (extraLogging(mPackageName)) {
Slog.i(TAG,
- "Not sending displayEvent: " + event + " due to flag:"
- + mEventFlagsMask);
+ "Not sending displayEvent: " + event + " due to mask:"
+ + mInternalEventFlagsMask);
}
if (Trace.isTagEnabled(Trace.TRACE_TAG_POWER)) {
Trace.instant(Trace.TRACE_TAG_POWER,
- "notifyDisplayEventAsync#notSendingEvent=" + event + ",mEventsFlag="
- + mEventFlagsMask);
+ "notifyDisplayEventAsync#notSendingEvent=" + event
+ + ",mInternalEventFlagsMask=" + mInternalEventFlagsMask);
}
// The client is not interested in this event, so do nothing.
return true;
@@ -4173,22 +4173,29 @@
* Return true if the client is interested in this event.
*/
private boolean shouldSendEvent(@DisplayEvent int event) {
- final long flag = mEventFlagsMask.get();
+ final long mask = mInternalEventFlagsMask.get();
switch (event) {
case DisplayManagerGlobal.EVENT_DISPLAY_ADDED:
- return (flag & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0;
+ return (mask & DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED) != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_CHANGED:
- return (flag & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0;
+ return (mask & DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED) != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_BRIGHTNESS_CHANGED:
- return (flag & DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0;
+ return (mask
+ & DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED)
+ != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_REMOVED:
- return (flag & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0;
+ return (mask & DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED) != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_HDR_SDR_RATIO_CHANGED:
- return (flag & DisplayManager.EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0;
+ return (mask
+ & DisplayManagerGlobal
+ .INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED)
+ != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_CONNECTED:
// fallthrough
case DisplayManagerGlobal.EVENT_DISPLAY_DISCONNECTED:
- return (flag & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0;
+ return (mask
+ & DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED)
+ != 0;
default:
// This should never happen.
Slog.e(TAG, "Unknown display event " + event);
@@ -4374,15 +4381,16 @@
@Override // Binder call
public void registerCallback(IDisplayManagerCallback callback) {
- registerCallbackWithEventMask(callback, DisplayManager.EVENT_FLAG_DISPLAY_ADDED
- | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED);
+ registerCallbackWithEventMask(callback,
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED);
}
@Override // Binder call
@SuppressLint("AndroidFrameworkRequiresPermission") // Permission only required sometimes
public void registerCallbackWithEventMask(IDisplayManagerCallback callback,
- @EventFlag long eventFlagsMask) {
+ @InternalEventFlag long internalEventFlagsMask) {
if (callback == null) {
throw new IllegalArgumentException("listener must not be null");
}
@@ -4391,7 +4399,9 @@
final int callingUid = Binder.getCallingUid();
if (mFlags.isConnectedDisplayManagementEnabled()) {
- if ((eventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
+ if ((internalEventFlagsMask
+ & DisplayManagerGlobal
+ .INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
mContext.enforceCallingOrSelfPermission(MANAGE_DISPLAYS,
"Permission required to get signals about connection events.");
}
@@ -4399,7 +4409,7 @@
final long token = Binder.clearCallingIdentity();
try {
- registerCallbackInternal(callback, callingPid, callingUid, eventFlagsMask);
+ registerCallbackInternal(callback, callingPid, callingUid, internalEventFlagsMask);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index a9ed0aa..c90dfbf 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1595,7 +1595,8 @@
// Note throttling effectively changes the allowed brightness range, so, similarly to HBM,
// we broadcast this change through setting.
final float unthrottledBrightnessState = rawBrightnessState;
- DisplayBrightnessState clampedState = mBrightnessClamperController.clamp(mPowerRequest,
+ DisplayBrightnessState clampedState = mBrightnessClamperController.clamp(
+ displayBrightnessState, mPowerRequest,
brightnessState, slowChange, /* displayState= */ state);
brightnessState = clampedState.getBrightness();
slowChange = clampedState.isSlowChange();
@@ -2003,7 +2004,9 @@
mCachedBrightnessInfo.brightnessMax.value,
mCachedBrightnessInfo.hbmMode.value,
mCachedBrightnessInfo.hbmTransitionPoint.value,
- mCachedBrightnessInfo.brightnessMaxReason.value);
+ mCachedBrightnessInfo.brightnessMaxReason.value,
+ mCachedBrightnessInfo.brightnessReason.value
+ == BrightnessReason.REASON_OVERRIDE);
}
}
@@ -2028,6 +2031,8 @@
@BrightnessInfo.BrightnessMaxReason int maxReason =
state != null ? state.getBrightnessMaxReason()
: BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
+ BrightnessReason brightnessReason = state != null ? state.getBrightnessReason()
+ : new BrightnessReason(BrightnessReason.REASON_UNKNOWN);
final float minBrightness = Math.max(stateMin, Math.min(
mBrightnessRangeController.getCurrentBrightnessMin(), stateMax));
final float maxBrightness = Math.min(
@@ -2055,6 +2060,9 @@
changed |=
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason,
maxReason);
+ changed |=
+ mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessReason,
+ brightnessReason.getReason());
return changed;
}
}
@@ -2683,6 +2691,8 @@
+ mCachedBrightnessInfo.hbmTransitionPoint.value);
pw.println(" mCachedBrightnessInfo.brightnessMaxReason ="
+ mCachedBrightnessInfo.brightnessMaxReason.value);
+ pw.println(" mCachedBrightnessInfo.brightnessReason ="
+ + mCachedBrightnessInfo.brightnessReason);
}
pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
@@ -3390,6 +3400,7 @@
new MutableFloat(HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID);
public MutableInt brightnessMaxReason =
new MutableInt(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
+ public MutableInt brightnessReason = new MutableInt(BrightnessReason.REASON_UNKNOWN);
public boolean checkAndSetFloat(MutableFloat mf, float f) {
if (mf.value != f) {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 4211453..dabef84 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -51,6 +51,7 @@
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.Message;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.ArrayMap;
@@ -64,6 +65,7 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.brightness.BrightnessUtils;
import com.android.server.display.feature.DisplayManagerFlags;
import java.io.PrintWriter;
@@ -323,7 +325,7 @@
private int mWidth;
private int mHeight;
private int mDensityDpi;
- private float mRequestedRefreshRate;
+ private final float mRequestedRefreshRate;
private Surface mSurface;
private DisplayDeviceInfo mInfo;
private int mDisplayState;
@@ -332,7 +334,9 @@
private Display.Mode mMode;
private int mDisplayIdToMirror;
private boolean mIsWindowManagerMirroring;
- private DisplayCutout mDisplayCutout;
+ private final DisplayCutout mDisplayCutout;
+ private final float mDefaultBrightness;
+ private float mCurrentBrightness;
public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
int ownerUid, String ownerPackageName, Surface surface, int flags,
@@ -349,6 +353,8 @@
mDensityDpi = virtualDisplayConfig.getDensityDpi();
mRequestedRefreshRate = virtualDisplayConfig.getRequestedRefreshRate();
mDisplayCutout = virtualDisplayConfig.getDisplayCutout();
+ mDefaultBrightness = virtualDisplayConfig.getDefaultBrightness();
+ mCurrentBrightness = mDefaultBrightness;
mMode = createMode(mWidth, mHeight, getRefreshRate());
mSurface = surface;
mFlags = flags;
@@ -457,6 +463,12 @@
mCallback.dispatchDisplayResumed();
}
}
+ if (android.companion.virtualdevice.flags.Flags.deviceAwareDisplayPower()
+ && BrightnessUtils.isValidBrightnessValue(brightnessState)
+ && brightnessState != mCurrentBrightness) {
+ mCurrentBrightness = brightnessState;
+ mCallback.dispatchRequestedBrightnessChanged(mCurrentBrightness);
+ }
return null;
}
@@ -623,6 +635,10 @@
mInfo.state = mDisplayState;
}
+ mInfo.brightnessMinimum = PowerManager.BRIGHTNESS_MIN;
+ mInfo.brightnessMaximum = PowerManager.BRIGHTNESS_MAX;
+ mInfo.brightnessDefault = mDefaultBrightness;
+
mInfo.ownerUid = mOwnerUid;
mInfo.ownerPackageName = mOwnerPackageName;
@@ -642,6 +658,7 @@
private static final int MSG_ON_DISPLAY_PAUSED = 0;
private static final int MSG_ON_DISPLAY_RESUMED = 1;
private static final int MSG_ON_DISPLAY_STOPPED = 2;
+ private static final int MSG_ON_REQUESTED_BRIGHTNESS_CHANGED = 3;
private final IVirtualDisplayCallback mCallback;
@@ -663,6 +680,9 @@
case MSG_ON_DISPLAY_STOPPED:
mCallback.onStopped();
break;
+ case MSG_ON_REQUESTED_BRIGHTNESS_CHANGED:
+ mCallback.onRequestedBrightnessChanged((Float) msg.obj);
+ break;
}
} catch (RemoteException e) {
Slog.w(TAG, "Failed to notify listener of virtual display event.", e);
@@ -677,6 +697,11 @@
sendEmptyMessage(MSG_ON_DISPLAY_RESUMED);
}
+ public void dispatchRequestedBrightnessChanged(float brightness) {
+ Message msg = obtainMessage(MSG_ON_REQUESTED_BRIGHTNESS_CHANGED, brightness);
+ sendMessage(msg);
+ }
+
public void dispatchDisplayStopped() {
sendEmptyMessage(MSG_ON_DISPLAY_STOPPED);
}
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
index a10094f..6e579bf 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
@@ -172,17 +172,18 @@
* Applies clamping
* Called in DisplayControllerHandler
*/
- public DisplayBrightnessState clamp(DisplayManagerInternal.DisplayPowerRequest request,
+ public DisplayBrightnessState clamp(DisplayBrightnessState displayBrightnessState,
+ DisplayManagerInternal.DisplayPowerRequest request,
float brightnessValue, boolean slowChange, int displayState) {
float cappedBrightness = Math.min(brightnessValue, mBrightnessCap);
- DisplayBrightnessState.Builder builder = DisplayBrightnessState.builder();
+ DisplayBrightnessState.Builder builder = DisplayBrightnessState.Builder.from(
+ displayBrightnessState);
builder.setIsSlowChange(slowChange);
builder.setBrightness(cappedBrightness);
builder.setMaxBrightness(mBrightnessCap);
builder.setCustomAnimationRate(mCustomAnimationRate);
builder.setBrightnessMaxReason(getBrightnessMaxReason());
-
if (mClamperType != null) {
builder.getBrightnessReason().addModifier(BrightnessReason.MODIFIER_THROTTLED);
if (!mClamperApplied) {
diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
index 88562ab..8423e19 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -2077,8 +2077,8 @@
mDeviceConfigDisplaySettings.startListening();
mInjector.registerDisplayListener(this, mHandler,
- DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS);
+ DisplayManager.EVENT_FLAG_DISPLAY_CHANGED,
+ DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS);
}
private void setLoggingEnabled(boolean loggingEnabled) {
@@ -2878,8 +2878,8 @@
}
mDisplayManagerInternal = mInjector.getDisplayManagerInternal();
mInjector.registerDisplayListener(this, mHandler,
- DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED);
+ DisplayManager.EVENT_FLAG_DISPLAY_REMOVED,
+ DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS);
}
/**
@@ -3108,6 +3108,9 @@
void registerDisplayListener(@NonNull DisplayManager.DisplayListener listener,
Handler handler, long flags);
+ void registerDisplayListener(@NonNull DisplayManager.DisplayListener listener,
+ Handler handler, long flags, long privateFlags);
+
Display getDisplay(int displayId);
Display[] getDisplays();
@@ -3175,6 +3178,12 @@
}
@Override
+ public void registerDisplayListener(DisplayManager.DisplayListener listener,
+ Handler handler, long flags, long privateFlags) {
+ getDisplayManager().registerDisplayListener(listener, handler, flags, privateFlags);
+ }
+
+ @Override
public Display getDisplay(int displayId) {
return getDisplayManager().getDisplay(displayId);
}
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 76e5ef0..794eb87 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -64,12 +64,15 @@
import android.service.dreams.DreamManagerInternal;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
+import android.text.TextUtils;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.Display;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.content.PackageMonitor;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.util.DumpUtils;
@@ -86,6 +89,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -155,6 +159,10 @@
private ComponentName mDreamOverlayServiceName;
private final AmbientDisplayConfiguration mDozeConfig;
+
+ /** Stores {@link PerUserPackageMonitor} to monitor dream uninstalls. */
+ private final SparseArray<PackageMonitor> mPackageMonitors = new SparseArray<>();
+
private final ActivityInterceptorCallback mActivityInterceptorCallback =
new ActivityInterceptorCallback() {
@Nullable
@@ -218,6 +226,15 @@
}
}
+ private final class PerUserPackageMonitor extends PackageMonitor {
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ super.onPackageRemoved(packageName, uid);
+ final int userId = getChangingUserId();
+ updateDreamOnPackageRemoved(packageName, userId);
+ }
+ }
+
public DreamManagerService(Context context) {
this(context, new DreamHandler(FgThread.get().getLooper()));
}
@@ -333,6 +350,33 @@
});
}
+ @Override
+ public void onUserStarting(@NonNull TargetUser user) {
+ super.onUserStarting(user);
+ mHandler.post(() -> {
+ final int userId = user.getUserIdentifier();
+ if (!mPackageMonitors.contains(userId)) {
+ final PackageMonitor monitor = new PerUserPackageMonitor();
+ monitor.register(mContext, UserHandle.of(userId), mHandler);
+ mPackageMonitors.put(userId, monitor);
+ } else {
+ Slog.w(TAG, "Package monitor already registered for " + userId);
+ }
+ });
+ }
+
+ @Override
+ public void onUserStopping(@NonNull TargetUser user) {
+ super.onUserStopping(user);
+ mHandler.post(() -> {
+ final PackageMonitor monitor = mPackageMonitors.removeReturnOld(
+ user.getUserIdentifier());
+ if (monitor != null) {
+ monitor.unregister();
+ }
+ });
+ }
+
private void dumpInternal(PrintWriter pw) {
synchronized (mLock) {
pw.println("DREAM MANAGER (dumpsys dreams)");
@@ -664,6 +708,22 @@
return validComponents.toArray(new ComponentName[validComponents.size()]);
}
+ private void updateDreamOnPackageRemoved(String packageName, int userId) {
+ final ComponentName[] componentNames = componentsFromString(
+ Settings.Secure.getStringForUser(mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_COMPONENTS,
+ userId));
+ if (componentNames != null) {
+ // Filter out any components in the removed package.
+ final ComponentName[] filteredComponents = Arrays.stream(componentNames).filter(
+ (componentName -> !TextUtils.equals(componentName.getPackageName(),
+ packageName))).toArray(ComponentName[]::new);
+ if (filteredComponents.length != componentNames.length) {
+ setDreamComponentsForUser(userId, filteredComponents);
+ }
+ }
+ }
+
private void setDreamComponentsForUser(int userId, ComponentName[] componentNames) {
Settings.Secure.putStringForUser(mContext.getContentResolver(),
Settings.Secure.SCREENSAVER_COMPONENTS,
diff --git a/services/core/java/com/android/server/flags/services.aconfig b/services/core/java/com/android/server/flags/services.aconfig
index 69ba785..eea5c98 100644
--- a/services/core/java/com/android/server/flags/services.aconfig
+++ b/services/core/java/com/android/server/flags/services.aconfig
@@ -67,3 +67,14 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ namespace: "backstage_power"
+ name: "rate_limit_battery_changed_broadcast"
+ description: "Optimize the delivery of the battery changed broadcast by rate limiting the frequency of the updates"
+ bug: "362337621"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/services/core/java/com/android/server/input/InputGestureManager.java b/services/core/java/com/android/server/input/InputGestureManager.java
index cf1cdaf..e545dd5 100644
--- a/services/core/java/com/android/server/input/InputGestureManager.java
+++ b/services/core/java/com/android/server/input/InputGestureManager.java
@@ -17,6 +17,8 @@
package com.android.server.input;
import static android.hardware.input.InputGestureData.createKeyTrigger;
+
+import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;
import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
import static com.android.window.flags.Flags.enableMoveToNextDisplayShortcut;
@@ -209,12 +211,12 @@
KeyGestureEvent.KEY_GESTURE_TYPE_MOVE_TO_NEXT_DISPLAY
));
}
- if (keyboardA11yShortcutControl()) {
- systemShortcuts.add(createKeyGesture(
- KeyEvent.KEYCODE_T,
+ if (enableTalkbackAndMagnifierKeyGestures()) {
+ systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_T,
KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
- KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK
- ));
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK));
+ }
+ if (keyboardA11yShortcutControl()) {
if (InputSettings.isAccessibilityBounceKeysFeatureEnabled()) {
systemShortcuts.add(createKeyGesture(
KeyEvent.KEYCODE_3,
@@ -321,26 +323,50 @@
return InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_DOES_NOT_EXIST;
}
customGestures.remove(data.getTrigger());
- if (customGestures.size() == 0) {
+ if (customGestures.isEmpty()) {
mCustomInputGestures.remove(userId);
}
return InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS;
}
}
- public void removeAllCustomInputGestures(int userId) {
+ public void removeAllCustomInputGestures(int userId, @Nullable InputGestureData.Filter filter) {
synchronized (mGestureLock) {
- mCustomInputGestures.remove(userId);
+ Map<InputGestureData.Trigger, InputGestureData> customGestures =
+ mCustomInputGestures.get(userId);
+ if (customGestures == null) {
+ return;
+ }
+ if (filter == null) {
+ mCustomInputGestures.remove(userId);
+ return;
+ }
+ customGestures.entrySet().removeIf(entry -> filter.matches(entry.getValue()));
+ if (customGestures.isEmpty()) {
+ mCustomInputGestures.remove(userId);
+ }
}
}
@NonNull
- public List<InputGestureData> getCustomInputGestures(int userId) {
+ public List<InputGestureData> getCustomInputGestures(int userId,
+ @Nullable InputGestureData.Filter filter) {
synchronized (mGestureLock) {
if (!mCustomInputGestures.contains(userId)) {
return List.of();
}
- return new ArrayList<>(mCustomInputGestures.get(userId).values());
+ Map<InputGestureData.Trigger, InputGestureData> customGestures =
+ mCustomInputGestures.get(userId);
+ if (filter == null) {
+ return new ArrayList<>(customGestures.values());
+ }
+ List<InputGestureData> result = new ArrayList<>();
+ for (InputGestureData customGesture : customGestures.values()) {
+ if (filter.matches(customGesture)) {
+ result.add(customGesture);
+ }
+ }
+ return result;
}
}
@@ -362,6 +388,22 @@
}
@Nullable
+ public InputGestureData getCustomGestureForTouchpadGesture(@UserIdInt int userId,
+ int touchpadGestureType) {
+ if (touchpadGestureType == InputGestureData.TOUCHPAD_GESTURE_TYPE_UNKNOWN) {
+ return null;
+ }
+ synchronized (mGestureLock) {
+ Map<InputGestureData.Trigger, InputGestureData> customGestures =
+ mCustomInputGestures.get(userId);
+ if (customGestures == null) {
+ return null;
+ }
+ return customGestures.get(InputGestureData.createTouchpadTrigger(touchpadGestureType));
+ }
+ }
+
+ @Nullable
public InputGestureData getSystemShortcutForKeyEvent(KeyEvent event) {
final int keyCode = event.getKeyCode();
if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 78e3b84..f4dd717 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -64,6 +64,7 @@
import android.hardware.input.IStickyModifierStateListener;
import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.InputDeviceIdentifier;
+import android.hardware.input.InputGestureData;
import android.hardware.input.InputManager;
import android.hardware.input.InputSensorInfo;
import android.hardware.input.InputSettings;
@@ -2314,7 +2315,8 @@
// Native callback.
@SuppressWarnings("unused")
private void notifyTouchpadThreeFingerTap() {
- mKeyGestureController.handleTouchpadThreeFingerTap();
+ mKeyGestureController.handleTouchpadGesture(
+ InputGestureData.TOUCHPAD_GESTURE_TYPE_THREE_FINGER_TAP);
}
// Native callback.
@@ -2995,35 +2997,36 @@
@Override
@PermissionManuallyEnforced
- public int addCustomInputGesture(@NonNull AidlInputGestureData inputGestureData) {
+ public int addCustomInputGesture(@UserIdInt int userId,
+ @NonNull AidlInputGestureData inputGestureData) {
enforceManageKeyGesturePermission();
Objects.requireNonNull(inputGestureData);
- return mKeyGestureController.addCustomInputGesture(UserHandle.getCallingUserId(),
- inputGestureData);
+ return mKeyGestureController.addCustomInputGesture(userId, inputGestureData);
}
@Override
@PermissionManuallyEnforced
- public int removeCustomInputGesture(@NonNull AidlInputGestureData inputGestureData) {
+ public int removeCustomInputGesture(@UserIdInt int userId,
+ @NonNull AidlInputGestureData inputGestureData) {
enforceManageKeyGesturePermission();
Objects.requireNonNull(inputGestureData);
- return mKeyGestureController.removeCustomInputGesture(UserHandle.getCallingUserId(),
- inputGestureData);
+ return mKeyGestureController.removeCustomInputGesture(userId, inputGestureData);
}
@Override
@PermissionManuallyEnforced
- public void removeAllCustomInputGestures() {
+ public void removeAllCustomInputGestures(@UserIdInt int userId, int tag) {
enforceManageKeyGesturePermission();
- mKeyGestureController.removeAllCustomInputGestures(UserHandle.getCallingUserId());
+ mKeyGestureController.removeAllCustomInputGestures(userId, InputGestureData.Filter.of(tag));
}
@Override
- public AidlInputGestureData[] getCustomInputGestures() {
- return mKeyGestureController.getCustomInputGestures(UserHandle.getCallingUserId());
+ public AidlInputGestureData[] getCustomInputGestures(@UserIdInt int userId, int tag) {
+ return mKeyGestureController.getCustomInputGestures(userId,
+ InputGestureData.Filter.of(tag));
}
@Override
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index e0991ec..155ffe8 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -847,6 +847,13 @@
/* appLaunchData = */null);
}
+ private void handleTouchpadGesture(@KeyGestureEvent.KeyGestureType int keyGestureType,
+ @Nullable AppLaunchData appLaunchData) {
+ handleKeyGesture(KeyCharacterMap.VIRTUAL_KEYBOARD, new int[0], /* modifierState= */0,
+ keyGestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE,
+ Display.DEFAULT_DISPLAY, /* focusedToken = */null, /* flags = */0, appLaunchData);
+ }
+
@VisibleForTesting
boolean handleKeyGesture(int deviceId, int[] keycodes, int modifierState,
@KeyGestureEvent.KeyGestureType int gestureType, int action, int displayId,
@@ -897,11 +904,18 @@
handleKeyGesture(event, null /*focusedToken*/);
}
- public void handleTouchpadThreeFingerTap() {
- // TODO(b/365063048): trigger a custom shortcut based on the three-finger tap.
- if (DEBUG) {
- Slog.d(TAG, "Three-finger touchpad tap occurred");
+ public void handleTouchpadGesture(int touchpadGestureType) {
+ // Handle custom shortcuts
+ InputGestureData customGesture;
+ synchronized (mUserLock) {
+ customGesture = mInputGestureManager.getCustomGestureForTouchpadGesture(mCurrentUserId,
+ touchpadGestureType);
}
+ if (customGesture == null) {
+ return;
+ }
+ handleTouchpadGesture(customGesture.getAction().keyGestureType(),
+ customGesture.getAction().appLaunchData());
}
@MainThread
@@ -1007,13 +1021,16 @@
}
@BinderThread
- public void removeAllCustomInputGestures(@UserIdInt int userId) {
- mInputGestureManager.removeAllCustomInputGestures(userId);
+ public void removeAllCustomInputGestures(@UserIdInt int userId,
+ @Nullable InputGestureData.Filter filter) {
+ mInputGestureManager.removeAllCustomInputGestures(userId, filter);
}
@BinderThread
- public AidlInputGestureData[] getCustomInputGestures(@UserIdInt int userId) {
- List<InputGestureData> customGestures = mInputGestureManager.getCustomInputGestures(userId);
+ public AidlInputGestureData[] getCustomInputGestures(@UserIdInt int userId,
+ @Nullable InputGestureData.Filter filter) {
+ List<InputGestureData> customGestures = mInputGestureManager.getCustomInputGestures(userId,
+ filter);
AidlInputGestureData[] result = new AidlInputGestureData[customGestures.size()];
for (int i = 0; i < customGestures.size(); i++) {
result[i] = customGestures.get(i).getAidlData();
@@ -1214,6 +1231,7 @@
public void dump(IndentingPrintWriter ipw) {
ipw.println("KeyGestureController:");
ipw.increaseIndent();
+ ipw.println("mCurrentUserId = " + mCurrentUserId);
ipw.println("mSystemPid = " + mSystemPid);
ipw.println("mPendingMetaAction = " + mPendingMetaAction);
ipw.println("mPendingCapsLockToggle = " + mPendingCapsLockToggle);
diff --git a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
index 146ce17..46be1ca 100644
--- a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
+++ b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
@@ -27,6 +27,7 @@
import android.util.AtomicFile;
import android.util.Slog;
import android.util.Xml;
+import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
@@ -59,8 +60,14 @@
private static final String NODE_SUBTYPE = "subtype";
private static final String NODE_IMI = "imi";
private static final String ATTR_ID = "id";
+ /** The resource ID of the subtype name. */
private static final String ATTR_LABEL = "label";
+ /** The untranslatable name of the subtype. */
private static final String ATTR_NAME_OVERRIDE = "nameOverride";
+ /** The layout label string resource identifier. */
+ private static final String ATTR_LAYOUT_LABEL = "layoutLabel";
+ /** The non-localized layout label. */
+ private static final String ATTR_LAYOUT_LABEL_NON_LOCALIZED = "layoutLabelNonLocalized";
private static final String ATTR_NAME_PK_LANGUAGE_TAG = "pkLanguageTag";
private static final String ATTR_NAME_PK_LAYOUT_TYPE = "pkLayoutType";
private static final String ATTR_ICON = "icon";
@@ -173,6 +180,11 @@
out.attributeInt(null, ATTR_ICON, subtype.getIconResId());
out.attributeInt(null, ATTR_LABEL, subtype.getNameResId());
out.attribute(null, ATTR_NAME_OVERRIDE, subtype.getNameOverride().toString());
+ if (Flags.imeSwitcherRevampApi()) {
+ out.attributeInt(null, ATTR_LAYOUT_LABEL, subtype.getLayoutLabelResource());
+ out.attribute(null, ATTR_LAYOUT_LABEL_NON_LOCALIZED,
+ subtype.getLayoutLabelNonLocalized().toString());
+ }
ULocale pkLanguageTag = subtype.getPhysicalKeyboardHintLanguageTag();
if (pkLanguageTag != null) {
out.attribute(null, ATTR_NAME_PK_LANGUAGE_TAG,
@@ -264,6 +276,16 @@
final int label = parser.getAttributeInt(null, ATTR_LABEL);
final String untranslatableName = parser.getAttributeValue(null,
ATTR_NAME_OVERRIDE);
+ final int layoutLabelResource;
+ final String layoutLabelNonLocalized;
+ if (Flags.imeSwitcherRevampApi()) {
+ layoutLabelResource = parser.getAttributeInt(null, ATTR_LAYOUT_LABEL);
+ layoutLabelNonLocalized = parser.getAttributeValue(null,
+ ATTR_LAYOUT_LABEL_NON_LOCALIZED);
+ } else {
+ layoutLabelResource = 0;
+ layoutLabelNonLocalized = null;
+ }
final String pkLanguageTag = parser.getAttributeValue(null,
ATTR_NAME_PK_LANGUAGE_TAG);
final String pkLayoutType = parser.getAttributeValue(null,
@@ -283,6 +305,7 @@
final InputMethodSubtype.InputMethodSubtypeBuilder
builder = new InputMethodSubtype.InputMethodSubtypeBuilder()
.setSubtypeNameResId(label)
+ .setLayoutLabelResource(layoutLabelResource)
.setPhysicalKeyboardHint(
pkLanguageTag == null ? null : new ULocale(pkLanguageTag),
pkLayoutType == null ? "" : pkLayoutType)
@@ -301,6 +324,9 @@
if (untranslatableName != null) {
builder.setSubtypeNameOverride(untranslatableName);
}
+ if (layoutLabelNonLocalized != null) {
+ builder.setLayoutLabelNonLocalized(layoutLabelNonLocalized);
+ }
tempSubtypesArray.add(builder.build());
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java
index 6abd5aa..9f94905 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java
@@ -238,8 +238,8 @@
prevImeId = imeId;
}
- menuItems.add(new SubtypeItem(item.mImeName, item.mSubtypeName, item.mImi,
- item.mSubtypeIndex));
+ menuItems.add(new SubtypeItem(item.mImeName, item.mSubtypeName, item.mLayoutName,
+ item.mImi, item.mSubtypeIndex));
}
return menuItems;
@@ -348,6 +348,13 @@
@Nullable
final CharSequence mSubtypeName;
+ /**
+ * The name of the subtype's layout, or {@code null} if this item doesn't have a subtype,
+ * or doesn't specify a layout.
+ */
+ @Nullable
+ private final CharSequence mLayoutName;
+
/** The info of the input method. */
@NonNull
final InputMethodInfo mImi;
@@ -360,10 +367,11 @@
final int mSubtypeIndex;
SubtypeItem(@NonNull CharSequence imeName, @Nullable CharSequence subtypeName,
- @NonNull InputMethodInfo imi,
+ @Nullable CharSequence layoutName, @NonNull InputMethodInfo imi,
@IntRange(from = NOT_A_SUBTYPE_INDEX) int subtypeIndex) {
mImeName = imeName;
mSubtypeName = subtypeName;
+ mLayoutName = layoutName;
mImi = imi;
mSubtypeIndex = subtypeIndex;
}
@@ -521,6 +529,9 @@
/** The name of the item. */
@NonNull
private final TextView mName;
+ /** The layout name. */
+ @NonNull
+ private final TextView mLayout;
/** Indicator for the selected status of the item. */
@NonNull
private final ImageView mCheckmark;
@@ -536,6 +547,7 @@
mContainer = itemView;
mName = itemView.requireViewById(com.android.internal.R.id.text);
+ mLayout = itemView.requireViewById(com.android.internal.R.id.text2);
mCheckmark = itemView.requireViewById(com.android.internal.R.id.image);
mContainer.setOnClickListener((v) -> {
@@ -563,6 +575,9 @@
// Trigger the ellipsize marquee behaviour by selecting the name.
mName.setSelected(isSelected);
mName.setText(name);
+ mLayout.setText(item.mLayoutName);
+ mLayout.setVisibility(
+ !TextUtils.isEmpty(item.mLayoutName) ? View.VISIBLE : View.GONE);
mCheckmark.setVisibility(isSelected ? View.VISIBLE : View.GONE);
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
index 96b3e08..51b85e9 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -85,6 +85,12 @@
public final CharSequence mImeName;
@Nullable
public final CharSequence mSubtypeName;
+ /**
+ * The subtype's layout name, or {@code null} if this item doesn't have a subtype,
+ * or doesn't specify a layout.
+ */
+ @Nullable
+ public final CharSequence mLayoutName;
@NonNull
public final InputMethodInfo mImi;
/**
@@ -96,10 +102,11 @@
public final boolean mIsSystemLanguage;
ImeSubtypeListItem(@NonNull CharSequence imeName, @Nullable CharSequence subtypeName,
- @NonNull InputMethodInfo imi, int subtypeIndex, @Nullable String subtypeLocale,
- @NonNull String systemLocale) {
+ @Nullable CharSequence layoutName, @NonNull InputMethodInfo imi, int subtypeIndex,
+ @Nullable String subtypeLocale, @NonNull String systemLocale) {
mImeName = imeName;
mSubtypeName = subtypeName;
+ mLayoutName = layoutName;
mImi = imi;
mSubtypeIndex = subtypeIndex;
if (TextUtils.isEmpty(subtypeLocale)) {
@@ -252,8 +259,11 @@
subtype.overridesImplicitlyEnabledSubtype() ? null : subtype
.getDisplayName(userAwareContext, imi.getPackageName(),
imi.getServiceInfo().applicationInfo);
- imList.add(new ImeSubtypeListItem(imeLabel,
- subtypeLabel, imi, j, subtype.getLocale(), mSystemLocaleStr));
+ final var layoutName = subtype.overridesImplicitlyEnabledSubtype() ? null
+ : subtype.getLayoutDisplayName(userAwareContext,
+ imi.getServiceInfo().applicationInfo);
+ imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, layoutName,
+ imi, j, subtype.getLocale(), mSystemLocaleStr));
// Removing this subtype from enabledSubtypeSet because we no
// longer need to add an entry of this subtype to imList to avoid
@@ -262,8 +272,8 @@
}
}
} else {
- imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_INDEX, null,
- mSystemLocaleStr));
+ imList.add(new ImeSubtypeListItem(imeLabel, null /* subtypeName */,
+ null /* layoutName */, imi, NOT_A_SUBTYPE_INDEX, null, mSystemLocaleStr));
}
}
Collections.sort(imList);
@@ -311,13 +321,16 @@
subtype.overridesImplicitlyEnabledSubtype() ? null : subtype
.getDisplayName(userAwareContext, imi.getPackageName(),
imi.getServiceInfo().applicationInfo);
- imList.add(new ImeSubtypeListItem(imeLabel,
- subtypeLabel, imi, j, subtype.getLocale(), mSystemLocaleStr));
+ final var layoutName = subtype.overridesImplicitlyEnabledSubtype() ? null
+ : subtype.getLayoutDisplayName(userAwareContext,
+ imi.getServiceInfo().applicationInfo);
+ imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, layoutName,
+ imi, j, subtype.getLocale(), mSystemLocaleStr));
}
}
} else {
- imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_INDEX, null,
- mSystemLocaleStr));
+ imList.add(new ImeSubtypeListItem(imeLabel, null /* subtypeName */,
+ null /* layoutName */, imi, NOT_A_SUBTYPE_INDEX, null, mSystemLocaleStr));
}
}
return imList;
diff --git a/services/core/java/com/android/server/media/AudioManagerRouteController.java b/services/core/java/com/android/server/media/AudioManagerRouteController.java
index 6bc4098..0f65d1d 100644
--- a/services/core/java/com/android/server/media/AudioManagerRouteController.java
+++ b/services/core/java/com/android/server/media/AudioManagerRouteController.java
@@ -662,8 +662,6 @@
MediaRoute2Info.TYPE_HDMI_EARC,
/* defaultRouteId= */ "ROUTE_ID_HDMI_EARC",
/* nameResource= */ R.string.default_audio_route_name_external_device));
- // TODO: b/305199571 - Add a proper type constants and human readable names for AUX_LINE,
- // LINE_ANALOG, LINE_DIGITAL, BLE_BROADCAST, BLE_SPEAKER, BLE_HEADSET, and HEARING_AID.
AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
AudioDeviceInfo.TYPE_HEARING_AID,
new SystemRouteInfo(
@@ -691,19 +689,22 @@
AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
AudioDeviceInfo.TYPE_LINE_DIGITAL,
new SystemRouteInfo(
- MediaRoute2Info.TYPE_UNKNOWN,
+ com.android.media.flags.Flags.enableNewWiredMediaRoute2InfoTypes()
+ ? MediaRoute2Info.TYPE_LINE_DIGITAL : MediaRoute2Info.TYPE_UNKNOWN,
/* defaultRouteId= */ "ROUTE_ID_LINE_DIGITAL",
/* nameResource= */ R.string.default_audio_route_name_external_device));
AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
AudioDeviceInfo.TYPE_LINE_ANALOG,
new SystemRouteInfo(
- MediaRoute2Info.TYPE_UNKNOWN,
+ com.android.media.flags.Flags.enableNewWiredMediaRoute2InfoTypes()
+ ? MediaRoute2Info.TYPE_LINE_ANALOG : MediaRoute2Info.TYPE_UNKNOWN,
/* defaultRouteId= */ "ROUTE_ID_LINE_ANALOG",
/* nameResource= */ R.string.default_audio_route_name_external_device));
AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
AudioDeviceInfo.TYPE_AUX_LINE,
new SystemRouteInfo(
- MediaRoute2Info.TYPE_UNKNOWN,
+ com.android.media.flags.Flags.enableNewWiredMediaRoute2InfoTypes()
+ ? MediaRoute2Info.TYPE_AUX_LINE : MediaRoute2Info.TYPE_UNKNOWN,
/* defaultRouteId= */ "ROUTE_ID_AUX_LINE",
/* nameResource= */ R.string.default_audio_route_name_external_device));
AUDIO_DEVICE_INFO_TYPE_TO_ROUTE_INFO.put(
diff --git a/services/core/java/com/android/server/media/MediaSession2Record.java b/services/core/java/com/android/server/media/MediaSession2Record.java
index 89555a9..c8a8799 100644
--- a/services/core/java/com/android/server/media/MediaSession2Record.java
+++ b/services/core/java/com/android/server/media/MediaSession2Record.java
@@ -161,6 +161,11 @@
}
@Override
+ public void onGlobalPrioritySessionActiveChanged(boolean isGlobalPrioritySessionActive) {
+ // NA as MediaSession2 doesn't support UserEngagementStates for FGS.
+ }
+
+ @Override
public boolean sendMediaButton(String packageName, int pid, int uid, boolean asSystemService,
KeyEvent ke, int sequenceId, ResultReceiver cb) {
// TODO(jaewan): Implement.
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index d752429..668ee2a 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -230,51 +230,49 @@
private final Runnable mUserEngagementTimeoutExpirationRunnable =
() -> {
synchronized (mLock) {
- updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ true);
+ updateUserEngagedStateIfNeededLocked(
+ /* isTimeoutExpired= */ true,
+ /* isGlobalPrioritySessionActive= */ false);
}
};
@GuardedBy("mLock")
private @UserEngagementState int mUserEngagementState = USER_DISENGAGED;
- @IntDef({USER_PERMANENTLY_ENGAGED, USER_TEMPORARY_ENGAGED, USER_DISENGAGED})
+ @IntDef({USER_PERMANENTLY_ENGAGED, USER_TEMPORARILY_ENGAGED, USER_DISENGAGED})
@Retention(RetentionPolicy.SOURCE)
private @interface UserEngagementState {}
/**
- * Indicates that the session is active and in one of the user engaged states.
+ * Indicates that the session is {@linkplain MediaSession#isActive() active} and in one of the
+ * {@linkplain PlaybackState#isActive() active states}.
*
* @see #updateUserEngagedStateIfNeededLocked(boolean)
*/
private static final int USER_PERMANENTLY_ENGAGED = 0;
/**
- * Indicates that the session is active and in {@link PlaybackState#STATE_PAUSED} state.
+ * Indicates that the session is {@linkplain MediaSession#isActive() active} and has recently
+ * switched to one of the {@linkplain PlaybackState#isActive() inactive states}.
*
* @see #updateUserEngagedStateIfNeededLocked(boolean)
*/
- private static final int USER_TEMPORARY_ENGAGED = 1;
+ private static final int USER_TEMPORARILY_ENGAGED = 1;
/**
- * Indicates that the session is either not active or in one of the user disengaged states
+ * Indicates that the session is either not {@linkplain MediaSession#isActive() active} or in
+ * one of the {@linkplain PlaybackState#isActive() inactive states}.
*
* @see #updateUserEngagedStateIfNeededLocked(boolean)
*/
private static final int USER_DISENGAGED = 2;
/**
- * Indicates the duration of the temporary engaged states, in milliseconds.
+ * Indicates the duration of the temporary engaged state, in milliseconds.
*
- * <p>Some {@link MediaSession} states like {@link PlaybackState#STATE_PAUSED} are temporarily
- * engaged, meaning the corresponding session is only considered in an engaged state for the
- * duration of this timeout, and only if coming from an engaged state.
- *
- * <p>For example, if a session is transitioning from a user-engaged state {@link
- * PlaybackState#STATE_PLAYING} to a temporary user-engaged state {@link
- * PlaybackState#STATE_PAUSED}, then the session will be considered in a user-engaged state for
- * the duration of this timeout, starting at the transition instant. However, a temporary
- * user-engaged state is not considered user-engaged when transitioning from a non-user engaged
- * state {@link PlaybackState#STATE_STOPPED}.
+ * <p>When switching to an {@linkplain PlaybackState#isActive() inactive state}, the user is
+ * treated as temporarily engaged, meaning the corresponding session is only considered in an
+ * engaged state for the duration of this timeout, and only if coming from an engaged state.
*/
private static final int TEMP_USER_ENGAGED_TIMEOUT_MS = 600000;
@@ -598,7 +596,8 @@
mSessionCb.mCb.asBinder().unlinkToDeath(this, 0);
mDestroyed = true;
mPlaybackState = null;
- updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ true);
+ updateUserEngagedStateIfNeededLocked(
+ /* isTimeoutExpired= */ true, /* isGlobalPrioritySessionActive= */ false);
mHandler.post(MessageHandler.MSG_DESTROYED);
}
}
@@ -615,6 +614,24 @@
mHandler.post(mUserEngagementTimeoutExpirationRunnable);
}
+ @Override
+ public void onGlobalPrioritySessionActiveChanged(boolean isGlobalPrioritySessionActive) {
+ mHandler.post(
+ () -> {
+ synchronized (mLock) {
+ if (isGlobalPrioritySessionActive) {
+ mHandler.removeCallbacks(mUserEngagementTimeoutExpirationRunnable);
+ } else {
+ if (mUserEngagementState == USER_TEMPORARILY_ENGAGED) {
+ mHandler.postDelayed(
+ mUserEngagementTimeoutExpirationRunnable,
+ TEMP_USER_ENGAGED_TIMEOUT_MS);
+ }
+ }
+ }
+ });
+ }
+
/**
* Sends media button.
*
@@ -1063,21 +1080,20 @@
}
@GuardedBy("mLock")
- private void updateUserEngagedStateIfNeededLocked(boolean isTimeoutExpired) {
+ private void updateUserEngagedStateIfNeededLocked(
+ boolean isTimeoutExpired, boolean isGlobalPrioritySessionActive) {
if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
return;
}
int oldUserEngagedState = mUserEngagementState;
int newUserEngagedState;
- if (!isActive() || mPlaybackState == null || mDestroyed) {
+ if (!isActive() || mPlaybackState == null) {
newUserEngagedState = USER_DISENGAGED;
- } else if (isActive() && mPlaybackState.isActive()) {
+ } else if (mPlaybackState.isActive()) {
newUserEngagedState = USER_PERMANENTLY_ENGAGED;
- } else if (mPlaybackState.getState() == PlaybackState.STATE_PAUSED) {
- newUserEngagedState =
- oldUserEngagedState == USER_PERMANENTLY_ENGAGED || !isTimeoutExpired
- ? USER_TEMPORARY_ENGAGED
- : USER_DISENGAGED;
+ } else if (oldUserEngagedState == USER_PERMANENTLY_ENGAGED
+ || (oldUserEngagedState == USER_TEMPORARILY_ENGAGED && !isTimeoutExpired)) {
+ newUserEngagedState = USER_TEMPORARILY_ENGAGED;
} else {
newUserEngagedState = USER_DISENGAGED;
}
@@ -1086,7 +1102,7 @@
}
mUserEngagementState = newUserEngagedState;
- if (newUserEngagedState == USER_TEMPORARY_ENGAGED) {
+ if (newUserEngagedState == USER_TEMPORARILY_ENGAGED && !isGlobalPrioritySessionActive) {
mHandler.postDelayed(
mUserEngagementTimeoutExpirationRunnable, TEMP_USER_ENGAGED_TIMEOUT_MS);
} else {
@@ -1141,9 +1157,11 @@
.logFgsApiEnd(ActivityManager.FOREGROUND_SERVICE_API_TYPE_MEDIA_PLAYBACK,
callingUid, callingPid);
}
+ boolean isGlobalPrioritySessionActive = mService.isGlobalPrioritySessionActive();
synchronized (mLock) {
mIsActive = active;
- updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ false);
+ updateUserEngagedStateIfNeededLocked(
+ /* isTimeoutExpired= */ false, isGlobalPrioritySessionActive);
}
long token = Binder.clearCallingIdentity();
try {
@@ -1300,9 +1318,11 @@
boolean shouldUpdatePriority = ALWAYS_PRIORITY_STATES.contains(newState)
|| (!TRANSITION_PRIORITY_STATES.contains(oldState)
&& TRANSITION_PRIORITY_STATES.contains(newState));
+ boolean isGlobalPrioritySessionActive = mService.isGlobalPrioritySessionActive();
synchronized (mLock) {
mPlaybackState = state;
- updateUserEngagedStateIfNeededLocked(/* isTimeoutExpired= */ false);
+ updateUserEngagedStateIfNeededLocked(
+ /* isTimeoutExpired= */ false, isGlobalPrioritySessionActive);
}
final long token = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java
index 15f90d4..6c3b123 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java
@@ -206,6 +206,10 @@
*/
public abstract void expireTempEngaged();
+ /** Notifies record that the global priority session active state changed. */
+ public abstract void onGlobalPrioritySessionActiveChanged(
+ boolean isGlobalPrioritySessionActive);
+
@Override
public final boolean equals(Object o) {
if (this == o) return true;
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 1ebc856..2b29fbd 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -362,6 +362,7 @@
+ record.isActive());
}
user.pushAddressedPlayerChangedLocked();
+ mHandler.post(this::notifyGlobalPrioritySessionActiveChanged);
} else {
if (!user.mPriorityStack.contains(record)) {
Log.w(TAG, "Unknown session updated. Ignoring.");
@@ -394,11 +395,16 @@
// Currently only media1 can become global priority session.
void setGlobalPrioritySession(MediaSessionRecord record) {
+ boolean globalPrioritySessionActiveChanged = false;
synchronized (mLock) {
FullUserRecord user = getFullUserRecordLocked(record.getUserId());
if (mGlobalPrioritySession != record) {
Log.d(TAG, "Global priority session is changed from " + mGlobalPrioritySession
+ " to " + record);
+ globalPrioritySessionActiveChanged =
+ (mGlobalPrioritySession == null && record.isActive())
+ || (mGlobalPrioritySession != null
+ && mGlobalPrioritySession.isActive() != record.isActive());
mGlobalPrioritySession = record;
if (user != null && user.mPriorityStack.contains(record)) {
// Handle the global priority session separately.
@@ -409,6 +415,30 @@
}
}
}
+ if (globalPrioritySessionActiveChanged) {
+ mHandler.post(this::notifyGlobalPrioritySessionActiveChanged);
+ }
+ }
+
+ /** Returns whether the global priority session is active. */
+ boolean isGlobalPrioritySessionActive() {
+ synchronized (mLock) {
+ return isGlobalPriorityActiveLocked();
+ }
+ }
+
+ private void notifyGlobalPrioritySessionActiveChanged() {
+ if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
+ return;
+ }
+ synchronized (mLock) {
+ boolean isGlobalPriorityActive = isGlobalPriorityActiveLocked();
+ for (Set<MediaSessionRecordImpl> records : mUserEngagedSessionsForFgs.values()) {
+ for (MediaSessionRecordImpl record : records) {
+ record.onGlobalPrioritySessionActiveChanged(isGlobalPriorityActive);
+ }
+ }
+ }
}
private List<MediaSessionRecord> getActiveSessionsLocked(int userId) {
@@ -646,8 +676,11 @@
if (mGlobalPrioritySession == session) {
mGlobalPrioritySession = null;
- if (session.isActive() && user != null) {
- user.pushAddressedPlayerChangedLocked();
+ if (session.isActive()) {
+ if (user != null) {
+ user.pushAddressedPlayerChangedLocked();
+ }
+ mHandler.post(this::notifyGlobalPrioritySessionActiveChanged);
}
} else {
if (user != null) {
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 6681e36..5febd5c 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -25,8 +25,10 @@
import static android.app.Notification.VISIBILITY_PRIVATE;
import static android.app.Notification.VISIBILITY_PUBLIC;
import static android.service.notification.Flags.notificationForceGrouping;
+import static android.service.notification.Flags.notificationRegroupOnClassification;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -49,6 +51,9 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -83,10 +88,22 @@
// with less than this value, they will be forced grouped
private static final int MIN_CHILD_COUNT_TO_AVOID_FORCE_GROUPING = 3;
+ // Regrouping needed because the channel was updated, ie. importance changed
+ static final int REGROUP_REASON_CHANNEL_UPDATE = 0;
+ // Regrouping needed because of notification bundling
+ static final int REGROUP_REASON_BUNDLE = 1;
+
+ @IntDef(prefix = { "REGROUP_REASON_" }, value = {
+ REGROUP_REASON_CHANNEL_UPDATE,
+ REGROUP_REASON_BUNDLE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface RegroupingReason {}
private final Callback mCallback;
private final int mAutoGroupAtCount;
private final int mAutogroupSparseGroupsAtCount;
+ private final int mAutoGroupRegroupingAtCount;
private final Context mContext;
private final PackageManager mPackageManager;
private boolean mIsTestHarnessExempted;
@@ -173,6 +190,11 @@
mContext = context;
mPackageManager = packageManager;
mAutogroupSparseGroupsAtCount = autoGroupSparseGroupsAtCount;
+ if (notificationRegroupOnClassification()) {
+ mAutoGroupRegroupingAtCount = 1;
+ } else {
+ mAutoGroupRegroupingAtCount = mAutoGroupAtCount;
+ }
NOTIFICATION_SHADE_SECTIONS = getNotificationShadeSections();
}
@@ -865,7 +887,8 @@
}
}
- regroupNotifications(userId, pkgName, notificationsToCheck);
+ regroupNotifications(userId, pkgName, notificationsToCheck,
+ REGROUP_REASON_CHANNEL_UPDATE);
}
}
@@ -883,13 +906,14 @@
ArrayMap<String, NotificationRecord> notificationsToCheck = new ArrayMap<>();
notificationsToCheck.put(record.getKey(), record);
regroupNotifications(record.getUserId(), record.getSbn().getPackageName(),
- notificationsToCheck);
+ notificationsToCheck, REGROUP_REASON_BUNDLE);
}
}
@GuardedBy("mAggregatedNotifications")
private void regroupNotifications(int userId, String pkgName,
- ArrayMap<String, NotificationRecord> notificationsToCheck) {
+ ArrayMap<String, NotificationRecord> notificationsToCheck,
+ @RegroupingReason int regroupingReason) {
// The list of notification operations required after the channel update
final ArrayList<NotificationMoveOp> notificationsToMove = new ArrayList<>();
@@ -904,12 +928,42 @@
notificationsToMove.addAll(
getUngroupedNotificationsMoveOps(userId, pkgName, notificationsToCheck));
+ // Handle "grouped correctly" notifications that were re-classified (bundled)
+ if (notificationRegroupOnClassification()) {
+ if (regroupingReason == REGROUP_REASON_BUNDLE) {
+ notificationsToMove.addAll(
+ getReclassifiedNotificationsMoveOps(userId, pkgName, notificationsToCheck));
+ }
+ }
+
// Batch move to new section
if (!notificationsToMove.isEmpty()) {
moveNotificationsToNewSection(userId, pkgName, notificationsToMove);
}
}
+ private List<NotificationMoveOp> getReclassifiedNotificationsMoveOps(int userId,
+ String pkgName, ArrayMap<String, NotificationRecord> notificationsToCheck) {
+ final ArrayList<NotificationMoveOp> notificationsToMove = new ArrayList<>();
+ for (NotificationRecord record : notificationsToCheck.values()) {
+ if (isChildOfValidAppGroup(record)) {
+ // Check if section changes
+ NotificationSectioner sectioner = getSection(record);
+ if (sectioner != null) {
+ FullyQualifiedGroupKey newFullAggregateGroupKey =
+ new FullyQualifiedGroupKey(userId, pkgName, sectioner);
+ if (DEBUG) {
+ Slog.v(TAG, "Regroup after classification: " + record + " to: "
+ + newFullAggregateGroupKey);
+ }
+ notificationsToMove.add(
+ new NotificationMoveOp(record, null, newFullAggregateGroupKey));
+ }
+ }
+ }
+ return notificationsToMove;
+ }
+
@GuardedBy("mAggregatedNotifications")
private List<NotificationMoveOp> getAutogroupedNotificationsMoveOps(int userId, String pkgName,
ArrayMap<String, NotificationRecord> notificationsToCheck) {
@@ -1010,6 +1064,10 @@
// Bundled operations to apply to groups affected by the channel update
ArrayMap<FullyQualifiedGroupKey, GroupUpdateOp> groupsToUpdate = new ArrayMap<>();
+ // App-provided (valid) groups of notifications that were classified (bundled).
+ // Summaries will be canceled if all child notifications have been bundled.
+ ArrayMap<String, String> originalGroupsOfBundledNotifications = new ArrayMap<>();
+
for (NotificationMoveOp moveOp: notificationsToMove) {
final NotificationRecord record = moveOp.record;
final FullyQualifiedGroupKey oldFullAggregateGroupKey = moveOp.oldGroup;
@@ -1035,6 +1093,13 @@
groupsToUpdate.put(oldFullAggregateGroupKey,
new GroupUpdateOp(oldFullAggregateGroupKey, record, true));
}
+ } else {
+ if (notificationRegroupOnClassification()) {
+ // Null "old aggregate group" => this notification was re-classified from
+ // a valid app-provided group => maybe cancel the original summary
+ // if no children are left
+ originalGroupsOfBundledNotifications.put(record.getKey(), record.getGroupKey());
+ }
}
// Add moved notifications to the ungrouped list for new group and do grouping
@@ -1076,7 +1141,7 @@
NotificationRecord triggeringNotification = groupsToUpdate.get(groupKey).record;
boolean hasSummary = groupsToUpdate.get(groupKey).hasSummary;
//Group needs to be created/updated
- if (ungrouped.size() >= mAutoGroupAtCount
+ if (ungrouped.size() >= mAutoGroupRegroupingAtCount
|| (hasSummary && !aggregatedNotificationsAttrs.isEmpty())) {
NotificationSectioner sectioner = getSection(triggeringNotification);
if (sectioner == null) {
@@ -1092,6 +1157,18 @@
}
}
}
+
+ if (notificationRegroupOnClassification()) {
+ // Cancel the summary if it's the last notification of the original app-provided group
+ for (String triggeringKey : originalGroupsOfBundledNotifications.keySet()) {
+ NotificationRecord canceledSummary =
+ mCallback.removeAppProvidedSummaryOnClassification(triggeringKey,
+ originalGroupsOfBundledNotifications.getOrDefault(triggeringKey, null));
+ if (canceledSummary != null) {
+ cacheCanceledSummary(canceledSummary);
+ }
+ }
+ }
}
static String getFullAggregateGroupKey(String pkgName,
@@ -1113,6 +1190,42 @@
return (record.mOriginalFlags & Notification.FLAG_AUTOGROUP_SUMMARY) != 0;
}
+ private boolean isNotificationAggregatedInSection(NotificationRecord record,
+ NotificationSectioner sectioner) {
+ final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
+ record.getUserId(), record.getSbn().getPackageName(), sectioner);
+ return record.getGroupKey().equals(fullAggregateGroupKey.toString());
+ }
+
+ private boolean isChildOfValidAppGroup(NotificationRecord record) {
+ final StatusBarNotification sbn = record.getSbn();
+ if (!sbn.isAppGroup()) {
+ return false;
+ }
+
+ if (!sbn.getNotification().isGroupChild()) {
+ return false;
+ }
+
+ if (record.isCanceled) {
+ return false;
+ }
+
+ final NotificationSectioner sectioner = getSection(record);
+ if (sectioner == null) {
+ if (DEBUG) {
+ Slog.i(TAG, "Skipping autogrouping for " + record + " no valid section found.");
+ }
+ return false;
+ }
+
+ if (isNotificationAggregatedInSection(record, sectioner)) {
+ return false;
+ }
+
+ return true;
+ }
+
private static int getNumChildrenForGroup(@NonNull final String groupKey,
final List<NotificationRecord> notificationList) {
//TODO (b/349072751): track grouping state in GroupHelper -> do not use notificationList
@@ -1438,6 +1551,48 @@
}
}
+ protected void dump(PrintWriter pw, String prefix) {
+ synchronized (mAggregatedNotifications) {
+ if (!mUngroupedAbuseNotifications.isEmpty()) {
+ pw.println(prefix + "Ungrouped notifications:");
+ for (FullyQualifiedGroupKey groupKey: mUngroupedAbuseNotifications.keySet()) {
+ if (!mUngroupedAbuseNotifications.getOrDefault(groupKey, new ArrayMap<>())
+ .isEmpty()) {
+ pw.println(prefix + prefix + groupKey.toString());
+ for (String notifKey : mUngroupedAbuseNotifications.get(groupKey)
+ .keySet()) {
+ pw.println(prefix + prefix + prefix + notifKey);
+ }
+ }
+ }
+ pw.println("");
+ }
+
+ if (!mAggregatedNotifications.isEmpty()) {
+ pw.println(prefix + "Autogrouped notifications:");
+ for (FullyQualifiedGroupKey groupKey: mAggregatedNotifications.keySet()) {
+ if (!mAggregatedNotifications.getOrDefault(groupKey, new ArrayMap<>())
+ .isEmpty()) {
+ pw.println(prefix + prefix + groupKey.toString());
+ for (String notifKey : mAggregatedNotifications.get(groupKey).keySet()) {
+ pw.println(prefix + prefix + prefix + notifKey);
+ }
+ }
+ }
+ pw.println("");
+ }
+
+ if (!mCanceledSummaries.isEmpty()) {
+ pw.println(prefix + "Cached canceled summaries:");
+ for (CachedSummary summary: mCanceledSummaries.values()) {
+ pw.println(prefix + prefix + prefix + summary.key + " -> "
+ + summary.originalGroupKey);
+ }
+ pw.println("");
+ }
+ }
+ }
+
protected static class NotificationSectioner {
final String mName;
final int mSummaryId;
@@ -1551,5 +1706,16 @@
void removeNotificationFromCanceledGroup(int userId, String pkg, String groupKey,
int cancelReason);
+
+ /**
+ * Cancels the group summary of a notification that was regrouped because of classification
+ * (bundling). Only cancels if the summary is the last notification of the original group.
+ * @param triggeringKey the triggering child notification key
+ * @param groupKey the original group key
+ * @return the canceled group summary or null if the summary was not canceled
+ */
+ @Nullable
+ NotificationRecord removeAppProvidedSummaryOnClassification(String triggeringKey,
+ @Nullable String groupKey);
}
}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 122836e..93482e7 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -21,9 +21,6 @@
import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.Context.DEVICE_POLICY_SERVICE;
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
-import static android.content.pm.PackageManager.MATCH_INSTANT;
import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_SYSTEM;
import static android.service.notification.NotificationListenerService.META_DATA_DEFAULT_AUTOBIND;
@@ -109,8 +106,7 @@
protected final String TAG = getClass().getSimpleName().replace('$', '.');
protected final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- protected static final int ON_BINDING_DIED_REBIND_DELAY_MS = 10000;
- protected static final int ON_BINDING_DIED_REBIND_MSG = 1234;
+ private static final int ON_BINDING_DIED_REBIND_DELAY_MS = 10000;
protected static final String ENABLED_SERVICES_SEPARATOR = ":";
private static final String DB_VERSION_1 = "1";
private static final String DB_VERSION_2 = "2";
@@ -879,21 +875,7 @@
String approvedItem = getApprovedValue(pkgOrComponent);
if (approvedItem != null) {
- final ComponentName component = ComponentName.unflattenFromString(approvedItem);
if (enabled) {
- if (Flags.notificationNlsRebind()) {
- if (component != null && !isValidService(component, userId)) {
- // Only fail if package is available
- // If not, it will be validated again in onPackagesChanged
- final PackageManager pm = mContext.getPackageManager();
- if (pm.isPackageAvailable(component.getPackageName())) {
- Slog.w(TAG, "Skip allowing " + mConfig.caption
- + " " + pkgOrComponent + " (userSet: " + userSet
- + ") for invalid service");
- return;
- }
- }
- }
approved.add(approvedItem);
} else {
approved.remove(approvedItem);
@@ -991,7 +973,7 @@
|| isPackageOrComponentAllowed(component.getPackageName(), userId))) {
return false;
}
- return isValidService(component, userId);
+ return componentHasBindPermission(component, userId);
}
private boolean componentHasBindPermission(ComponentName component, int userId) {
@@ -1238,21 +1220,12 @@
if (!TextUtils.isEmpty(packageName)) {
queryIntent.setPackage(packageName);
}
-
- if (Flags.notificationNlsRebind()) {
- // Expand the package query
- extraFlags |= MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
- extraFlags |= MATCH_INSTANT;
- }
-
List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser(
queryIntent,
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA | extraFlags,
userId);
- if (DEBUG) {
- Slog.v(TAG, mConfig.serviceInterface + " pkg: " + packageName + " services: "
- + installedServices);
- }
+ if (DEBUG)
+ Slog.v(TAG, mConfig.serviceInterface + " services: " + installedServices);
if (installedServices != null) {
for (int i = 0, count = installedServices.size(); i < count; i++) {
ResolveInfo resolveInfo = installedServices.get(i);
@@ -1352,12 +1325,11 @@
if (TextUtils.equals(getPackageName(approvedPackageOrComponent), packageName)) {
final ComponentName component = ComponentName.unflattenFromString(
approvedPackageOrComponent);
- if (component != null && !isValidService(component, userId)) {
+ if (component != null && !componentHasBindPermission(component, userId)) {
approved.removeAt(j);
if (DEBUG) {
Slog.v(TAG, "Removing " + approvedPackageOrComponent
- + " from approved list; no bind permission or "
- + "service interface filter found "
+ + " from approved list; no bind permission found "
+ mConfig.bindPermission);
}
}
@@ -1376,15 +1348,6 @@
}
}
- protected boolean isValidService(ComponentName component, int userId) {
- if (Flags.notificationNlsRebind()) {
- return componentHasBindPermission(component, userId) && queryPackageForServices(
- component.getPackageName(), userId).contains(component);
- } else {
- return componentHasBindPermission(component, userId);
- }
- }
-
protected boolean isValidEntry(String packageOrComponent, int userId) {
return hasMatchingServices(packageOrComponent, userId);
}
@@ -1542,27 +1505,23 @@
* Called when user switched to unbind all services from other users.
*/
@VisibleForTesting
- void unbindOtherUserServices(int switchedToUser) {
+ void unbindOtherUserServices(int currentUser) {
TimingsTraceAndSlog t = new TimingsTraceAndSlog();
- t.traceBegin("ManagedServices.unbindOtherUserServices_current" + switchedToUser);
- unbindServicesImpl(switchedToUser, true /* allExceptUser */);
+ t.traceBegin("ManagedServices.unbindOtherUserServices_current" + currentUser);
+ unbindServicesImpl(currentUser, true /* allExceptUser */);
t.traceEnd();
}
- void unbindUserServices(int removedUser) {
+ void unbindUserServices(int user) {
TimingsTraceAndSlog t = new TimingsTraceAndSlog();
- t.traceBegin("ManagedServices.unbindUserServices" + removedUser);
- unbindServicesImpl(removedUser, false /* allExceptUser */);
+ t.traceBegin("ManagedServices.unbindUserServices" + user);
+ unbindServicesImpl(user, false /* allExceptUser */);
t.traceEnd();
}
void unbindServicesImpl(int user, boolean allExceptUser) {
final SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();
synchronized (mMutex) {
- if (Flags.notificationNlsRebind()) {
- // Remove enqueued rebinds to avoid rebinding services for a switched user
- mHandler.removeMessages(ON_BINDING_DIED_REBIND_MSG);
- }
final Set<ManagedServiceInfo> removableBoundServices = getRemovableConnectedServices();
for (ManagedServiceInfo info : removableBoundServices) {
if ((allExceptUser && (info.userid != user))
@@ -1757,7 +1716,6 @@
mServicesRebinding.add(servicesBindingTag);
mHandler.postDelayed(() ->
reregisterService(name, userid),
- ON_BINDING_DIED_REBIND_MSG,
ON_BINDING_DIED_REBIND_DELAY_MS);
} else {
Slog.v(TAG, getCaption() + " not rebinding in user " + userid
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 2c45fc8..4d0c7ec 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -82,6 +82,8 @@
import static android.app.NotificationManager.zenModeFromInterruptionFilter;
import static android.app.StatusBarManager.ACTION_KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED;
import static android.app.StatusBarManager.EXTRA_KM_PRIVATE_NOTIFS_ALLOWED;
+import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG;
+import static android.app.backup.NotificationLoggingConstants.ERROR_XML_PARSING;
import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
@@ -162,8 +164,6 @@
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
-import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG;
-import static android.app.backup.NotificationLoggingConstants.ERROR_XML_PARSING;
import static com.android.server.notification.Flags.expireBitmaps;
import static com.android.server.policy.PhoneWindowManager.TOAST_WINDOW_ANIM_BUFFER;
import static com.android.server.policy.PhoneWindowManager.TOAST_WINDOW_TIMEOUT;
@@ -474,6 +474,10 @@
Adjustment.KEY_TYPE
};
+ static final Integer[] DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES = new Integer[] {
+ TYPE_PROMOTION
+ };
+
static final String[] NON_BLOCKABLE_DEFAULT_ROLES = new String[] {
RoleManager.ROLE_DIALER,
RoleManager.ROLE_EMERGENCY
@@ -1929,6 +1933,12 @@
hasSensitiveContent, lifespanMs);
}
+ protected void logClassificationChannelAdjustmentReceived(boolean hasPosted, boolean isAlerting,
+ int classification, int lifespanMs) {
+ FrameworkStatsLog.write(FrameworkStatsLog.NOTIFICATION_CHANNEL_CLASSIFICATION,
+ hasPosted, isAlerting, classification, lifespanMs);
+ }
+
protected final BroadcastReceiver mLocaleChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -2998,6 +3008,16 @@
groupKey, REASON_APP_CANCEL, SystemClock.elapsedRealtime());
}
}
+
+ @Override
+ @Nullable
+ public NotificationRecord removeAppProvidedSummaryOnClassification(String triggeringKey,
+ @Nullable String oldGroupKey) {
+ synchronized (mNotificationLock) {
+ return removeAppProvidedSummaryOnClassificationLocked(triggeringKey,
+ oldGroupKey);
+ }
+ }
});
}
@@ -4189,6 +4209,22 @@
}
@Override
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+ public @NonNull int[] getAllowedAdjustmentKeyTypes() {
+ checkCallerIsSystemOrSystemUiOrShell();
+ return mAssistants.getAllowedAdjustmentKeyTypes();
+ }
+
+ @Override
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+ public void setAssistantAdjustmentKeyTypeState(int type, boolean enabled) {
+ checkCallerIsSystemOrSystemUiOrShell();
+ mAssistants.setAssistantAdjustmentKeyTypeState(type, enabled);
+
+ handleSavePolicyFile();
+ }
+
+ @Override
@FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
public boolean appCanBePromoted(String pkg, int uid) {
checkCallerIsSystemOrSystemUiOrShell();
@@ -6977,19 +7013,30 @@
if (!mAssistants.isAdjustmentAllowed(potentialKey)) {
toRemove.add(potentialKey);
}
+ if (notificationClassification() && adjustments.containsKey(KEY_TYPE)) {
+ if (!mAssistants.isAdjustmentKeyTypeAllowed(adjustments.getInt(KEY_TYPE))) {
+ toRemove.add(potentialKey);
+ }
+ }
}
for (String removeKey : toRemove) {
adjustments.remove(removeKey);
}
- if (android.service.notification.Flags.notificationClassification()
- && adjustments.containsKey(KEY_TYPE)) {
+ if (notificationClassification() && adjustments.containsKey(KEY_TYPE)) {
final NotificationChannel newChannel = getClassificationChannelLocked(r,
adjustments);
if (newChannel == null || newChannel.getId().equals(r.getChannel().getId())) {
adjustments.remove(KEY_TYPE);
} else {
+ // Save the app-provided type for logging.
+ int classification = adjustments.getInt(KEY_TYPE);
// swap app provided type with the real thing
adjustments.putParcelable(KEY_TYPE, newChannel);
+ // Note that this value of isAlerting does not fully indicate whether a notif
+ // would make a sound or HUN on device; it is an approximation for metrics.
+ boolean isAlerting = r.getChannel().getImportance() >= IMPORTANCE_DEFAULT;
+ logClassificationChannelAdjustmentReceived(isPosted, isAlerting, classification,
+ r.getLifespanMs(System.currentTimeMillis()));
}
}
r.addAdjustment(adjustment);
@@ -7114,6 +7161,50 @@
}
@GuardedBy("mNotificationLock")
+ @Nullable
+ NotificationRecord removeAppProvidedSummaryOnClassificationLocked(String triggeringKey,
+ @Nullable String oldGroupKey) {
+ NotificationRecord canceledSummary = null;
+ NotificationRecord r = mNotificationsByKey.get(triggeringKey);
+ if (r == null || oldGroupKey == null) {
+ return null;
+ }
+
+ if (r.getSbn().isAppGroup() && r.getNotification().isGroupChild()) {
+ NotificationRecord groupSummary = mSummaryByGroupKey.get(oldGroupKey);
+ // We only care about app-provided valid groups
+ if (groupSummary != null && !GroupHelper.isAggregatedGroup(groupSummary)) {
+ List<NotificationRecord> notificationsInGroup =
+ findGroupNotificationsLocked(r.getSbn().getPackageName(),
+ oldGroupKey, r.getUserId());
+ // Remove the app-provided summary if only the summary is left in the
+ // original group, or summary + triggering notification that will be
+ // regrouped
+ boolean isOnlySummaryLeft =
+ (notificationsInGroup.size() <= 1)
+ || (notificationsInGroup.size() == 2
+ && notificationsInGroup.contains(r)
+ && notificationsInGroup.contains(groupSummary));
+ if (isOnlySummaryLeft) {
+ if (DBG) {
+ Slog.i(TAG, "Removing app summary (all children bundled): "
+ + groupSummary);
+ }
+ canceledSummary = groupSummary;
+ mSummaryByGroupKey.remove(oldGroupKey);
+ cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(),
+ groupSummary.getSbn().getPackageName(),
+ groupSummary.getSbn().getTag(),
+ groupSummary.getSbn().getId(), 0, 0, false, groupSummary.getUserId(),
+ NotificationListenerService.REASON_GROUP_OPTIMIZATION, null);
+ }
+ }
+ }
+
+ return canceledSummary;
+ }
+
+ @GuardedBy("mNotificationLock")
private boolean hasAutoGroupSummaryLocked(NotificationRecord record) {
final String autbundledGroupKey;
if (notificationForceGrouping()) {
@@ -7493,6 +7584,11 @@
mTtlHelper.dump(pw, " ");
}
}
+
+ if (notificationForceGrouping()) {
+ pw.println("\n GroupHelper:");
+ mGroupHelper.dump(pw, " ");
+ }
}
}
@@ -7770,10 +7866,11 @@
// Make Notification silent
r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE;
- // Repost
+ // Repost as the original app (even if it was posted by a delegate originally
+ // because the delegate may now be revoked)
enqueueNotificationInternal(r.getSbn().getPackageName(),
- r.getSbn().getOpPkg(), r.getSbn().getUid(),
- r.getSbn().getInitialPid(), r.getSbn().getTag(),
+ r.getSbn().getPackageName(), r.getSbn().getUid(),
+ MY_PID, r.getSbn().getTag(),
r.getSbn().getId(), r.getNotification(),
r.getSbn().getUserId(), /* postSilently= */ true,
/* byForegroundService= */ false,
@@ -8012,7 +8109,6 @@
r.setPkgAllowedAsConvo(mMsgPkgsAllowedAsConvos.contains(pkg));
boolean isImportanceFixed = mPermissionHelper.isPermissionFixed(pkg, userId);
r.setImportanceFixed(isImportanceFixed);
-
if (notification.isFgsOrUij()) {
if (((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
|| !channel.isUserVisibleTaskShown())
@@ -11552,11 +11648,15 @@
private static final String ATT_TYPES = "types";
private static final String ATT_DENIED = "denied_adjustments";
+ private static final String ATT_ENABLED_TYPES = "enabled_key_types";
private static final String ATT_NAS_UNSUPPORTED = "unsupported_adjustments";
private final Object mLock = new Object();
@GuardedBy("mLock")
+ private Set<Integer> mAllowedAdjustmentKeyTypes = new ArraySet<>();
+
+ @GuardedBy("mLock")
private Set<String> mAllowedAdjustments = new ArraySet<>();
@GuardedBy("mLock")
@@ -11639,6 +11739,8 @@
for (int i = 0; i < DEFAULT_ALLOWED_ADJUSTMENTS.length; i++) {
mAllowedAdjustments.add(DEFAULT_ALLOWED_ADJUSTMENTS[i]);
}
+ } else {
+ mAllowedAdjustmentKeyTypes.addAll(List.of(DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES));
}
}
@@ -11726,6 +11828,42 @@
}
}
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+ protected @NonNull boolean isAdjustmentKeyTypeAllowed(@Adjustment.Types int type) {
+ synchronized (mLock) {
+ if (notificationClassification()) {
+ return mAllowedAdjustmentKeyTypes.contains(type);
+ }
+ }
+ return false;
+ }
+
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+ protected @NonNull int[] getAllowedAdjustmentKeyTypes() {
+ synchronized (mLock) {
+ if (notificationClassification()) {
+ return mAllowedAdjustmentKeyTypes.stream()
+ .mapToInt(Integer::intValue).toArray();
+ }
+ }
+ return new int[]{};
+ }
+
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+ public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type,
+ boolean enabled) {
+ if (!android.service.notification.Flags.notificationClassification()) {
+ return;
+ }
+ synchronized (mLock) {
+ if (enabled) {
+ mAllowedAdjustmentKeyTypes.add(type);
+ } else {
+ mAllowedAdjustmentKeyTypes.remove(type);
+ }
+ }
+ }
+
protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) {
for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
ArrayList<String> keys = new ArrayList<>(records.size());
@@ -12165,27 +12303,46 @@
@Override
protected void writeExtraXmlTags(TypedXmlSerializer out) throws IOException {
- if (!android.service.notification.Flags.notificationClassification()) {
+ if (!notificationClassification()) {
return;
}
synchronized (mLock) {
out.startTag(null, ATT_DENIED);
out.attribute(null, ATT_TYPES, TextUtils.join(",", mDeniedAdjustments));
out.endTag(null, ATT_DENIED);
+ out.startTag(null, ATT_ENABLED_TYPES);
+ out.attribute(null, ATT_TYPES,
+ TextUtils.join(",", mAllowedAdjustmentKeyTypes));
+ out.endTag(null, ATT_ENABLED_TYPES);
}
}
@Override
protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException {
- if (!android.service.notification.Flags.notificationClassification()) {
+ if (!notificationClassification()) {
return;
}
if (ATT_DENIED.equals(tag)) {
- final String types = XmlUtils.readStringAttribute(parser, ATT_TYPES);
+ final String keys = XmlUtils.readStringAttribute(parser, ATT_TYPES);
synchronized (mLock) {
mDeniedAdjustments.clear();
+ if (!TextUtils.isEmpty(keys)) {
+ mDeniedAdjustments.addAll(Arrays.asList(keys.split(",")));
+ }
+ }
+ } else if (ATT_ENABLED_TYPES.equals(tag)) {
+ final String types = XmlUtils.readStringAttribute(parser, ATT_TYPES);
+ synchronized (mLock) {
+ mAllowedAdjustmentKeyTypes.clear();
if (!TextUtils.isEmpty(types)) {
- mDeniedAdjustments.addAll(Arrays.asList(types.split(",")));
+ List<String> typeList = Arrays.asList(types.split(","));
+ for (String type : typeList) {
+ try {
+ mAllowedAdjustmentKeyTypes.add(Integer.parseInt(type));
+ } catch (NumberFormatException e) {
+ Slog.wtf(TAG, "Bad type specified", e);
+ }
+ }
}
}
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index d5f13a8..cfeacdf 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -2422,7 +2422,7 @@
|| (mSuppressedEffects & SUPPRESSED_EFFECT_NOTIFICATIONS) != 0;
// call restrictions
final boolean muteCalls = zenAlarmsOnly
- || (zenPriorityOnly && !(allowCalls || allowRepeatCallers))
+ || (zenPriorityOnly && (!allowCalls || !allowRepeatCallers))
|| (mSuppressedEffects & SUPPRESSED_EFFECT_CALLS) != 0;
// alarm restrictions
final boolean muteAlarms = zenPriorityOnly && !allowAlarms;
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index c479acf..f79d9ef 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -194,13 +194,3 @@
description: "Enables sound uri with vibration source in notification channel"
bug: "351975435"
}
-
-flag {
- name: "notification_nls_rebind"
- namespace: "systemui"
- description: "Check for NLS service intent filter when rebinding services"
- bug: "347674739"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
index 015b7fd..38f3939 100644
--- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java
+++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.content.om.OverlayInfo;
import android.content.om.OverlayableInfo;
+import android.content.res.Flags;
import android.net.Uri;
import android.os.Process;
import android.text.TextUtils;
@@ -162,11 +163,15 @@
return ActorState.UNABLE_TO_GET_TARGET_OVERLAYABLE;
}
- if (targetOverlayable == null) {
+ // Framework doesn't have <overlayable> declaration by design, and we still want to be able
+ // to enable its overlays from the packages with the permission.
+ if (targetOverlayable == null
+ && !(Flags.rroControlForAndroidNoOverlayable() && targetPackageName.equals(
+ "android"))) {
return ActorState.MISSING_OVERLAYABLE;
}
- String actor = targetOverlayable.actor;
+ final String actor = targetOverlayable == null ? null : targetOverlayable.actor;
if (TextUtils.isEmpty(actor)) {
// If there's no actor defined, fallback to the legacy permission check
try {
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 5653da0..2c09423 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -88,6 +88,7 @@
import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
import android.content.pm.UserInfo;
import android.content.pm.UserProperties;
+import android.database.ContentObserver;
import android.graphics.Rect;
import android.multiuser.Flags;
import android.net.Uri;
@@ -95,6 +96,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IInterface;
+import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteCallbackList;
@@ -249,6 +251,7 @@
private PackageInstallerService mPackageInstallerService;
final LauncherAppsServiceInternal mInternal;
+ private SecureSettingsObserver mSecureSettingsObserver;
@NonNull
private final RemoteCallbackList<IDumpCallback> mDumpCallbacks =
@@ -278,6 +281,7 @@
mCallbackHandler = BackgroundThread.getHandler();
mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
mInternal = new LocalService();
+ registerSettingsObserver();
}
@VisibleForTesting
@@ -2312,6 +2316,13 @@
}
}
+ void registerSettingsObserver() {
+ if (Flags.addLauncherUserConfig()) {
+ mSecureSettingsObserver = new SecureSettingsObserver();
+ mSecureSettingsObserver.register();
+ }
+ }
+
public static class ShortcutChangeHandler implements LauncherApps.ShortcutChangeCallback {
private final UserManagerInternal mUserManagerInternal;
@@ -2837,5 +2848,84 @@
shortcutId, sourceBounds, startActivityOptions, targetUserId);
}
}
+
+ class SecureSettingsObserver extends ContentObserver {
+
+ SecureSettingsObserver() {
+ super(new Handler(Looper.getMainLooper()));
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ if (uri.equals(
+ Settings.Secure.getUriFor(Settings.Secure.HIDE_PRIVATESPACE_ENTRY_POINT))) {
+
+ // This setting key only apply to private profile at the moment
+ UserHandle privateProfile = getPrivateProfile();
+ if (privateProfile.getIdentifier() == UserHandle.USER_NULL) {
+ return;
+ }
+
+ final int n = mListeners.beginBroadcast();
+ try {
+ for (int i = 0; i < n; i++) {
+ final IOnAppsChangedListener listener =
+ mListeners.getBroadcastItem(i);
+ final BroadcastCookie cookie =
+ (BroadcastCookie) mListeners.getBroadcastCookie(
+ i);
+ if (!isEnabledProfileOf(cookie, privateProfile,
+ "onSecureSettingsChange")) {
+ Log.d(TAG, "onSecureSettingsChange: Skipping - profile not enabled"
+ + " or not accessible for package=" + cookie.packageName
+ + ", packageUid=" + cookie.callingUid);
+ } else {
+ try {
+ Log.d(TAG,
+ "onUserConfigChanged: triggering onUserConfigChanged");
+ listener.onUserConfigChanged(
+ mUserManagerInternal.getLauncherUserInfo(
+ privateProfile.getIdentifier()));
+ } catch (RemoteException re) {
+ Slog.d(TAG, "onUserConfigChanged: Callback failed ", re);
+ }
+ }
+ }
+ } finally {
+ mListeners.finishBroadcast();
+ }
+ }
+ }
+
+ public void register() {
+ UserHandle privateProfile = getPrivateProfile();
+ int parentUserId;
+ if (privateProfile.getIdentifier() == UserHandle.USER_NULL) {
+ // No private space available, register the observer for the current user
+ parentUserId = mContext.getUserId();
+ } else {
+ parentUserId = mUserManagerInternal.getProfileParentId(
+ privateProfile.getIdentifier());
+ }
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.HIDE_PRIVATESPACE_ENTRY_POINT),
+ true, this, parentUserId);
+ }
+
+ public void unregister() {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ }
+
+ private UserHandle getPrivateProfile() {
+ UserInfo[] userInfos = mUserManagerInternal.getUserInfos();
+ for (UserInfo u : userInfos) {
+ if (u.isPrivateProfile()) {
+ return UserHandle.of(u.id);
+ }
+ }
+ return UserHandle.of(UserHandle.USER_NULL);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 7ecfe7f..06e29c2 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -21,6 +21,7 @@
import static android.content.Intent.EXTRA_USER_ID;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.pm.LauncherUserInfo.PRIVATE_SPACE_ENTRYPOINT_HIDDEN;
import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
import static android.content.pm.PackageManager.FEATURE_EMBEDDED;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
@@ -32,6 +33,7 @@
import static android.os.UserManager.USER_OPERATION_ERROR_UNKNOWN;
import static android.os.UserManager.USER_OPERATION_ERROR_USER_RESTRICTED;
import static android.os.UserManager.USER_TYPE_PROFILE_PRIVATE;
+import static android.provider.Settings.Secure.HIDE_PRIVATESPACE_ENTRY_POINT;
import static com.android.internal.app.SetScreenLockDialogActivity.EXTRA_ORIGIN_USER_ID;
import static com.android.internal.app.SetScreenLockDialogActivity.LAUNCH_REASON_DISABLE_QUIET_MODE;
@@ -341,6 +343,10 @@
private static final String TRON_USER_CREATED = "users_user_created";
private static final String TRON_DEMO_CREATED = "users_demo_created";
+ // The boot user strategy for HSUM.
+ private static final int BOOT_TO_PREVIOUS_OR_FIRST_SWITCHABLE_USER = 0;
+ private static final int BOOT_TO_HSU_FOR_PROVISIONED_DEVICE = 1;
+
private final Context mContext;
private final PackageManagerService mPm;
@@ -1391,37 +1397,77 @@
}
if (isHeadlessSystemUserMode()) {
- if (mContext.getResources()
- .getBoolean(com.android.internal.R.bool.config_bootToHeadlessSystemUser)) {
- return UserHandle.USER_SYSTEM;
+ final int bootStrategy = mContext.getResources()
+ .getInteger(com.android.internal.R.integer.config_hsumBootStrategy);
+ switch (bootStrategy) {
+ case BOOT_TO_PREVIOUS_OR_FIRST_SWITCHABLE_USER:
+ return getPreviousOrFirstSwitchableUser();
+ case BOOT_TO_HSU_FOR_PROVISIONED_DEVICE:
+ return getBootUserBasedOnProvisioning();
+ default:
+ Slogf.w(LOG_TAG, "Unknown HSUM boot strategy: %d", bootStrategy);
+ return getPreviousOrFirstSwitchableUser();
}
- // Return the previous foreground user, if there is one.
- final int previousUser = getPreviousFullUserToEnterForeground();
- if (previousUser != UserHandle.USER_NULL) {
- Slogf.i(LOG_TAG, "Boot user is previous user %d", previousUser);
- return previousUser;
- }
- // No previous user. Return the first switchable user if there is one.
- synchronized (mUsersLock) {
- final int userSize = mUsers.size();
- for (int i = 0; i < userSize; i++) {
- final UserData userData = mUsers.valueAt(i);
- if (userData.info.supportsSwitchToByUser()) {
- int firstSwitchable = userData.info.id;
- Slogf.i(LOG_TAG,
- "Boot user is first switchable user %d", firstSwitchable);
- return firstSwitchable;
- }
- }
- }
- // No switchable users found. Uh oh!
- throw new UserManager.CheckedUserOperationException(
- "No switchable users found", USER_OPERATION_ERROR_UNKNOWN);
}
// Not HSUM, return system user.
return UserHandle.USER_SYSTEM;
}
+ private @UserIdInt int getBootUserBasedOnProvisioning()
+ throws UserManager.CheckedUserOperationException {
+ final boolean provisioned = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+ if (provisioned) {
+ return UserHandle.USER_SYSTEM;
+ } else {
+ final int firstSwitchableFullUser = getFirstSwitchableUser(true);
+ if (firstSwitchableFullUser != UserHandle.USER_NULL) {
+ Slogf.i(LOG_TAG,
+ "Boot user is first switchable full user %d",
+ firstSwitchableFullUser);
+ return firstSwitchableFullUser;
+ }
+ // No switchable full user found. Uh oh!
+ throw new UserManager.CheckedUserOperationException(
+ "No switchable full user found", USER_OPERATION_ERROR_UNKNOWN);
+ }
+ }
+
+ private @UserIdInt int getPreviousOrFirstSwitchableUser()
+ throws UserManager.CheckedUserOperationException {
+ // Return the previous foreground user, if there is one.
+ final int previousUser = getPreviousFullUserToEnterForeground();
+ if (previousUser != UserHandle.USER_NULL) {
+ Slogf.i(LOG_TAG, "Boot user is previous user %d", previousUser);
+ return previousUser;
+ }
+ // No previous user. Return the first switchable user if there is one.
+ final int firstSwitchableUser = getFirstSwitchableUser(false);
+ if (firstSwitchableUser != UserHandle.USER_NULL) {
+ Slogf.i(LOG_TAG,
+ "Boot user is first switchable user %d", firstSwitchableUser);
+ return firstSwitchableUser;
+ }
+ // No switchable users found. Uh oh!
+ throw new UserManager.CheckedUserOperationException(
+ "No switchable users found", USER_OPERATION_ERROR_UNKNOWN);
+ }
+
+ private @UserIdInt int getFirstSwitchableUser(boolean fullUserOnly) {
+ synchronized (mUsersLock) {
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
+ final UserData userData = mUsers.valueAt(i);
+ if (userData.info.supportsSwitchToByUser() &&
+ (!fullUserOnly || userData.info.isFull())) {
+ int firstSwitchable = userData.info.id;
+ return firstSwitchable;
+ }
+ }
+ }
+ return UserHandle.USER_NULL;
+ }
+
@Override
public int getPreviousFullUserToEnterForeground() {
@@ -7902,11 +7948,25 @@
}
if (userInfo != null) {
final UserTypeDetails userDetails = getUserTypeDetails(userInfo);
- final LauncherUserInfo uiInfo = new LauncherUserInfo.Builder(
- userDetails.getName(),
- userInfo.serialNumber)
- .build();
- return uiInfo;
+
+ if (Flags.addLauncherUserConfig()) {
+ Bundle config = new Bundle();
+ if (userInfo.isPrivateProfile()) {
+ try {
+ int parentId = getProfileParentIdUnchecked(userId);
+ config.putBoolean(PRIVATE_SPACE_ENTRYPOINT_HIDDEN,
+ Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ HIDE_PRIVATESPACE_ENTRY_POINT, parentId) == 1);
+ } catch (Settings.SettingNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return new LauncherUserInfo.Builder(userDetails.getName(),
+ userInfo.serialNumber, config).build();
+ }
+
+ return new LauncherUserInfo.Builder(userDetails.getName(),
+ userInfo.serialNumber).build();
} else {
return null;
}
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 07fd1cb..acf62dc 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -235,6 +235,7 @@
NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN);
NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.UWB_RANGING);
NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.NEARBY_WIFI_DEVICES);
+ NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.RANGING);
}
private static final Set<String> NOTIFICATION_PERMISSIONS = new ArraySet<>();
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 24933ca..05bc69a 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1312,7 +1312,7 @@
selfAccess, singleReceiverFromDatasource, attributedOp,
proxyAttributionFlags, proxiedAttributionFlags, attributionChainId);
- if (opMode != AppOpsManager.MODE_ALLOWED) {
+ if (startDataDelivery && opMode != AppOpsManager.MODE_ALLOWED) {
// Current failed the perm check, so if we are part-way through an attr chain,
// we need to clean up the already started proxy op higher up the chain. Note,
// proxy ops are verified two by two, which means we have to clear the 2nd next
@@ -1326,7 +1326,10 @@
finishDataDelivery(context, attributedOp,
cutAttrSourceState, fromDatasource);
}
- if (opMode == AppOpsManager.MODE_ERRORED) {
+ }
+
+ switch (opMode) {
+ case AppOpsManager.MODE_ERRORED: {
if (permission.equals(Manifest.permission.BLUETOOTH_CONNECT)) {
Slog.e(LOG_TAG, "BLUETOOTH_CONNECT permission hard denied as op"
+ " mode is MODE_ERRORED. Permission check was requested for: "
@@ -1334,7 +1337,8 @@
+ current);
}
return PermissionChecker.PERMISSION_HARD_DENIED;
- } else {
+ }
+ case AppOpsManager.MODE_IGNORED: {
return PermissionChecker.PERMISSION_SOFT_DENIED;
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index fc24e62d..19406b4 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -84,6 +84,7 @@
import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;
import static com.android.hardware.input.Flags.emojiAndScreenshotKeycodesAvailable;
+import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;
import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
import static com.android.hardware.input.Flags.modifierShortcutDump;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
@@ -183,6 +184,7 @@
import android.provider.MediaStore;
import android.provider.Settings;
import android.provider.Settings.Secure;
+import android.service.SensorPrivacyToggleSourceProto;
import android.service.dreams.DreamManagerInternal;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
@@ -3612,7 +3614,7 @@
}
break;
case KeyEvent.KEYCODE_T:
- if (keyboardA11yShortcutControl()) {
+ if (enableTalkbackAndMagnifierKeyGestures()) {
if (firstDown && event.isMetaPressed() && event.isAltPressed()) {
mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
TalkbackShortcutController.ShortcutSource.KEYBOARD);
@@ -4112,7 +4114,7 @@
return mDefaultDisplayPolicy.isAwake() && mAccessibilityShortcutController
.isAccessibilityShortcutAvailable(false);
case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
- return keyboardA11yShortcutControl();
+ return enableTalkbackAndMagnifierKeyGestures();
case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS:
return InputSettings.isAccessibilitySlowKeysFeatureFlagEnabled()
&& keyboardA11yShortcutControl();
@@ -4345,7 +4347,7 @@
}
return true;
case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
- if (keyboardA11yShortcutControl()) {
+ if (enableTalkbackAndMagnifierKeyGestures()) {
if (complete) {
mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
TalkbackShortcutController.ShortcutSource.KEYBOARD);
@@ -4535,8 +4537,8 @@
SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
SensorPrivacyManager.Sensors.MICROPHONE);
- mSensorPrivacyManager.setSensorPrivacy(SensorPrivacyManager.Sensors.MICROPHONE,
- !isEnabled);
+ mSensorPrivacyManager.setSensorPrivacy(SensorPrivacyToggleSourceProto.OTHER,
+ SensorPrivacyManager.Sensors.MICROPHONE, !isEnabled, mCurrentUserId);
int toastTextResId;
if (isEnabled) {
diff --git a/services/core/java/com/android/server/power/FrameworkStatsLogger.java b/services/core/java/com/android/server/power/FrameworkStatsLogger.java
new file mode 100644
index 0000000..78ad305
--- /dev/null
+++ b/services/core/java/com/android/server/power/FrameworkStatsLogger.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.power;
+
+import android.os.WorkSource.WorkChain;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+public class FrameworkStatsLogger {
+ public enum WakelockEventType {
+ ACQUIRE,
+ RELEASE
+ }
+
+ /** Log WakelockStateChanged push atom without a WorkChain. */
+ public void wakelockStateChanged(
+ int ownerUid, String tag, int powerManagerWakeLockLevel, WakelockEventType eventType) {
+ int event =
+ (eventType == WakelockEventType.ACQUIRE)
+ ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE
+ : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE;
+ FrameworkStatsLog.write_non_chained(
+ FrameworkStatsLog.WAKELOCK_STATE_CHANGED,
+ ownerUid,
+ null,
+ powerManagerWakeLockLevel,
+ tag,
+ event,
+ FrameworkStatsLog.WAKELOCK_STATE_CHANGED__PROCESS_STATE__PROCESS_STATE_UNKNOWN);
+ }
+
+ /** Log WakelockStateChanged push atom with a WorkChain. */
+ public void wakelockStateChanged(
+ String tag, WorkChain wc, int powerManagerWakeLockLevel, WakelockEventType eventType) {
+ int event =
+ (eventType == WakelockEventType.ACQUIRE)
+ ? FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE
+ : FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE;
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.WAKELOCK_STATE_CHANGED,
+ wc.getUids(),
+ wc.getTags(),
+ powerManagerWakeLockLevel,
+ tag,
+ event,
+ FrameworkStatsLog.WAKELOCK_STATE_CHANGED__PROCESS_STATE__PROCESS_STATE_UNKNOWN);
+ }
+}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 8ba56c5..0c3c46c 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -33,6 +33,7 @@
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.BatteryStats;
+import android.os.BatteryStatsInternal;
import android.os.Bundle;
import android.os.Handler;
import android.os.IWakeLockCallback;
@@ -48,6 +49,7 @@
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.os.WorkSource;
+import android.os.WorkSource.WorkChain;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.EventLog;
@@ -66,10 +68,12 @@
import com.android.server.input.InputManagerInternal;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.power.FrameworkStatsLogger.WakelockEventType;
import com.android.server.power.feature.PowerManagerFlags;
import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.PrintWriter;
+import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -195,6 +199,9 @@
private final PowerManagerFlags mFlags;
+ private final BatteryStatsInternal mBatteryStatsInternal;
+ private final FrameworkStatsLogger mFrameworkStatsLogger;
+
public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
@@ -241,6 +248,14 @@
} catch (RemoteException ex) { }
FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED,
FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON);
+
+ if (mFlags.isMoveWscLoggingToNotifierEnabled()) {
+ mBatteryStatsInternal = mInjector.getBatteryStatsInternal();
+ mFrameworkStatsLogger = mInjector.getFrameworkStatsLogger();
+ } else {
+ mBatteryStatsInternal = null;
+ mFrameworkStatsLogger = null;
+ }
}
/**
@@ -277,6 +292,7 @@
+ ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+ ", workSource=" + workSource);
}
+ logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.ACQUIRE);
notifyWakeLockListener(callback, tag, true, ownerUid, ownerPid, flags, workSource,
packageName, historyTag);
if (!mFlags.improveWakelockLatency()) {
@@ -380,6 +396,10 @@
+ ", workSource=" + newWorkSource);
}
+ logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.RELEASE);
+ logWakelockStateChanged(
+ newFlags, newTag, newOwnerUid, newWorkSource, WakelockEventType.ACQUIRE);
+
final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
&& (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
try {
@@ -425,6 +445,7 @@
+ ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+ ", workSource=" + workSource);
}
+ logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.RELEASE);
notifyWakeLockListener(callback, tag, false, ownerUid, ownerPid, flags, workSource,
packageName, historyTag);
if (!mFlags.improveWakelockLatency()) {
@@ -1258,6 +1279,44 @@
}
}
+ private void logWakelockStateChanged(
+ int flags,
+ String tag,
+ int ownerUid,
+ WorkSource workSource,
+ WakelockEventType eventType) {
+ if (mBatteryStatsInternal == null) {
+ return;
+ }
+ final int type = flags & PowerManager.WAKE_LOCK_LEVEL_MASK;
+ if (workSource == null || workSource.isEmpty()) {
+ final int mappedUid = mBatteryStatsInternal.getOwnerUid(ownerUid);
+ mFrameworkStatsLogger.wakelockStateChanged(mappedUid, tag, type, eventType);
+ } else {
+ for (int i = 0; i < workSource.size(); ++i) {
+ final int mappedUid = mBatteryStatsInternal.getOwnerUid(workSource.getUid(i));
+ mFrameworkStatsLogger.wakelockStateChanged(mappedUid, tag, type, eventType);
+ }
+
+ List<WorkChain> workChains = workSource.getWorkChains();
+ if (workChains != null) {
+ for (WorkChain workChain : workChains) {
+ WorkChain mappedWorkChain = new WorkChain();
+ // Cache getUids() and getTags() because they make an arraycopy.
+ int[] uids = workChain.getUids();
+ String[] tags = workChain.getTags();
+
+ for (int i = 0; i < workChain.getSize(); ++i) {
+ final int mappedUid = mBatteryStatsInternal.getOwnerUid(uids[i]);
+ mappedWorkChain.addNode(mappedUid, tags[i]);
+ }
+ mFrameworkStatsLogger.wakelockStateChanged(
+ tag, mappedWorkChain, type, eventType);
+ }
+ }
+ }
+ }
+
public interface Injector {
/**
* Gets the current time in millis
@@ -1273,9 +1332,15 @@
* Gets the AppOpsManager system service
*/
AppOpsManager getAppOpsManager(Context context);
+
+ /** Gets the BatteryStatsInternal object */
+ BatteryStatsInternal getBatteryStatsInternal();
+
+ /** Get the FrameworkStatsLogger object */
+ FrameworkStatsLogger getFrameworkStatsLogger();
}
- static class RealInjector implements Injector {
+ class RealInjector implements Injector {
@Override
public long currentTimeMillis() {
return System.currentTimeMillis();
@@ -1290,5 +1355,15 @@
public AppOpsManager getAppOpsManager(Context context) {
return context.getSystemService(AppOpsManager.class);
}
+
+ @Override
+ public BatteryStatsInternal getBatteryStatsInternal() {
+ return LocalServices.getService(BatteryStatsInternal.class);
+ }
+
+ @Override
+ public FrameworkStatsLogger getFrameworkStatsLogger() {
+ return new FrameworkStatsLogger();
+ }
}
}
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 78bc06c..42dbb79 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -43,6 +43,7 @@
import android.os.HwBinder;
import android.os.IBinder;
import android.os.IThermalEventListener;
+import android.os.IThermalHeadroomListener;
import android.os.IThermalService;
import android.os.IThermalStatusListener;
import android.os.PowerManager;
@@ -59,6 +60,7 @@
import android.util.ArrayMap;
import android.util.EventLog;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.StatsEvent;
import com.android.internal.annotations.GuardedBy;
@@ -96,6 +98,15 @@
/** Input range limits for getThermalHeadroom API */
public static final int MIN_FORECAST_SEC = 0;
public static final int MAX_FORECAST_SEC = 60;
+ public static final int DEFAULT_FORECAST_SECONDS = 10;
+ public static final int HEADROOM_CALLBACK_MIN_INTERVAL_MILLIS = 5000;
+ // headroom to temperature conversion: 3C every 0.1 headroom difference
+ // if no throttling event, the temperature difference should be at least 0.9C (or 0.03 headroom)
+ // to make a callback
+ public static final float HEADROOM_CALLBACK_MIN_DIFFERENCE = 0.03f;
+ // if no throttling event, the threshold headroom difference should be at least 0.01 (or 0.3C)
+ // to make a callback
+ public static final float HEADROOM_THRESHOLD_CALLBACK_MIN_DIFFERENCE = 0.01f;
/** Lock to protect listen list. */
private final Object mLock = new Object();
@@ -113,6 +124,15 @@
private final RemoteCallbackList<IThermalStatusListener> mThermalStatusListeners =
new RemoteCallbackList<>();
+ /** Registered observers of the thermal headroom. */
+ @GuardedBy("mLock")
+ private final RemoteCallbackList<IThermalHeadroomListener> mThermalHeadroomListeners =
+ new RemoteCallbackList<>();
+ @GuardedBy("mLock")
+ private long mLastHeadroomCallbackTimeMillis;
+ @GuardedBy("mLock")
+ private HeadroomCallbackData mLastHeadroomCallbackData = null;
+
/** Current thermal status */
@GuardedBy("mLock")
private int mStatus;
@@ -133,7 +153,7 @@
/** Watches temperatures to forecast when throttling will occur */
@VisibleForTesting
- final TemperatureWatcher mTemperatureWatcher = new TemperatureWatcher();
+ final TemperatureWatcher mTemperatureWatcher;
private final ThermalHalWrapper.WrapperThermalChangedCallback mWrapperCallback =
new ThermalHalWrapper.WrapperThermalChangedCallback() {
@@ -151,8 +171,14 @@
public void onThresholdChanged(TemperatureThreshold threshold) {
final long token = Binder.clearCallingIdentity();
try {
+ final HeadroomCallbackData data;
synchronized (mTemperatureWatcher.mSamples) {
+ Slog.d(TAG, "Updating skin threshold: " + threshold);
mTemperatureWatcher.updateTemperatureThresholdLocked(threshold, true);
+ data = mTemperatureWatcher.getHeadroomCallbackDataLocked();
+ }
+ synchronized (mLock) {
+ checkAndNotifyHeadroomListenersLocked(data);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -175,6 +201,7 @@
halWrapper.setCallback(mWrapperCallback);
}
mStatus = Temperature.THROTTLING_NONE;
+ mTemperatureWatcher = new TemperatureWatcher();
}
@Override
@@ -231,32 +258,79 @@
}
}
- private void postStatusListener(IThermalStatusListener listener) {
+ @GuardedBy("mLock")
+ private void postStatusListenerLocked(IThermalStatusListener listener) {
final boolean thermalCallbackQueued = FgThread.getHandler().post(() -> {
try {
listener.onStatusChange(mStatus);
} catch (RemoteException | RuntimeException e) {
- Slog.e(TAG, "Thermal callback failed to call", e);
+ Slog.e(TAG, "Thermal status callback failed to call", e);
}
});
if (!thermalCallbackQueued) {
- Slog.e(TAG, "Thermal callback failed to queue");
+ Slog.e(TAG, "Thermal status callback failed to queue");
}
}
+ @GuardedBy("mLock")
private void notifyStatusListenersLocked() {
final int length = mThermalStatusListeners.beginBroadcast();
try {
for (int i = 0; i < length; i++) {
final IThermalStatusListener listener =
mThermalStatusListeners.getBroadcastItem(i);
- postStatusListener(listener);
+ postStatusListenerLocked(listener);
}
} finally {
mThermalStatusListeners.finishBroadcast();
}
}
+ @GuardedBy("mLock")
+ private void postHeadroomListenerLocked(IThermalHeadroomListener listener,
+ HeadroomCallbackData data) {
+ if (!mHalReady.get()) {
+ return;
+ }
+ final boolean thermalCallbackQueued = FgThread.getHandler().post(() -> {
+ try {
+ if (Float.isNaN(data.mHeadroom)) {
+ return;
+ }
+ listener.onHeadroomChange(data.mHeadroom, data.mForecastHeadroom,
+ data.mForecastSeconds, data.mHeadroomThresholds);
+ } catch (RemoteException | RuntimeException e) {
+ Slog.e(TAG, "Thermal headroom callback failed to call", e);
+ }
+ });
+ if (!thermalCallbackQueued) {
+ Slog.e(TAG, "Thermal headroom callback failed to queue");
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void checkAndNotifyHeadroomListenersLocked(HeadroomCallbackData data) {
+ if (!data.isSignificantDifferentFrom(mLastHeadroomCallbackData)
+ && System.currentTimeMillis()
+ < mLastHeadroomCallbackTimeMillis + HEADROOM_CALLBACK_MIN_INTERVAL_MILLIS) {
+ // skip notifying the client with similar data within a short period
+ return;
+ }
+ mLastHeadroomCallbackTimeMillis = System.currentTimeMillis();
+ mLastHeadroomCallbackData = data;
+ final int length = mThermalHeadroomListeners.beginBroadcast();
+ try {
+ for (int i = 0; i < length; i++) {
+ final IThermalHeadroomListener listener =
+ mThermalHeadroomListeners.getBroadcastItem(i);
+ postHeadroomListenerLocked(listener, data);
+ }
+ } finally {
+ mThermalHeadroomListeners.finishBroadcast();
+ }
+ }
+
+ @GuardedBy("mLock")
private void onTemperatureMapChangedLocked() {
int newStatus = Temperature.THROTTLING_NONE;
final int count = mTemperatureMap.size();
@@ -272,6 +346,7 @@
}
}
+ @GuardedBy("mLock")
private void setStatusLocked(int newStatus) {
if (newStatus != mStatus) {
Trace.traceCounter(Trace.TRACE_TAG_POWER, "ThermalManagerService.status", newStatus);
@@ -280,18 +355,18 @@
}
}
- private void postEventListenerCurrentTemperatures(IThermalEventListener listener,
+ @GuardedBy("mLock")
+ private void postEventListenerCurrentTemperaturesLocked(IThermalEventListener listener,
@Nullable Integer type) {
- synchronized (mLock) {
- final int count = mTemperatureMap.size();
- for (int i = 0; i < count; i++) {
- postEventListener(mTemperatureMap.valueAt(i), listener,
- type);
- }
+ final int count = mTemperatureMap.size();
+ for (int i = 0; i < count; i++) {
+ postEventListenerLocked(mTemperatureMap.valueAt(i), listener,
+ type);
}
}
- private void postEventListener(Temperature temperature,
+ @GuardedBy("mLock")
+ private void postEventListenerLocked(Temperature temperature,
IThermalEventListener listener,
@Nullable Integer type) {
// Skip if listener registered with a different type
@@ -302,14 +377,15 @@
try {
listener.notifyThrottling(temperature);
} catch (RemoteException | RuntimeException e) {
- Slog.e(TAG, "Thermal callback failed to call", e);
+ Slog.e(TAG, "Thermal event callback failed to call", e);
}
});
if (!thermalCallbackQueued) {
- Slog.e(TAG, "Thermal callback failed to queue");
+ Slog.e(TAG, "Thermal event callback failed to queue");
}
}
+ @GuardedBy("mLock")
private void notifyEventListenersLocked(Temperature temperature) {
final int length = mThermalEventListeners.beginBroadcast();
try {
@@ -318,7 +394,7 @@
mThermalEventListeners.getBroadcastItem(i);
final Integer type =
(Integer) mThermalEventListeners.getBroadcastCookie(i);
- postEventListener(temperature, listener, type);
+ postEventListenerLocked(temperature, listener, type);
}
} finally {
mThermalEventListeners.finishBroadcast();
@@ -348,17 +424,31 @@
}
}
- private void onTemperatureChanged(Temperature temperature, boolean sendStatus) {
+ private void onTemperatureChanged(Temperature temperature, boolean sendCallback) {
shutdownIfNeeded(temperature);
synchronized (mLock) {
Temperature old = mTemperatureMap.put(temperature.getName(), temperature);
if (old == null || old.getStatus() != temperature.getStatus()) {
notifyEventListenersLocked(temperature);
}
- if (sendStatus) {
+ if (sendCallback) {
onTemperatureMapChangedLocked();
}
}
+ if (sendCallback && Flags.allowThermalThresholdsCallback()
+ && temperature.getType() == Temperature.TYPE_SKIN) {
+ final HeadroomCallbackData data;
+ synchronized (mTemperatureWatcher.mSamples) {
+ Slog.d(TAG, "Updating new temperature: " + temperature);
+ mTemperatureWatcher.updateTemperatureSampleLocked(System.currentTimeMillis(),
+ temperature);
+ mTemperatureWatcher.mCachedHeadrooms.clear();
+ data = mTemperatureWatcher.getHeadroomCallbackDataLocked();
+ }
+ synchronized (mLock) {
+ checkAndNotifyHeadroomListenersLocked(data);
+ }
+ }
}
private void registerStatsCallbacks() {
@@ -399,7 +489,7 @@
return false;
}
// Notify its callback after new client registered.
- postEventListenerCurrentTemperatures(listener, null);
+ postEventListenerCurrentTemperaturesLocked(listener, null);
return true;
} finally {
Binder.restoreCallingIdentity(token);
@@ -415,11 +505,11 @@
synchronized (mLock) {
final long token = Binder.clearCallingIdentity();
try {
- if (!mThermalEventListeners.register(listener, new Integer(type))) {
+ if (!mThermalEventListeners.register(listener, type)) {
return false;
}
// Notify its callback after new client registered.
- postEventListenerCurrentTemperatures(listener, new Integer(type));
+ postEventListenerCurrentTemperaturesLocked(listener, type);
return true;
} finally {
Binder.restoreCallingIdentity(token);
@@ -484,7 +574,7 @@
return false;
}
// Notify its callback after new client registered.
- postStatusListener(listener);
+ postStatusListenerLocked(listener);
return true;
} finally {
Binder.restoreCallingIdentity(token);
@@ -557,11 +647,50 @@
}
@Override
+ public boolean registerThermalHeadroomListener(IThermalHeadroomListener listener) {
+ if (!mHalReady.get()) {
+ return false;
+ }
+ synchronized (mLock) {
+ // Notify its callback after new client registered.
+ final long token = Binder.clearCallingIdentity();
+ try {
+ if (!mThermalHeadroomListeners.register(listener)) {
+ return false;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ final HeadroomCallbackData data;
+ synchronized (mTemperatureWatcher.mSamples) {
+ data = mTemperatureWatcher.getHeadroomCallbackDataLocked();
+ }
+ // Notify its callback after new client registered.
+ synchronized (mLock) {
+ postHeadroomListenerLocked(listener, data);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean unregisterThermalHeadroomListener(IThermalHeadroomListener listener) {
+ synchronized (mLock) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return mThermalHeadroomListeners.unregister(listener);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ }
+
+ @Override
public float getThermalHeadroom(int forecastSeconds) {
if (!mHalReady.get()) {
FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_CALLED, getCallingUid(),
- FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__HAL_NOT_READY,
- Float.NaN, forecastSeconds);
+ FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__HAL_NOT_READY,
+ Float.NaN, forecastSeconds);
return Float.NaN;
}
@@ -570,8 +699,8 @@
Slog.d(TAG, "Invalid forecastSeconds: " + forecastSeconds);
}
FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_CALLED, getCallingUid(),
- FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__INVALID_ARGUMENT,
- Float.NaN, forecastSeconds);
+ FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__INVALID_ARGUMENT,
+ Float.NaN, forecastSeconds);
return Float.NaN;
}
@@ -592,13 +721,10 @@
THERMAL_HEADROOM_THRESHOLDS_CALLED__API_STATUS__FEATURE_NOT_SUPPORTED);
throw new UnsupportedOperationException("Thermal headroom thresholds not enabled");
}
- synchronized (mTemperatureWatcher.mSamples) {
- FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS_CALLED,
- Binder.getCallingUid(),
- THERMAL_HEADROOM_THRESHOLDS_CALLED__API_STATUS__SUCCESS);
- return Arrays.copyOf(mTemperatureWatcher.mHeadroomThresholds,
- mTemperatureWatcher.mHeadroomThresholds.length);
- }
+ FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS_CALLED,
+ Binder.getCallingUid(),
+ THERMAL_HEADROOM_THRESHOLDS_CALLED__API_STATUS__SUCCESS);
+ return mTemperatureWatcher.getHeadroomThresholds();
}
@Override
@@ -711,7 +837,7 @@
class ThermalShellCommand extends ShellCommand {
@Override
public int onCommand(String cmd) {
- switch(cmd != null ? cmd : "") {
+ switch (cmd != null ? cmd : "") {
case "inject-temperature":
return runInjectTemperature();
case "override-status":
@@ -1112,7 +1238,8 @@
}
@Override
- @NonNull protected List<TemperatureThreshold> getTemperatureThresholds(
+ @NonNull
+ protected List<TemperatureThreshold> getTemperatureThresholds(
boolean shouldFilter, int type) {
synchronized (mHalLock) {
final List<TemperatureThreshold> ret = new ArrayList<>();
@@ -1631,14 +1758,68 @@
}
}
+ private static final class HeadroomCallbackData {
+ float mHeadroom;
+ float mForecastHeadroom;
+ int mForecastSeconds;
+ float[] mHeadroomThresholds;
+
+ HeadroomCallbackData(float headroom, float forecastHeadroom, int forecastSeconds,
+ @NonNull float[] headroomThresholds) {
+ mHeadroom = headroom;
+ mForecastHeadroom = forecastHeadroom;
+ mForecastSeconds = forecastSeconds;
+ mHeadroomThresholds = headroomThresholds;
+ }
+
+ private boolean isSignificantDifferentFrom(HeadroomCallbackData other) {
+ if (other == null) return true;
+ // currently this is always the same as DEFAULT_FORECAST_SECONDS, when it's retried
+ // from thermal HAL, we may want to adjust this.
+ if (this.mForecastSeconds != other.mForecastSeconds) return true;
+ if (Math.abs(this.mHeadroom - other.mHeadroom)
+ >= HEADROOM_CALLBACK_MIN_DIFFERENCE) return true;
+ if (Math.abs(this.mForecastHeadroom - other.mForecastHeadroom)
+ >= HEADROOM_CALLBACK_MIN_DIFFERENCE) return true;
+ for (int i = 0; i < this.mHeadroomThresholds.length; i++) {
+ if (Float.isNaN(this.mHeadroomThresholds[i]) != Float.isNaN(
+ other.mHeadroomThresholds[i])) {
+ return true;
+ }
+ if (Math.abs(this.mHeadroomThresholds[i] - other.mHeadroomThresholds[i])
+ >= HEADROOM_THRESHOLD_CALLBACK_MIN_DIFFERENCE) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "HeadroomCallbackData[mHeadroom=" + mHeadroom + ", mForecastHeadroom="
+ + mForecastHeadroom + ", mForecastSeconds=" + mForecastSeconds
+ + ", mHeadroomThresholds=" + Arrays.toString(mHeadroomThresholds) + "]";
+ }
+ }
+
@VisibleForTesting
class TemperatureWatcher {
+ private static final int RING_BUFFER_SIZE = 30;
+ private static final int INACTIVITY_THRESHOLD_MILLIS = 10000;
+ @VisibleForTesting
+ long mInactivityThresholdMillis = INACTIVITY_THRESHOLD_MILLIS;
+
private final Handler mHandler = BackgroundThread.getHandler();
- /** Map of skin temperature sensor name to a corresponding list of samples */
+ /**
+ * Map of skin temperature sensor name to a corresponding list of samples
+ * Updates to the samples should also clear the headroom cache.
+ */
@GuardedBy("mSamples")
@VisibleForTesting
final ArrayMap<String, ArrayList<Sample>> mSamples = new ArrayMap<>();
+ @GuardedBy("mSamples")
+ private final SparseArray<Float> mCachedHeadrooms = new SparseArray<>(2);
/** Map of skin temperature sensor name to the corresponding SEVERE temperature threshold */
@GuardedBy("mSamples")
@@ -1650,13 +1831,9 @@
@GuardedBy("mSamples")
private long mLastForecastCallTimeMillis = 0;
- private static final int INACTIVITY_THRESHOLD_MILLIS = 10000;
- @VisibleForTesting
- long mInactivityThresholdMillis = INACTIVITY_THRESHOLD_MILLIS;
-
void getAndUpdateThresholds() {
List<TemperatureThreshold> thresholds =
- mHalWrapper.getTemperatureThresholds(true, Temperature.TYPE_SKIN);
+ mHalWrapper.getTemperatureThresholds(true, Temperature.TYPE_SKIN);
synchronized (mSamples) {
if (Flags.allowThermalHeadroomThresholds()) {
Arrays.fill(mHeadroomThresholds, Float.NaN);
@@ -1684,6 +1861,8 @@
return;
}
if (override) {
+ Slog.d(TAG, "Headroom cache cleared on threshold update " + threshold);
+ mCachedHeadrooms.clear();
Arrays.fill(mHeadroomThresholds, Float.NaN);
}
for (int severity = ThrottlingSeverity.LIGHT;
@@ -1693,62 +1872,61 @@
if (Float.isNaN(t)) {
continue;
}
- synchronized (mSamples) {
- if (severity == ThrottlingSeverity.SEVERE) {
- mHeadroomThresholds[severity] = 1.0f;
- continue;
- }
- float headroom = normalizeTemperature(t, severeThreshold);
- if (Float.isNaN(mHeadroomThresholds[severity])) {
- mHeadroomThresholds[severity] = headroom;
- } else {
- float lastHeadroom = mHeadroomThresholds[severity];
- mHeadroomThresholds[severity] = Math.min(lastHeadroom, headroom);
- }
+ if (severity == ThrottlingSeverity.SEVERE) {
+ mHeadroomThresholds[severity] = 1.0f;
+ continue;
+ }
+ float headroom = normalizeTemperature(t, severeThreshold);
+ if (Float.isNaN(mHeadroomThresholds[severity])) {
+ mHeadroomThresholds[severity] = headroom;
+ } else {
+ float lastHeadroom = mHeadroomThresholds[severity];
+ mHeadroomThresholds[severity] = Math.min(lastHeadroom, headroom);
}
}
}
}
- private static final int RING_BUFFER_SIZE = 30;
-
- private void updateTemperature() {
+ private void getAndUpdateTemperatureSamples() {
synchronized (mSamples) {
if (SystemClock.elapsedRealtime() - mLastForecastCallTimeMillis
< mInactivityThresholdMillis) {
// Trigger this again after a second as long as forecast has been called more
// recently than the inactivity timeout
- mHandler.postDelayed(this::updateTemperature, 1000);
+ mHandler.postDelayed(this::getAndUpdateTemperatureSamples, 1000);
} else {
// Otherwise, we've been idle for at least 10 seconds, so we should
// shut down
mSamples.clear();
+ mCachedHeadrooms.clear();
return;
}
long now = SystemClock.elapsedRealtime();
- List<Temperature> temperatures = mHalWrapper.getCurrentTemperatures(true,
+ final List<Temperature> temperatures = mHalWrapper.getCurrentTemperatures(true,
Temperature.TYPE_SKIN);
-
- for (int t = 0; t < temperatures.size(); ++t) {
- Temperature temperature = temperatures.get(t);
-
- // Filter out invalid temperatures. If this results in no values being stored at
- // all, the mSamples.empty() check in getForecast() will catch it.
- if (Float.isNaN(temperature.getValue())) {
- continue;
- }
-
- ArrayList<Sample> samples = mSamples.computeIfAbsent(temperature.getName(),
- k -> new ArrayList<>(RING_BUFFER_SIZE));
- if (samples.size() == RING_BUFFER_SIZE) {
- samples.removeFirst();
- }
- samples.add(new Sample(now, temperature.getValue()));
+ for (Temperature temperature : temperatures) {
+ updateTemperatureSampleLocked(now, temperature);
}
+ mCachedHeadrooms.clear();
}
}
+ @GuardedBy("mSamples")
+ private void updateTemperatureSampleLocked(long timeNow, Temperature temperature) {
+ // Filter out invalid temperatures. If this results in no values being stored at
+ // all, the mSamples.empty() check in getForecast() will catch it.
+ if (Float.isNaN(temperature.getValue())) {
+ return;
+ }
+ ArrayList<Sample> samples = mSamples.computeIfAbsent(temperature.getName(),
+ k -> new ArrayList<>(RING_BUFFER_SIZE));
+ if (samples.size() == RING_BUFFER_SIZE) {
+ samples.removeFirst();
+ }
+ samples.add(new Sample(timeNow, temperature.getValue()));
+ }
+
/**
* Calculates the trend using a linear regression. As the samples are degrees Celsius with
* associated timestamps in milliseconds, the slope is in degrees Celsius per millisecond.
@@ -1801,7 +1979,7 @@
synchronized (mSamples) {
mLastForecastCallTimeMillis = SystemClock.elapsedRealtime();
if (mSamples.isEmpty()) {
- updateTemperature();
+ getAndUpdateTemperatureSamples();
}
// If somehow things take much longer than expected or there are no temperatures
@@ -1826,6 +2004,14 @@
return Float.NaN;
}
+ if (mCachedHeadrooms.contains(forecastSeconds)) {
+ // TODO(b/360486877): replace with metrics
+ Slog.d(TAG,
+ "Headroom forecast in " + forecastSeconds + "s served from cache: "
+ + mCachedHeadrooms.get(forecastSeconds));
+ return mCachedHeadrooms.get(forecastSeconds);
+ }
+
float maxNormalized = Float.NaN;
int noThresholdSampleCount = 0;
for (Map.Entry<String, ArrayList<Sample>> entry : mSamples.entrySet()) {
@@ -1842,6 +2028,12 @@
float currentTemperature = samples.getLast().temperature;
if (samples.size() < MINIMUM_SAMPLE_COUNT) {
+ if (mSamples.size() == 1 && mCachedHeadrooms.contains(0)) {
+ // if only one sensor name exists, then try reading the cache
+ // TODO(b/360486877): replace with metrics
+ Slog.d(TAG, "Headroom forecast cached: " + mCachedHeadrooms.get(0));
+ return mCachedHeadrooms.get(0);
+ }
// Don't try to forecast, just use the latest one we have
float normalized = normalizeTemperature(currentTemperature, threshold);
if (Float.isNaN(maxNormalized) || normalized > maxNormalized) {
@@ -1849,8 +2041,10 @@
}
continue;
}
-
- float slope = getSlopeOf(samples);
+ float slope = 0.0f;
+ if (forecastSeconds > 0) {
+ slope = getSlopeOf(samples);
+ }
float normalized = normalizeTemperature(
currentTemperature + slope * forecastSeconds * 1000, threshold);
if (Float.isNaN(maxNormalized) || normalized > maxNormalized) {
@@ -1868,10 +2062,28 @@
FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__SUCCESS,
maxNormalized, forecastSeconds);
}
+ mCachedHeadrooms.put(forecastSeconds, maxNormalized);
return maxNormalized;
}
}
+ float[] getHeadroomThresholds() {
+ synchronized (mSamples) {
+ return Arrays.copyOf(mHeadroomThresholds, mHeadroomThresholds.length);
+ }
+ }
+
+ @GuardedBy("mSamples")
+ HeadroomCallbackData getHeadroomCallbackDataLocked() {
+ final HeadroomCallbackData data = new HeadroomCallbackData(
+ getForecast(0),
+ getForecast(DEFAULT_FORECAST_SECONDS),
+ DEFAULT_FORECAST_SECONDS,
+ Arrays.copyOf(mHeadroomThresholds, mHeadroomThresholds.length));
+ Slog.d(TAG, "New headroom callback data: " + data);
+ return data;
+ }
+
@VisibleForTesting
// Since Sample is inside an inner class, we can't make it static
// This allows test code to create Sample objects via ThermalManagerService
@@ -1880,7 +2092,7 @@
}
@VisibleForTesting
- class Sample {
+ static class Sample {
public long time;
public float temperature;
@@ -1888,6 +2100,11 @@
this.time = time;
this.temperature = temperature;
}
+
+ @Override
+ public String toString() {
+ return "Sample[temperature=" + temperature + ", time=" + time + "]";
+ }
}
}
}
diff --git a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
index 4ddf0c0..5cd7dee 100644
--- a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
+++ b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
@@ -55,6 +55,9 @@
Flags::policyReasonInDisplayPowerRequest
);
+ private final FlagState mMoveWscLoggingToNotifier =
+ new FlagState(Flags.FLAG_MOVE_WSC_LOGGING_TO_NOTIFIER, Flags::moveWscLoggingToNotifier);
+
/** Returns whether early-screen-timeout-detector is enabled on not. */
public boolean isEarlyScreenTimeoutDetectorEnabled() {
return mEarlyScreenTimeoutDetectorFlagState.isEnabled();
@@ -89,6 +92,14 @@
}
/**
+ * @return Whether we move WakelockStateChanged atom logging to Notifier (enabled) or leave it
+ * in BatteryStatsImpl (disabled).
+ */
+ public boolean isMoveWscLoggingToNotifierEnabled() {
+ return mMoveWscLoggingToNotifier.isEnabled();
+ }
+
+ /**
* dumps all flagstates
* @param pw printWriter
*/
@@ -98,6 +109,7 @@
pw.println(" " + mImproveWakelockLatency);
pw.println(" " + mPerDisplayWakeByTouch);
pw.println(" " + mFrameworkWakelockInfo);
+ pw.println(" " + mMoveWscLoggingToNotifier);
}
private static class FlagState {
diff --git a/services/core/java/com/android/server/power/feature/power_flags.aconfig b/services/core/java/com/android/server/power/feature/power_flags.aconfig
index e27f8bb..a6948fc 100644
--- a/services/core/java/com/android/server/power/feature/power_flags.aconfig
+++ b/services/core/java/com/android/server/power/feature/power_flags.aconfig
@@ -41,3 +41,10 @@
bug: "364349703"
is_fixed_read_only: true
}
+
+flag {
+ name: "move_wsc_logging_to_notifier"
+ namespace: "power"
+ description: "Feature flag to move logging of WakelockStateChanged atoms from BatteryStatsImpl to Notifier."
+ bug: "352602149"
+}
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index 940a509..677a2de 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -5155,10 +5155,11 @@
Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs);
uidStats.noteStartWakeLocked(pid, name, type, elapsedRealtimeMs);
-
- mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name,
- uidStats.mProcessState, true /* acquired */,
- getPowerManagerWakeLockLevel(type));
+ if (!mPowerManagerFlags.isMoveWscLoggingToNotifierEnabled()) {
+ mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name,
+ uidStats.mProcessState, true /* acquired */,
+ getPowerManagerWakeLockLevel(type));
+ }
if (mPowerManagerFlags.isFrameworkWakelockInfoEnabled()) {
mFrameworkEvents.noteStartWakeLock(
mapIsolatedUid(uid), name, getPowerManagerWakeLockLevel(type), uptimeMs);
@@ -5205,9 +5206,11 @@
Uid uidStats = getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs);
uidStats.noteStopWakeLocked(pid, name, type, elapsedRealtimeMs);
- mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name,
- uidStats.mProcessState, false/* acquired */,
- getPowerManagerWakeLockLevel(type));
+ if (!mPowerManagerFlags.isMoveWscLoggingToNotifierEnabled()) {
+ mFrameworkStatsLogger.wakelockStateChanged(mapIsolatedUid(uid), wc, name,
+ uidStats.mProcessState, false/* acquired */,
+ getPowerManagerWakeLockLevel(type));
+ }
if (mPowerManagerFlags.isFrameworkWakelockInfoEnabled()) {
mFrameworkEvents.noteStopWakeLock(
mapIsolatedUid(uid), name, getPowerManagerWakeLockLevel(type), uptimeMs);
diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
index 600fe59..606bd1d 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -51,6 +51,7 @@
private final CpuScalingPolicies mCpuScalingPolicies;
private final int mAccumulatedBatteryUsageStatsSpanSize;
private final Clock mClock;
+ private final MonotonicClock mMonotonicClock;
private final Object mLock = new Object();
private List<PowerCalculator> mPowerCalculators;
private UserPowerCalculator mUserPowerCalculator;
@@ -67,7 +68,7 @@
@NonNull PowerAttributor powerAttributor,
@NonNull PowerProfile powerProfile, @NonNull CpuScalingPolicies cpuScalingPolicies,
@NonNull PowerStatsStore powerStatsStore, int accumulatedBatteryUsageStatsSpanSize,
- @NonNull Clock clock) {
+ @NonNull Clock clock, @NonNull MonotonicClock monotonicClock) {
mContext = context;
mPowerAttributor = powerAttributor;
mPowerStatsStore = powerStatsStore;
@@ -75,6 +76,7 @@
mCpuScalingPolicies = cpuScalingPolicies;
mAccumulatedBatteryUsageStatsSpanSize = accumulatedBatteryUsageStatsSpanSize;
mClock = clock;
+ mMonotonicClock = monotonicClock;
mUserPowerCalculator = new UserPowerCalculator();
mPowerStatsStore.addSectionReader(new BatteryUsageStatsSection.Reader());
@@ -213,7 +215,7 @@
powerStatsSpan.addTimeFrame(accumulatedStats.startMonotonicTime,
accumulatedStats.startWallClockTime,
accumulatedStats.endMonotonicTime - accumulatedStats.startMonotonicTime);
- stats.commitMonotonicClock();
+ mMonotonicClock.write();
mPowerStatsStore.storePowerStatsSpanAsync(powerStatsSpan,
accumulatedStats.builder::discard);
}
@@ -308,23 +310,29 @@
private void updateAccumulatedBatteryUsageStats(AccumulatedBatteryUsageStats accumulatedStats,
BatteryStatsImpl stats, BatteryUsageStatsQuery query) {
- // TODO(b/366493365): add the current batteryusagestats directly into
- // `accumulatedStats.builder` to avoid allocating a second CursorWindow
- BatteryUsageStats.Builder remainingBatteryUsageStats = computeBatteryUsageStats(stats,
- query, accumulatedStats.endMonotonicTime, query.getMonotonicEndTime(),
- mClock.currentTimeMillis());
+ long startMonotonicTime = accumulatedStats.endMonotonicTime;
+ if (startMonotonicTime == MonotonicClock.UNDEFINED) {
+ startMonotonicTime = stats.getMonotonicStartTime();
+ }
+ long endWallClockTime = mClock.currentTimeMillis();
+ long endMonotonicTime = mMonotonicClock.monotonicTime();
if (accumulatedStats.builder == null) {
- accumulatedStats.builder = remainingBatteryUsageStats;
+ accumulatedStats.builder = new BatteryUsageStats.Builder(
+ stats.getCustomEnergyConsumerNames(), false, true, true, true, 0);
accumulatedStats.startWallClockTime = stats.getStartClockTime();
- accumulatedStats.startMonotonicTime = stats.getMonotonicStartTime();
- accumulatedStats.endMonotonicTime = accumulatedStats.startMonotonicTime
- + accumulatedStats.builder.getStatsDuration();
- } else {
- accumulatedStats.builder.add(remainingBatteryUsageStats.build());
- accumulatedStats.endMonotonicTime += remainingBatteryUsageStats.getStatsDuration();
- remainingBatteryUsageStats.discard();
+ accumulatedStats.builder.setStatsStartTimestamp(accumulatedStats.startWallClockTime);
}
+
+ accumulatedStats.endMonotonicTime = endMonotonicTime;
+
+ accumulatedStats.builder.setStatsEndTimestamp(endWallClockTime);
+ accumulatedStats.builder.setStatsDuration(endWallClockTime - startMonotonicTime);
+
+ mPowerAttributor.estimatePowerConsumption(accumulatedStats.builder, stats.getHistory(),
+ startMonotonicTime, MonotonicClock.UNDEFINED);
+
+ populateGeneralInfo(accumulatedStats.builder, stats);
}
private BatteryUsageStats.Builder computeBatteryUsageStats(BatteryStatsImpl stats,
diff --git a/services/core/java/com/android/server/vcn/VcnContext.java b/services/core/java/com/android/server/vcn/VcnContext.java
index 6ce8685..9213d96 100644
--- a/services/core/java/com/android/server/vcn/VcnContext.java
+++ b/services/core/java/com/android/server/vcn/VcnContext.java
@@ -74,10 +74,6 @@
return mFeatureFlags;
}
- public boolean isFlagSafeModeTimeoutConfigEnabled() {
- return mFeatureFlags.safeModeTimeoutConfig();
- }
-
/**
* Verifies that the caller is running on the VcnContext Thread.
*
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 2d3bc84..2325f35 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -1263,7 +1263,7 @@
final PersistableBundleWrapper carrierConfig = snapshot.getCarrierConfigForSubGrp(subGrp);
int resultSeconds = defaultSeconds;
- if (vcnContext.isFlagSafeModeTimeoutConfigEnabled() && carrierConfig != null) {
+ if (carrierConfig != null) {
resultSeconds =
carrierConfig.getInt(
VcnManager.VCN_SAFE_MODE_TIMEOUT_SECONDS_KEY, defaultSeconds);
diff --git a/services/core/java/com/android/server/vibrator/ExternalVibrationSession.java b/services/core/java/com/android/server/vibrator/ExternalVibrationSession.java
index df44e50..a92ac67 100644
--- a/services/core/java/com/android/server/vibrator/ExternalVibrationSession.java
+++ b/services/core/java/com/android/server/vibrator/ExternalVibrationSession.java
@@ -45,6 +45,7 @@
void onExternalVibrationReleased(long vibrationId);
}
+ private final long mSessionId = VibrationSession.nextSessionId();
private final ExternalVibration mExternalVibration;
private final ExternalVibrationScale mScale = new ExternalVibrationScale();
private final VibratorManagerHooks mManagerHooks;
@@ -65,6 +66,11 @@
}
@Override
+ public long getSessionId() {
+ return mSessionId;
+ }
+
+ @Override
public long getCreateUptimeMillis() {
return stats.getCreateUptimeMillis();
}
@@ -148,7 +154,12 @@
@Override
public void notifySyncedVibratorsCallback(long vibrationId) {
- // ignored, external control does not expect callbacks from the vibrator manager
+ // ignored, external control does not expect callbacks from the vibrator manager for sync
+ }
+
+ @Override
+ public void notifySessionCallback() {
+ // ignored, external control does not expect callbacks from the vibrator manager for session
}
boolean isHoldingSameVibration(ExternalVibration vib) {
@@ -174,7 +185,8 @@
@Override
public String toString() {
return "ExternalVibrationSession{"
- + "id=" + id
+ + "sessionId=" + mSessionId
+ + ", vibrationId=" + id
+ ", callerInfo=" + callerInfo
+ ", externalVibration=" + mExternalVibration
+ ", scale=" + mScale
diff --git a/services/core/java/com/android/server/vibrator/SingleVibrationSession.java b/services/core/java/com/android/server/vibrator/SingleVibrationSession.java
index 67ba25f..628221b 100644
--- a/services/core/java/com/android/server/vibrator/SingleVibrationSession.java
+++ b/services/core/java/com/android/server/vibrator/SingleVibrationSession.java
@@ -35,6 +35,7 @@
private static final String TAG = "SingleVibrationSession";
private final Object mLock = new Object();
+ private final long mSessionId = VibrationSession.nextSessionId();
private final IBinder mCallerToken;
private final HalVibration mVibration;
@@ -58,6 +59,11 @@
}
@Override
+ public long getSessionId() {
+ return mSessionId;
+ }
+
+ @Override
public long getCreateUptimeMillis() {
return mVibration.stats.getCreateUptimeMillis();
}
@@ -155,9 +161,15 @@
}
@Override
+ public void notifySessionCallback() {
+ // ignored, external control does not expect callbacks from the vibrator manager for session
+ }
+
+ @Override
public String toString() {
return "SingleVibrationSession{"
- + "callerToken= " + mCallerToken
+ + "sessionId= " + mSessionId
+ + ", callerToken= " + mCallerToken
+ ", vibration=" + mVibration
+ '}';
}
diff --git a/services/core/java/com/android/server/vibrator/VendorVibrationSession.java b/services/core/java/com/android/server/vibrator/VendorVibrationSession.java
new file mode 100644
index 0000000..07478e3
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/VendorVibrationSession.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.vibrator;
+
+import static com.android.server.vibrator.VibrationSession.DebugInfo.formatTime;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.media.AudioAttributes;
+import android.os.CancellationSignal;
+import android.os.CombinedVibration;
+import android.os.ExternalVibration;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ICancellationSignal;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.VibrationAttributes;
+import android.os.vibrator.IVibrationSession;
+import android.os.vibrator.IVibrationSessionCallback;
+import android.util.IndentingPrintWriter;
+import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+
+/**
+ * A vibration session started by a vendor request that can trigger {@link CombinedVibration}.
+ */
+final class VendorVibrationSession extends IVibrationSession.Stub
+ implements VibrationSession, CancellationSignal.OnCancelListener, IBinder.DeathRecipient {
+ private static final String TAG = "VendorVibrationSession";
+
+ /** Calls into VibratorManager functionality needed for playing an {@link ExternalVibration}. */
+ interface VibratorManagerHooks {
+
+ /** Tells the manager to end the vibration session. */
+ void endSession(long sessionId, boolean shouldAbort);
+
+ /**
+ * Tells the manager that the vibration session is finished and the vibrators can now be
+ * used for another vibration.
+ */
+ void onSessionReleased(long sessionId);
+ }
+
+ private final Object mLock = new Object();
+ private final long mSessionId = VibrationSession.nextSessionId();
+ private final ICancellationSignal mCancellationSignal = CancellationSignal.createTransport();
+ private final int[] mVibratorIds;
+ private final long mCreateUptime;
+ private final long mCreateTime; // for debugging
+ private final IVibrationSessionCallback mCallback;
+ private final CallerInfo mCallerInfo;
+ private final VibratorManagerHooks mManagerHooks;
+ private final Handler mHandler;
+
+ @GuardedBy("mLock")
+ private Status mStatus = Status.RUNNING;
+ @GuardedBy("mLock")
+ private Status mEndStatusRequest;
+ @GuardedBy("mLock")
+ private long mStartTime; // for debugging
+ @GuardedBy("mLock")
+ private long mEndUptime;
+ @GuardedBy("mLock")
+ private long mEndTime; // for debugging
+
+ VendorVibrationSession(@NonNull CallerInfo callerInfo, @NonNull Handler handler,
+ @NonNull VibratorManagerHooks managerHooks, @NonNull int[] vibratorIds,
+ @NonNull IVibrationSessionCallback callback) {
+ mCreateUptime = SystemClock.uptimeMillis();
+ mCreateTime = System.currentTimeMillis();
+ mVibratorIds = vibratorIds;
+ mHandler = handler;
+ mCallback = callback;
+ mCallerInfo = callerInfo;
+ mManagerHooks = managerHooks;
+ CancellationSignal.fromTransport(mCancellationSignal).setOnCancelListener(this);
+ }
+
+ @Override
+ public void vibrate(CombinedVibration vibration, String reason) {
+ // TODO(b/345414356): implement vibration support
+ throw new UnsupportedOperationException("Vendor session vibrations not yet implemented");
+ }
+
+ @Override
+ public void finishSession() {
+ // Do not abort session in HAL, wait for ongoing vibration requests to complete.
+ // This might take a while to end the session, but it can be aborted by cancelSession.
+ requestEndSession(Status.FINISHED, /* shouldAbort= */ false);
+ }
+
+ @Override
+ public void cancelSession() {
+ // Always abort session in HAL while cancelling it.
+ // This might be triggered after finishSession was already called.
+ requestEndSession(Status.CANCELLED_BY_USER, /* shouldAbort= */ true);
+ }
+
+ @Override
+ public long getSessionId() {
+ return mSessionId;
+ }
+
+ @Override
+ public long getCreateUptimeMillis() {
+ return mCreateUptime;
+ }
+
+ @Override
+ public boolean isRepeating() {
+ return false;
+ }
+
+ @Override
+ public CallerInfo getCallerInfo() {
+ return mCallerInfo;
+ }
+
+ @Override
+ public IBinder getCallerToken() {
+ return mCallback.asBinder();
+ }
+
+ @Override
+ public DebugInfo getDebugInfo() {
+ synchronized (mLock) {
+ return new DebugInfoImpl(mStatus, mCallerInfo, mCreateUptime, mCreateTime, mStartTime,
+ mEndUptime, mEndTime);
+ }
+ }
+
+ @Override
+ public boolean wasEndRequested() {
+ synchronized (mLock) {
+ return mEndStatusRequest != null;
+ }
+ }
+
+ @Override
+ public void onCancel() {
+ Slog.d(TAG, "Cancellation signal received, cancelling vibration session...");
+ requestEnd(Status.CANCELLED_BY_USER, /* endedBy= */ null, /* immediate= */ false);
+ }
+
+ @Override
+ public void binderDied() {
+ Slog.d(TAG, "Binder died, cancelling vibration session...");
+ requestEnd(Status.CANCELLED_BINDER_DIED, /* endedBy= */ null, /* immediate= */ false);
+ }
+
+ @Override
+ public boolean linkToDeath() {
+ try {
+ mCallback.asBinder().linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error linking session to token death", e);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void unlinkToDeath() {
+ try {
+ mCallback.asBinder().unlinkToDeath(this, 0);
+ } catch (NoSuchElementException e) {
+ Slog.wtf(TAG, "Failed to unlink session to token death", e);
+ }
+ }
+
+ @Override
+ public void requestEnd(@NonNull Status status, @Nullable CallerInfo endedBy,
+ boolean immediate) {
+ // All requests to end a session should abort it to stop ongoing vibrations, even if
+ // immediate flag is false. Only the #finishSession API will not abort and wait for
+ // session vibrations to complete, which might take a long time.
+ requestEndSession(status, /* shouldAbort= */ true);
+ }
+
+ @Override
+ public void notifyVibratorCallback(int vibratorId, long vibrationId) {
+ // TODO(b/345414356): implement vibration support
+ }
+
+ @Override
+ public void notifySyncedVibratorsCallback(long vibrationId) {
+ // TODO(b/345414356): implement vibration support
+ }
+
+ @Override
+ public void notifySessionCallback() {
+ synchronized (mLock) {
+ // If end was not requested then the HAL has cancelled the session.
+ maybeSetEndRequestLocked(Status.CANCELLED_BY_UNKNOWN_REASON);
+ maybeSetStatusToRequestedLocked();
+ }
+ mManagerHooks.onSessionReleased(mSessionId);
+ }
+
+ @Override
+ public String toString() {
+ synchronized (mLock) {
+ return "createTime: " + formatTime(mCreateTime, /*includeDate=*/ true)
+ + ", startTime: " + (mStartTime == 0 ? null : formatTime(mStartTime,
+ /* includeDate= */ true))
+ + ", endTime: " + (mEndTime == 0 ? null : formatTime(mEndTime,
+ /* includeDate= */ true))
+ + ", status: " + mStatus.name().toLowerCase(Locale.ROOT)
+ + ", callerInfo: " + mCallerInfo
+ + ", vibratorIds: " + Arrays.toString(mVibratorIds);
+ }
+ }
+
+ public Status getStatus() {
+ synchronized (mLock) {
+ return mStatus;
+ }
+ }
+
+ public boolean isStarted() {
+ synchronized (mLock) {
+ return mStartTime > 0;
+ }
+ }
+
+ public boolean isEnded() {
+ synchronized (mLock) {
+ return mStatus != Status.RUNNING;
+ }
+ }
+
+ public int[] getVibratorIds() {
+ return mVibratorIds;
+ }
+
+ public ICancellationSignal getCancellationSignal() {
+ return mCancellationSignal;
+ }
+
+ public void notifyStart() {
+ boolean isAlreadyEnded = false;
+ synchronized (mLock) {
+ if (isEnded()) {
+ // Session already ended, skip start callbacks.
+ isAlreadyEnded = true;
+ } else {
+ mStartTime = System.currentTimeMillis();
+ // Run client callback in separate thread.
+ mHandler.post(() -> {
+ try {
+ mCallback.onStarted(this);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error notifying vendor session started", e);
+ }
+ });
+ }
+ }
+ if (isAlreadyEnded) {
+ // Session already ended, make sure we end it in the HAL.
+ mManagerHooks.endSession(mSessionId, /* shouldAbort= */ true);
+ }
+ }
+
+ private void requestEndSession(Status status, boolean shouldAbort) {
+ boolean shouldTriggerSessionHook = false;
+ synchronized (mLock) {
+ maybeSetEndRequestLocked(status);
+ if (isStarted()) {
+ // Always trigger session hook after it has started, in case new request aborts an
+ // already finishing session. Wait for HAL callback before actually ending here.
+ shouldTriggerSessionHook = true;
+ } else {
+ // Session did not start in the HAL, end it right away.
+ maybeSetStatusToRequestedLocked();
+ }
+ }
+ if (shouldTriggerSessionHook) {
+ mManagerHooks.endSession(mSessionId, shouldAbort);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void maybeSetEndRequestLocked(Status status) {
+ if (mEndStatusRequest != null) {
+ // End already requested, keep first requested status and time.
+ return;
+ }
+ mEndStatusRequest = status;
+ mEndTime = System.currentTimeMillis();
+ mEndUptime = SystemClock.uptimeMillis();
+ if (isStarted()) {
+ // Only trigger "finishing" callback if session started.
+ // Run client callback in separate thread.
+ mHandler.post(() -> {
+ try {
+ mCallback.onFinishing();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error notifying vendor session is finishing", e);
+ }
+ });
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void maybeSetStatusToRequestedLocked() {
+ if (isEnded()) {
+ // End already set, keep first requested status and time.
+ return;
+ }
+ if (mEndStatusRequest == null) {
+ // No end status was requested, nothing to set.
+ return;
+ }
+ mStatus = mEndStatusRequest;
+ // Run client callback in separate thread.
+ final Status endStatus = mStatus;
+ mHandler.post(() -> {
+ try {
+ mCallback.onFinished(toSessionStatus(endStatus));
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error notifying vendor session is finishing", e);
+ }
+ });
+ }
+
+ @android.os.vibrator.VendorVibrationSession.Status
+ private static int toSessionStatus(Status status) {
+ // Exhaustive switch to cover all possible internal status.
+ return switch (status) {
+ case FINISHED
+ -> android.os.vibrator.VendorVibrationSession.STATUS_SUCCESS;
+ case IGNORED_UNSUPPORTED
+ -> STATUS_UNSUPPORTED;
+ case CANCELLED_BINDER_DIED, CANCELLED_BY_APP_OPS, CANCELLED_BY_USER,
+ CANCELLED_SUPERSEDED, CANCELLED_BY_FOREGROUND_USER, CANCELLED_BY_SCREEN_OFF,
+ CANCELLED_BY_SETTINGS_UPDATE, CANCELLED_BY_UNKNOWN_REASON
+ -> android.os.vibrator.VendorVibrationSession.STATUS_CANCELED;
+ case IGNORED_APP_OPS, IGNORED_BACKGROUND, IGNORED_FOR_EXTERNAL, IGNORED_FOR_ONGOING,
+ IGNORED_FOR_POWER, IGNORED_FOR_SETTINGS, IGNORED_FOR_HIGHER_IMPORTANCE,
+ IGNORED_FOR_RINGER_MODE, IGNORED_FROM_VIRTUAL_DEVICE, IGNORED_SUPERSEDED,
+ IGNORED_MISSING_PERMISSION, IGNORED_ON_WIRELESS_CHARGER
+ -> android.os.vibrator.VendorVibrationSession.STATUS_IGNORED;
+ case UNKNOWN, IGNORED_ERROR_APP_OPS, IGNORED_ERROR_CANCELLING, IGNORED_ERROR_SCHEDULING,
+ IGNORED_ERROR_TOKEN, FORWARDED_TO_INPUT_DEVICES, FINISHED_UNEXPECTED, RUNNING
+ -> android.os.vibrator.VendorVibrationSession.STATUS_UNKNOWN_ERROR;
+ };
+ }
+
+ /**
+ * Holds lightweight debug information about the session that could potentially be kept in
+ * memory for a long time for bugreport dumpsys operations.
+ *
+ * Since DebugInfo can be kept in memory for a long time, it shouldn't hold any references to
+ * potentially expensive or resource-linked objects, such as {@link IBinder}.
+ */
+ static final class DebugInfoImpl implements VibrationSession.DebugInfo {
+ private final Status mStatus;
+ private final CallerInfo mCallerInfo;
+
+ private final long mCreateUptime;
+ private final long mCreateTime;
+ private final long mStartTime;
+ private final long mEndTime;
+ private final long mDurationMs;
+
+ DebugInfoImpl(Status status, CallerInfo callerInfo, long createUptime, long createTime,
+ long startTime, long endUptime, long endTime) {
+ mStatus = status;
+ mCallerInfo = callerInfo;
+ mCreateUptime = createUptime;
+ mCreateTime = createTime;
+ mStartTime = startTime;
+ mEndTime = endTime;
+ mDurationMs = endUptime > 0 ? endUptime - createUptime : -1;
+ }
+
+ @Override
+ public Status getStatus() {
+ return mStatus;
+ }
+
+ @Override
+ public long getCreateUptimeMillis() {
+ return mCreateUptime;
+ }
+
+ @Override
+ public CallerInfo getCallerInfo() {
+ return mCallerInfo;
+ }
+
+ @Nullable
+ @Override
+ public Object getDumpAggregationKey() {
+ return null; // No aggregation.
+ }
+
+ @Override
+ public void logMetrics(VibratorFrameworkStatsLogger statsLogger) {
+ }
+
+ @Override
+ public void dump(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(VibrationProto.END_TIME, mEndTime);
+ proto.write(VibrationProto.DURATION_MS, mDurationMs);
+ proto.write(VibrationProto.STATUS, mStatus.ordinal());
+
+ final long attrsToken = proto.start(VibrationProto.ATTRIBUTES);
+ final VibrationAttributes attrs = mCallerInfo.attrs;
+ proto.write(VibrationAttributesProto.USAGE, attrs.getUsage());
+ proto.write(VibrationAttributesProto.AUDIO_USAGE, attrs.getAudioUsage());
+ proto.write(VibrationAttributesProto.FLAGS, attrs.getFlags());
+ proto.end(attrsToken);
+
+ proto.end(token);
+ }
+
+ @Override
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("VibrationSession:");
+ pw.increaseIndent();
+ pw.println("status = " + mStatus.name().toLowerCase(Locale.ROOT));
+ pw.println("durationMs = " + mDurationMs);
+ pw.println("createTime = " + formatTime(mCreateTime, /*includeDate=*/ true));
+ pw.println("startTime = " + formatTime(mStartTime, /*includeDate=*/ true));
+ pw.println("endTime = " + (mEndTime == 0 ? null
+ : formatTime(mEndTime, /*includeDate=*/ true)));
+ pw.println("callerInfo = " + mCallerInfo);
+ pw.decreaseIndent();
+ }
+
+ @Override
+ public void dumpCompact(IndentingPrintWriter pw) {
+ // Follow pattern from Vibration.DebugInfoImpl for better debugging from dumpsys.
+ String timingsStr = String.format(Locale.ROOT,
+ "%s | %8s | %20s | duration: %5dms | start: %12s | end: %12s",
+ formatTime(mCreateTime, /*includeDate=*/ true),
+ "session",
+ mStatus.name().toLowerCase(Locale.ROOT),
+ mDurationMs,
+ mStartTime == 0 ? "" : formatTime(mStartTime, /*includeDate=*/ false),
+ mEndTime == 0 ? "" : formatTime(mEndTime, /*includeDate=*/ false));
+ String paramStr = String.format(Locale.ROOT,
+ " | flags: %4s | usage: %s",
+ Long.toBinaryString(mCallerInfo.attrs.getFlags()),
+ mCallerInfo.attrs.usageToString());
+ // Optional, most vibrations should not be defined via AudioAttributes
+ // so skip them to simplify the logs
+ String audioUsageStr =
+ mCallerInfo.attrs.getOriginalAudioUsage() != AudioAttributes.USAGE_UNKNOWN
+ ? " | audioUsage=" + AudioAttributes.usageToString(
+ mCallerInfo.attrs.getOriginalAudioUsage())
+ : "";
+ String callerStr = String.format(Locale.ROOT,
+ " | %s (uid=%d, deviceId=%d) | reason: %s",
+ mCallerInfo.opPkg, mCallerInfo.uid, mCallerInfo.deviceId, mCallerInfo.reason);
+ pw.println(timingsStr + paramStr + audioUsageStr + callerStr);
+ }
+
+ @Override
+ public String toString() {
+ return "createTime: " + formatTime(mCreateTime, /* includeDate= */ true)
+ + ", startTime: " + formatTime(mStartTime, /* includeDate= */ true)
+ + ", endTime: " + (mEndTime == 0 ? null : formatTime(mEndTime,
+ /* includeDate= */ true))
+ + ", durationMs: " + mDurationMs
+ + ", status: " + mStatus.name().toLowerCase(Locale.ROOT)
+ + ", callerInfo: " + mCallerInfo;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index bb2a17c..27f92b2 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -16,6 +16,8 @@
package com.android.server.vibrator;
+import static com.android.server.vibrator.VibrationSession.DebugInfo.formatTime;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.media.AudioAttributes;
@@ -31,9 +33,6 @@
import android.util.IndentingPrintWriter;
import android.util.proto.ProtoOutputStream;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
@@ -42,11 +41,6 @@
* The base class for all vibrations.
*/
abstract class Vibration {
- private static final DateTimeFormatter DEBUG_TIME_FORMATTER = DateTimeFormatter.ofPattern(
- "HH:mm:ss.SSS");
- private static final DateTimeFormatter DEBUG_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(
- "MM-dd HH:mm:ss.SSS");
-
// Used to generate globally unique vibration ids.
private static final AtomicInteger sNextVibrationId = new AtomicInteger(1); // 0 = no callback
@@ -399,12 +393,5 @@
proto.write(PrimitiveSegmentProto.DELAY, segment.getDelay());
proto.end(token);
}
-
- private String formatTime(long timeInMillis, boolean includeDate) {
- return (includeDate ? DEBUG_DATE_TIME_FORMATTER : DEBUG_TIME_FORMATTER)
- // Ensure timezone is retrieved at formatting time
- .withZone(ZoneId.systemDefault())
- .format(Instant.ofEpochMilli(timeInMillis));
- }
}
}
diff --git a/services/core/java/com/android/server/vibrator/VibrationSession.java b/services/core/java/com/android/server/vibrator/VibrationSession.java
index b511ba8..ae95a70 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSession.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSession.java
@@ -25,7 +25,11 @@
import android.util.proto.ProtoOutputStream;
import java.io.PrintWriter;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Represents a generic vibration session that plays one or more vibration requests.
@@ -39,6 +43,16 @@
*/
interface VibrationSession {
+ // Used to generate globally unique session ids.
+ AtomicInteger sNextSessionId = new AtomicInteger(1); // 0 = no callback
+
+ static long nextSessionId() {
+ return sNextSessionId.getAndIncrement();
+ }
+
+ /** Returns the session id. */
+ long getSessionId();
+
/** Returns the session creation time from {@link android.os.SystemClock#uptimeMillis()}. */
long getCreateUptimeMillis();
@@ -105,6 +119,14 @@
void notifySyncedVibratorsCallback(long vibrationId);
/**
+ * Notify vibrator manager have completed the vibration session.
+ *
+ * <p>This will be called by the vibrator manager hardware callback indicating the session
+ * is complete, either because it was ended or cancelled by the service or the vendor.
+ */
+ void notifySessionCallback();
+
+ /**
* Session status with reference to values from vibratormanagerservice.proto for logging.
*/
enum Status {
@@ -212,6 +234,17 @@
*/
interface DebugInfo {
+ DateTimeFormatter DEBUG_TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
+ DateTimeFormatter DEBUG_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(
+ "MM-dd HH:mm:ss.SSS");
+
+ static String formatTime(long timeInMillis, boolean includeDate) {
+ return (includeDate ? DEBUG_DATE_TIME_FORMATTER : DEBUG_TIME_FORMATTER)
+ // Ensure timezone is retrieved at formatting time
+ .withZone(ZoneId.systemDefault())
+ .format(Instant.ofEpochMilli(timeInMillis));
+ }
+
/** Return the vibration session status. */
Status getStatus();
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index ff34911..4764481 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -32,6 +32,7 @@
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.hardware.vibrator.IVibrator;
+import android.hardware.vibrator.IVibratorManager;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Build;
@@ -40,6 +41,7 @@
import android.os.ExternalVibrationScale;
import android.os.Handler;
import android.os.IBinder;
+import android.os.ICancellationSignal;
import android.os.IExternalVibratorService;
import android.os.IVibratorManagerService;
import android.os.IVibratorStateListener;
@@ -57,6 +59,7 @@
import android.os.VibrationEffect;
import android.os.VibratorInfo;
import android.os.vibrator.Flags;
+import android.os.vibrator.IVibrationSessionCallback;
import android.os.vibrator.PrebakedSegment;
import android.os.vibrator.VibrationConfig;
import android.os.vibrator.VibrationEffectSegment;
@@ -103,7 +106,7 @@
private static final String EXTERNAL_VIBRATOR_SERVICE = "external_vibrator_service";
private static final String VIBRATOR_CONTROL_SERVICE =
"android.frameworks.vibrator.IVibratorControlService/default";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
private static final VibrationAttributes DEFAULT_ATTRIBUTES =
new VibrationAttributes.Builder().build();
private static final int ATTRIBUTES_ALL_BYPASS_FLAGS =
@@ -159,12 +162,14 @@
new VibrationThreadCallbacks();
private final ExternalVibrationCallbacks mExternalVibrationCallbacks =
new ExternalVibrationCallbacks();
+ private final VendorVibrationSessionCallbacks mVendorVibrationSessionCallbacks =
+ new VendorVibrationSessionCallbacks();
@GuardedBy("mLock")
private final SparseArray<AlwaysOnVibration> mAlwaysOnEffects = new SparseArray<>();
@GuardedBy("mLock")
- private VibrationSession mCurrentVibration;
+ private VibrationSession mCurrentSession;
@GuardedBy("mLock")
- private VibrationSession mNextVibration;
+ private VibrationSession mNextSession;
@GuardedBy("mLock")
private boolean mServiceReady;
@@ -191,14 +196,14 @@
// When the system is entering a non-interactive state, we want to cancel
// vibrations in case a misbehaving app has abandoned them.
synchronized (mLock) {
- maybeClearCurrentAndNextVibrationsLocked(
+ maybeClearCurrentAndNextSessionsLocked(
VibratorManagerService.this::shouldCancelOnScreenOffLocked,
Status.CANCELLED_BY_SCREEN_OFF);
}
} else if (android.multiuser.Flags.addUiForSoundsFromBackgroundUsers()
&& intent.getAction().equals(BackgroundUserSoundNotifier.ACTION_MUTE_SOUND)) {
synchronized (mLock) {
- maybeClearCurrentAndNextVibrationsLocked(
+ maybeClearCurrentAndNextSessionsLocked(
VibratorManagerService.this::shouldCancelOnFgUserRequest,
Status.CANCELLED_BY_FOREGROUND_USER);
}
@@ -215,14 +220,14 @@
return;
}
synchronized (mLock) {
- maybeClearCurrentAndNextVibrationsLocked(
+ maybeClearCurrentAndNextSessionsLocked(
VibratorManagerService.this::shouldCancelAppOpModeChangedLocked,
Status.CANCELLED_BY_APP_OPS);
}
}
};
- static native long nativeInit(OnSyncedVibrationCompleteListener listener);
+ static native long nativeInit(VibratorManagerNativeCallbacks listener);
static native long nativeGetFinalizer();
@@ -236,6 +241,13 @@
static native void nativeCancelSynced(long nativeServicePtr);
+ static native boolean nativeStartSession(long nativeServicePtr, long sessionId,
+ int[] vibratorIds);
+
+ static native void nativeEndSession(long nativeServicePtr, long sessionId, boolean shouldAbort);
+
+ static native void nativeClearSessions(long nativeServicePtr);
+
@VisibleForTesting
VibratorManagerService(Context context, Injector injector) {
mContext = context;
@@ -303,6 +315,9 @@
// Reset the hardware to a default state, in case this is a runtime restart instead of a
// fresh boot.
mNativeWrapper.cancelSynced();
+ if (Flags.vendorVibrationEffects()) {
+ mNativeWrapper.clearSessions();
+ }
for (int i = 0; i < mVibrators.size(); i++) {
mVibrators.valueAt(i).reset();
}
@@ -363,6 +378,11 @@
}
@Override // Binder call
+ public int getCapabilities() {
+ return (int) mCapabilities;
+ }
+
+ @Override // Binder call
@Nullable
public VibratorInfo getVibratorInfo(int vibratorId) {
final VibratorController controller = mVibrators.get(vibratorId);
@@ -590,11 +610,17 @@
logAndRecordVibrationAttempt(effect, callerInfo, Status.IGNORED_ERROR_TOKEN);
return null;
}
- if (effect.hasVendorEffects()
- && !hasPermission(android.Manifest.permission.VIBRATE_VENDOR_EFFECTS)) {
- Slog.e(TAG, "vibrate; no permission for vendor effects");
- logAndRecordVibrationAttempt(effect, callerInfo, Status.IGNORED_MISSING_PERMISSION);
- return null;
+ if (effect.hasVendorEffects()) {
+ if (!Flags.vendorVibrationEffects()) {
+ Slog.e(TAG, "vibrate; vendor effects feature disabled");
+ logAndRecordVibrationAttempt(effect, callerInfo, Status.IGNORED_UNSUPPORTED);
+ return null;
+ }
+ if (!hasPermission(android.Manifest.permission.VIBRATE_VENDOR_EFFECTS)) {
+ Slog.e(TAG, "vibrate; no permission for vendor effects");
+ logAndRecordVibrationAttempt(effect, callerInfo, Status.IGNORED_MISSING_PERMISSION);
+ return null;
+ }
}
enforceUpdateAppOpsStatsPermission(uid);
if (!isEffectValid(effect)) {
@@ -623,7 +649,7 @@
// Check if ongoing vibration is more important than this vibration.
if (ignoreStatus == null) {
- Vibration.EndInfo vibrationEndInfo = shouldIgnoreVibrationForOngoingLocked(session);
+ Vibration.EndInfo vibrationEndInfo = shouldIgnoreForOngoingLocked(session);
if (vibrationEndInfo != null) {
ignoreStatus = vibrationEndInfo.status;
ignoredBy = vibrationEndInfo.endedBy;
@@ -634,8 +660,8 @@
if (ignoreStatus == null) {
final long ident = Binder.clearCallingIdentity();
try {
- if (mCurrentVibration != null) {
- if (shouldPipelineVibrationLocked(mCurrentVibration, vib)) {
+ if (mCurrentSession != null) {
+ if (shouldPipelineVibrationLocked(mCurrentSession, vib)) {
// Don't cancel the current vibration if it's pipeline-able.
// Note that if there is a pending next vibration that can't be
// pipelined, it will have already cancelled the current one, so we
@@ -645,12 +671,12 @@
}
} else {
vib.stats.reportInterruptedAnotherVibration(
- mCurrentVibration.getCallerInfo());
- mCurrentVibration.requestEnd(Status.CANCELLED_SUPERSEDED, callerInfo,
+ mCurrentSession.getCallerInfo());
+ mCurrentSession.requestEnd(Status.CANCELLED_SUPERSEDED, callerInfo,
/* immediate= */ false);
}
}
- clearNextVibrationLocked(Status.CANCELLED_SUPERSEDED, callerInfo);
+ clearNextSessionLocked(Status.CANCELLED_SUPERSEDED, callerInfo);
ignoreStatus = startVibrationLocked(session);
} finally {
Binder.restoreCallingIdentity(ident);
@@ -659,7 +685,7 @@
// Ignored or failed to start the vibration, end it and report metrics right away.
if (ignoreStatus != null) {
- endVibrationLocked(session, ignoreStatus, ignoredBy);
+ endSessionLocked(session, ignoreStatus, ignoredBy);
}
return vib;
}
@@ -681,14 +707,14 @@
try {
// TODO(b/370948466): investigate why token not checked on external vibrations.
IBinder cancelToken =
- (mNextVibration instanceof ExternalVibrationSession) ? null : token;
- if (shouldCancelVibration(mNextVibration, usageFilter, cancelToken)) {
- clearNextVibrationLocked(Status.CANCELLED_BY_USER);
+ (mNextSession instanceof ExternalVibrationSession) ? null : token;
+ if (shouldCancelSession(mNextSession, usageFilter, cancelToken)) {
+ clearNextSessionLocked(Status.CANCELLED_BY_USER);
}
cancelToken =
- (mCurrentVibration instanceof ExternalVibrationSession) ? null : token;
- if (shouldCancelVibration(mCurrentVibration, usageFilter, cancelToken)) {
- mCurrentVibration.requestEnd(Status.CANCELLED_BY_USER);
+ (mCurrentSession instanceof ExternalVibrationSession) ? null : token;
+ if (shouldCancelSession(mCurrentSession, usageFilter, cancelToken)) {
+ mCurrentSession.requestEnd(Status.CANCELLED_BY_USER);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -699,6 +725,141 @@
}
}
+ @android.annotation.EnforcePermission(allOf = {
+ android.Manifest.permission.VIBRATE,
+ android.Manifest.permission.VIBRATE_VENDOR_EFFECTS,
+ android.Manifest.permission.START_VIBRATION_SESSIONS,
+ })
+ @Override // Binder call
+ public ICancellationSignal startVendorVibrationSession(int uid, int deviceId, String opPkg,
+ int[] vibratorIds, VibrationAttributes attrs, String reason,
+ IVibrationSessionCallback callback) {
+ startVendorVibrationSession_enforcePermission();
+ Trace.traceBegin(TRACE_TAG_VIBRATOR, "startVibrationSession");
+ try {
+ VendorVibrationSession session = startVendorVibrationSessionInternal(
+ uid, deviceId, opPkg, vibratorIds, attrs, reason, callback);
+ return session == null ? null : session.getCancellationSignal();
+ } finally {
+ Trace.traceEnd(TRACE_TAG_VIBRATOR);
+ }
+ }
+
+ VendorVibrationSession startVendorVibrationSessionInternal(int uid, int deviceId, String opPkg,
+ int[] vibratorIds, VibrationAttributes attrs, String reason,
+ IVibrationSessionCallback callback) {
+ if (!Flags.vendorVibrationEffects()) {
+ throw new UnsupportedOperationException("Vibration sessions not supported");
+ }
+ attrs = fixupVibrationAttributes(attrs, /* effect= */ null);
+ CallerInfo callerInfo = new CallerInfo(attrs, uid, deviceId, opPkg, reason);
+ if (callback == null) {
+ Slog.e(TAG, "session callback must not be null");
+ logAndRecordSessionAttempt(callerInfo, Status.IGNORED_ERROR_TOKEN);
+ return null;
+ }
+ if (vibratorIds == null) {
+ vibratorIds = new int[0];
+ }
+ enforceUpdateAppOpsStatsPermission(uid);
+ VendorVibrationSession session = new VendorVibrationSession(callerInfo, mHandler,
+ mVendorVibrationSessionCallbacks, vibratorIds, callback);
+
+ if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
+ // Force update of user settings before checking if this vibration effect should
+ // be ignored or scaled.
+ mVibrationSettings.update();
+ }
+
+ synchronized (mLock) {
+ if (DEBUG) {
+ Slog.d(TAG, "Starting session " + session.getSessionId());
+ }
+
+ Status ignoreStatus = null;
+ CallerInfo ignoredBy = null;
+
+ // Check if HAL has capability to start sessions.
+ if ((mCapabilities & IVibratorManager.CAP_START_SESSIONS) == 0) {
+ if (DEBUG) {
+ Slog.d(TAG, "Missing capability to start sessions, ignoring request");
+ }
+ ignoreStatus = Status.IGNORED_UNSUPPORTED;
+ }
+
+ // Check if any vibrator ID was requested.
+ if (ignoreStatus == null && vibratorIds.length == 0) {
+ if (DEBUG) {
+ Slog.d(TAG, "Empty vibrator ids to start session, ignoring request");
+ }
+ ignoreStatus = Status.IGNORED_UNSUPPORTED;
+ }
+
+ // Check if user settings or DnD is set to ignore this session.
+ if (ignoreStatus == null) {
+ ignoreStatus = shouldIgnoreVibrationLocked(callerInfo);
+ }
+
+ // Check if ongoing vibration is more important than this session.
+ if (ignoreStatus == null) {
+ Vibration.EndInfo vibrationEndInfo = shouldIgnoreForOngoingLocked(session);
+ if (vibrationEndInfo != null) {
+ ignoreStatus = vibrationEndInfo.status;
+ ignoredBy = vibrationEndInfo.endedBy;
+ }
+ }
+
+ if (ignoreStatus == null) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ // If not ignored so far then stop ongoing sessions before starting this one.
+ clearNextSessionLocked(Status.CANCELLED_SUPERSEDED, callerInfo);
+ if (mCurrentSession != null) {
+ mNextSession = session;
+ mCurrentSession.requestEnd(Status.CANCELLED_SUPERSEDED, callerInfo,
+ /* immediate= */ false);
+ } else {
+ ignoreStatus = startVendorSessionLocked(session);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ // Ignored or failed to start the session, end it and report metrics right away.
+ if (ignoreStatus != null) {
+ endSessionLocked(session, ignoreStatus, ignoredBy);
+ }
+ return session;
+ }
+ }
+
+ @GuardedBy("mLock")
+ @Nullable
+ private Status startVendorSessionLocked(VendorVibrationSession session) {
+ Trace.traceBegin(TRACE_TAG_VIBRATOR, "startSessionLocked");
+ try {
+ if (session.isEnded()) {
+ // Session already ended, possibly cancelled by app cancellation signal.
+ return session.getStatus();
+ }
+ if (!session.linkToDeath()) {
+ return Status.IGNORED_ERROR_TOKEN;
+ }
+ if (!mNativeWrapper.startSession(session.getSessionId(), session.getVibratorIds())) {
+ Slog.e(TAG, "Error starting session " + session.getSessionId()
+ + " on vibrators " + Arrays.toString(session.getVibratorIds()));
+ session.unlinkToDeath();
+ return Status.IGNORED_UNSUPPORTED;
+ }
+ session.notifyStart();
+ mCurrentSession = session;
+ return null;
+ } finally {
+ Trace.traceEnd(TRACE_TAG_VIBRATOR);
+ }
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
@@ -747,8 +908,8 @@
pw.println("CurrentVibration:");
pw.increaseIndent();
- if (mCurrentVibration != null) {
- mCurrentVibration.getDebugInfo().dump(pw);
+ if (mCurrentSession != null) {
+ mCurrentSession.getDebugInfo().dump(pw);
} else {
pw.println("null");
}
@@ -757,8 +918,8 @@
pw.println("NextVibration:");
pw.increaseIndent();
- if (mNextVibration != null) {
- mNextVibration.getDebugInfo().dump(pw);
+ if (mNextSession != null) {
+ mNextSession.getDebugInfo().dump(pw);
} else {
pw.println("null");
}
@@ -782,8 +943,8 @@
synchronized (mLock) {
mVibrationSettings.dump(proto);
mVibrationScaler.dump(proto);
- if (mCurrentVibration != null) {
- mCurrentVibration.getDebugInfo().dump(proto,
+ if (mCurrentSession != null) {
+ mCurrentSession.getDebugInfo().dump(proto,
VibratorManagerServiceDumpProto.CURRENT_VIBRATION);
}
for (int i = 0; i < mVibrators.size(); i++) {
@@ -816,18 +977,18 @@
}
// TODO(b/372241975): investigate why external vibrations were not handled here before
- if (mCurrentVibration == null
- || (mCurrentVibration instanceof ExternalVibrationSession)) {
+ if (mCurrentSession == null
+ || (mCurrentSession instanceof ExternalVibrationSession)) {
return;
}
- Status ignoreStatus = shouldIgnoreVibrationLocked(mCurrentVibration.getCallerInfo());
+ Status ignoreStatus = shouldIgnoreVibrationLocked(mCurrentSession.getCallerInfo());
if (inputDevicesChanged || (ignoreStatus != null)) {
if (DEBUG) {
Slog.d(TAG, "Canceling vibration because settings changed: "
+ (inputDevicesChanged ? "input devices changed" : ignoreStatus));
}
- mCurrentVibration.requestEnd(Status.CANCELLED_BY_SETTINGS_UPDATE);
+ mCurrentSession.requestEnd(Status.CANCELLED_BY_SETTINGS_UPDATE);
}
}
}
@@ -866,15 +1027,15 @@
if (mInputDeviceDelegate.isAvailable()) {
return startVibrationOnInputDevicesLocked(session.getVibration());
}
- if (mCurrentVibration == null) {
+ if (mCurrentSession == null) {
return startVibrationOnThreadLocked(session);
}
// If there's already a vibration queued (waiting for the previous one to finish
// cancelling), end it cleanly and replace it with the new one.
// Note that we don't consider pipelining here, because new pipelined ones should
// replace pending non-executing pipelined ones anyway.
- clearNextVibrationLocked(Status.IGNORED_SUPERSEDED, session.getCallerInfo());
- mNextVibration = session;
+ clearNextSessionLocked(Status.IGNORED_SUPERSEDED, session.getCallerInfo());
+ mNextSession = session;
return null;
} finally {
Trace.traceEnd(TRACE_TAG_VIBRATOR);
@@ -891,16 +1052,16 @@
case AppOpsManager.MODE_ALLOWED:
Trace.asyncTraceBegin(TRACE_TAG_VIBRATOR, "vibration", 0);
// Make sure mCurrentVibration is set while triggering the VibrationThread.
- mCurrentVibration = session;
- if (!mCurrentVibration.linkToDeath()) {
+ mCurrentSession = session;
+ if (!mCurrentSession.linkToDeath()) {
// Shouldn't happen. The method call already logs.
- mCurrentVibration = null; // Aborted.
+ mCurrentSession = null; // Aborted.
return Status.IGNORED_ERROR_TOKEN;
}
if (!mVibrationThread.runVibrationOnVibrationThread(conductor)) {
// Shouldn't happen. The method call already logs.
session.setVibrationConductor(null); // Rejected by thread, clear it in session.
- mCurrentVibration = null; // Aborted.
+ mCurrentSession = null; // Aborted.
return Status.IGNORED_ERROR_SCHEDULING;
}
return null;
@@ -914,23 +1075,29 @@
}
@GuardedBy("mLock")
- private void maybeStartNextSingleVibrationLocked() {
- if (mNextVibration instanceof SingleVibrationSession session) {
- mNextVibration = null;
+ private void maybeStartNextSessionLocked() {
+ if (mNextSession instanceof SingleVibrationSession session) {
+ mNextSession = null;
Status errorStatus = startVibrationOnThreadLocked(session);
if (errorStatus != null) {
- endVibrationLocked(session, errorStatus);
+ endSessionLocked(session, errorStatus);
}
- }
+ } else if (mNextSession instanceof VendorVibrationSession session) {
+ mNextSession = null;
+ Status errorStatus = startVendorSessionLocked(session);
+ if (errorStatus != null) {
+ endSessionLocked(session, errorStatus);
+ }
+ } // External vibrations cannot be started asynchronously.
}
@GuardedBy("mLock")
- private void endVibrationLocked(VibrationSession session, Status status) {
- endVibrationLocked(session, status, /* endedBy= */ null);
+ private void endSessionLocked(VibrationSession session, Status status) {
+ endSessionLocked(session, status, /* endedBy= */ null);
}
@GuardedBy("mLock")
- private void endVibrationLocked(VibrationSession session, Status status, CallerInfo endedBy) {
+ private void endSessionLocked(VibrationSession session, Status status, CallerInfo endedBy) {
session.requestEnd(status, endedBy, /* immediate= */ false);
logAndRecordVibration(session.getDebugInfo());
}
@@ -975,6 +1142,13 @@
VibrationScaler.ADAPTIVE_SCALE_NONE));
}
+ private void logAndRecordSessionAttempt(CallerInfo callerInfo, Status status) {
+ logAndRecordVibration(
+ new VendorVibrationSession.DebugInfoImpl(status, callerInfo,
+ SystemClock.uptimeMillis(), System.currentTimeMillis(),
+ /* startTime= */ 0, /* endUptime= */ 0, /* endTime= */ 0));
+ }
+
private void logAndRecordVibration(DebugInfo info) {
info.logMetrics(mFrameworkStatsLogger);
logVibrationStatus(info.getCallerInfo().uid, info.getCallerInfo().attrs, info.getStatus());
@@ -1026,25 +1200,40 @@
}
}
+ private void onVibrationSessionComplete(long sessionId) {
+ synchronized (mLock) {
+ if (mCurrentSession == null || mCurrentSession.getSessionId() != sessionId) {
+ if (DEBUG) {
+ Slog.d(TAG, "Vibration session " + sessionId + " callback ignored");
+ }
+ return;
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "Vibration session " + sessionId + " complete, notifying session");
+ }
+ mCurrentSession.notifySessionCallback();
+ }
+ }
+
private void onSyncedVibrationComplete(long vibrationId) {
synchronized (mLock) {
- if (mCurrentVibration != null) {
+ if (mCurrentSession != null) {
if (DEBUG) {
Slog.d(TAG, "Synced vibration " + vibrationId + " complete, notifying thread");
}
- mCurrentVibration.notifySyncedVibratorsCallback(vibrationId);
+ mCurrentSession.notifySyncedVibratorsCallback(vibrationId);
}
}
}
private void onVibrationComplete(int vibratorId, long vibrationId) {
synchronized (mLock) {
- if (mCurrentVibration != null) {
+ if (mCurrentSession != null) {
if (DEBUG) {
Slog.d(TAG, "Vibration " + vibrationId + " on vibrator " + vibratorId
+ " complete, notifying thread");
}
- mCurrentVibration.notifyVibratorCallback(vibratorId, vibrationId);
+ mCurrentSession.notifyVibratorCallback(vibratorId, vibrationId);
}
}
}
@@ -1056,10 +1245,10 @@
*/
@GuardedBy("mLock")
@Nullable
- private Vibration.EndInfo shouldIgnoreVibrationForOngoingLocked(VibrationSession session) {
- if (mNextVibration != null) {
- Vibration.EndInfo vibrationEndInfo = shouldIgnoreVibrationForOngoing(session,
- mNextVibration);
+ private Vibration.EndInfo shouldIgnoreForOngoingLocked(VibrationSession session) {
+ if (mNextSession != null) {
+ Vibration.EndInfo vibrationEndInfo = shouldIgnoreForOngoing(session,
+ mNextSession);
if (vibrationEndInfo != null) {
// Next vibration has higher importance than the new one, so the new vibration
// should be ignored.
@@ -1067,13 +1256,13 @@
}
}
- if (mCurrentVibration != null) {
- if (mCurrentVibration.wasEndRequested()) {
+ if (mCurrentSession != null) {
+ if (mCurrentSession.wasEndRequested()) {
// Current session has ended or is cancelling, should not block incoming vibrations.
return null;
}
- return shouldIgnoreVibrationForOngoing(session, mCurrentVibration);
+ return shouldIgnoreForOngoing(session, mCurrentSession);
}
return null;
@@ -1086,7 +1275,7 @@
* @return a Vibration.EndInfo if the vibration should be ignored, null otherwise.
*/
@Nullable
- private static Vibration.EndInfo shouldIgnoreVibrationForOngoing(
+ private static Vibration.EndInfo shouldIgnoreForOngoing(
@NonNull VibrationSession newSession, @NonNull VibrationSession ongoingSession) {
int newSessionImportance = getVibrationImportance(newSession);
@@ -1214,11 +1403,15 @@
* @param tokenFilter The binder token to identify the vibration origin. Only vibrations
* started with the same token can be cancelled with it.
*/
- private boolean shouldCancelVibration(@Nullable VibrationSession session, int usageFilter,
+ private boolean shouldCancelSession(@Nullable VibrationSession session, int usageFilter,
@Nullable IBinder tokenFilter) {
if (session == null) {
return false;
}
+ if (session instanceof VendorVibrationSession) {
+ // Vendor sessions should not be cancelled by Vibrator.cancel API.
+ return false;
+ }
if ((tokenFilter != null) && (tokenFilter != session.getCallerToken())) {
// Vibration from a different app, this should not cancel it.
return false;
@@ -1572,10 +1765,10 @@
Trace.traceBegin(TRACE_TAG_VIBRATOR, "onVibrationThreadReleased");
try {
synchronized (mLock) {
- if (!(mCurrentVibration instanceof SingleVibrationSession session)) {
+ if (!(mCurrentSession instanceof SingleVibrationSession session)) {
if (Build.IS_DEBUGGABLE) {
Slog.wtf(TAG, "VibrationSession invalid on vibration thread release."
- + " currentSession=" + mCurrentVibration);
+ + " currentSession=" + mCurrentSession);
}
// Only single vibration sessions are ended by thread being released. Abort.
return;
@@ -1586,11 +1779,11 @@
+ " expected=%d, released=%d",
session.getVibration().id, vibrationId));
}
- finishAppOpModeLocked(mCurrentVibration.getCallerInfo());
- clearCurrentVibrationLocked();
+ finishAppOpModeLocked(mCurrentSession.getCallerInfo());
+ clearCurrentSessionLocked();
Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
- // Start next vibration if it's a single vibration waiting for the thread.
- maybeStartNextSingleVibrationLocked();
+ // Start next vibration if it's waiting for the thread.
+ maybeStartNextSessionLocked();
}
} finally {
Trace.traceEnd(TRACE_TAG_VIBRATOR);
@@ -1613,10 +1806,10 @@
Trace.traceBegin(TRACE_TAG_VIBRATOR, "onExternalVibrationReleased");
try {
synchronized (mLock) {
- if (!(mCurrentVibration instanceof ExternalVibrationSession session)) {
+ if (!(mCurrentSession instanceof ExternalVibrationSession session)) {
if (Build.IS_DEBUGGABLE) {
Slog.wtf(TAG, "VibrationSession invalid on external vibration release."
- + " currentSession=" + mCurrentVibration);
+ + " currentSession=" + mCurrentSession);
}
// Only external vibration sessions are ended by this callback. Abort.
return;
@@ -1627,10 +1820,9 @@
+ " expected=%d, released=%d", session.id, vibrationId));
}
setExternalControl(false, session.stats);
- clearCurrentVibrationLocked();
- // Start next vibration if it's a single vibration waiting for the external
- // control to be over.
- maybeStartNextSingleVibrationLocked();
+ clearCurrentSessionLocked();
+ // Start next vibration if it's waiting for the external control to be over.
+ maybeStartNextSessionLocked();
}
} finally {
Trace.traceEnd(TRACE_TAG_VIBRATOR);
@@ -1638,19 +1830,75 @@
}
}
- /** Listener for synced vibration completion callbacks from native. */
+ /**
+ * Implementation of {@link ExternalVibrationSession.VibratorManagerHooks} that controls
+ * external vibrations and reports them when finished.
+ */
+ private final class VendorVibrationSessionCallbacks
+ implements VendorVibrationSession.VibratorManagerHooks {
+
+ @Override
+ public void endSession(long sessionId, boolean shouldAbort) {
+ if (DEBUG) {
+ Slog.d(TAG, "Vibration session " + sessionId
+ + (shouldAbort ? " aborting" : " ending"));
+ }
+ Trace.traceBegin(TRACE_TAG_VIBRATOR, "endSession");
+ try {
+ mNativeWrapper.endSession(sessionId, shouldAbort);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_VIBRATOR);
+ }
+ }
+
+ @Override
+ public void onSessionReleased(long sessionId) {
+ if (DEBUG) {
+ Slog.d(TAG, "Vibration session " + sessionId + " released");
+ }
+ Trace.traceBegin(TRACE_TAG_VIBRATOR, "onVendorSessionReleased");
+ try {
+ synchronized (mLock) {
+ if (!(mCurrentSession instanceof VendorVibrationSession session)) {
+ if (Build.IS_DEBUGGABLE) {
+ Slog.wtf(TAG, "VibrationSession invalid on vibration session release."
+ + " currentSession=" + mCurrentSession);
+ }
+ // Only vendor vibration sessions are ended by this callback. Abort.
+ return;
+ }
+ if (Build.IS_DEBUGGABLE && (session.getSessionId() != sessionId)) {
+ Slog.wtf(TAG, TextUtils.formatSimple(
+ "SessionId mismatch on vendor vibration session release."
+ + " expected=%d, released=%d",
+ session.getSessionId(), sessionId));
+ }
+ clearCurrentSessionLocked();
+ // Start next vibration if it's waiting for the HAL session to be over.
+ maybeStartNextSessionLocked();
+ }
+ } finally {
+ Trace.traceEnd(TRACE_TAG_VIBRATOR);
+ }
+ }
+ }
+
+ /** Listener for vibrator manager completion callbacks from native. */
@VisibleForTesting
- interface OnSyncedVibrationCompleteListener {
+ interface VibratorManagerNativeCallbacks {
/** Callback triggered when synced vibration is complete. */
- void onComplete(long vibrationId);
+ void onSyncedVibrationComplete(long vibrationId);
+
+ /** Callback triggered when vibration session is complete. */
+ void onVibrationSessionComplete(long sessionId);
}
/**
* Implementation of listeners to native vibrators with a weak reference to this service.
*/
private static final class VibrationCompleteListener implements
- VibratorController.OnVibrationCompleteListener, OnSyncedVibrationCompleteListener {
+ VibratorController.OnVibrationCompleteListener, VibratorManagerNativeCallbacks {
private WeakReference<VibratorManagerService> mServiceRef;
VibrationCompleteListener(VibratorManagerService service) {
@@ -1658,7 +1906,7 @@
}
@Override
- public void onComplete(long vibrationId) {
+ public void onSyncedVibrationComplete(long vibrationId) {
VibratorManagerService service = mServiceRef.get();
if (service != null) {
service.onSyncedVibrationComplete(vibrationId);
@@ -1666,6 +1914,14 @@
}
@Override
+ public void onVibrationSessionComplete(long sessionId) {
+ VibratorManagerService service = mServiceRef.get();
+ if (service != null) {
+ service.onVibrationSessionComplete(sessionId);
+ }
+ }
+
+ @Override
public void onComplete(int vibratorId, long vibrationId) {
VibratorManagerService service = mServiceRef.get();
if (service != null) {
@@ -1698,7 +1954,7 @@
private long mNativeServicePtr = 0;
/** Returns native pointer to newly created controller and connects with HAL service. */
- public void init(OnSyncedVibrationCompleteListener listener) {
+ public void init(VibratorManagerNativeCallbacks listener) {
mNativeServicePtr = nativeInit(listener);
long finalizerPtr = nativeGetFinalizer();
@@ -1734,6 +1990,21 @@
public void cancelSynced() {
nativeCancelSynced(mNativeServicePtr);
}
+
+ /** Start vibration session. */
+ public boolean startSession(long sessionId, @NonNull int[] vibratorIds) {
+ return nativeStartSession(mNativeServicePtr, sessionId, vibratorIds);
+ }
+
+ /** End vibration session. */
+ public void endSession(long sessionId, boolean shouldAbort) {
+ nativeEndSession(mNativeServicePtr, sessionId, shouldAbort);
+ }
+
+ /** Clear vibration sessions. */
+ public void clearSessions() {
+ nativeClearSessions(mNativeServicePtr);
+ }
}
/** Keep records of vibrations played and provide debug information for this service. */
@@ -1853,46 +2124,46 @@
/** Clears mNextVibration if set, ending it cleanly */
@GuardedBy("mLock")
- private void clearNextVibrationLocked(Status status) {
- clearNextVibrationLocked(status, /* endedBy= */ null);
+ private void clearNextSessionLocked(Status status) {
+ clearNextSessionLocked(status, /* endedBy= */ null);
}
/** Clears mNextVibration if set, ending it cleanly */
@GuardedBy("mLock")
- private void clearNextVibrationLocked(Status status, CallerInfo endedBy) {
- if (mNextVibration != null) {
+ private void clearNextSessionLocked(Status status, CallerInfo endedBy) {
+ if (mNextSession != null) {
if (DEBUG) {
- Slog.d(TAG, "Dropping pending vibration from " + mNextVibration.getCallerInfo()
+ Slog.d(TAG, "Dropping pending vibration from " + mNextSession.getCallerInfo()
+ " with status: " + status);
}
// Clearing next vibration before playing it, end it and report metrics right away.
- endVibrationLocked(mNextVibration, status, endedBy);
- mNextVibration = null;
+ endSessionLocked(mNextSession, status, endedBy);
+ mNextSession = null;
}
}
/** Clears mCurrentVibration if set, reporting metrics */
@GuardedBy("mLock")
- private void clearCurrentVibrationLocked() {
- if (mCurrentVibration != null) {
- mCurrentVibration.unlinkToDeath();
- logAndRecordVibration(mCurrentVibration.getDebugInfo());
- mCurrentVibration = null;
+ private void clearCurrentSessionLocked() {
+ if (mCurrentSession != null) {
+ mCurrentSession.unlinkToDeath();
+ logAndRecordVibration(mCurrentSession.getDebugInfo());
+ mCurrentSession = null;
mLock.notify(); // Notify if waiting for current vibration to end.
}
}
@GuardedBy("mLock")
- private void maybeClearCurrentAndNextVibrationsLocked(
+ private void maybeClearCurrentAndNextSessionsLocked(
Predicate<VibrationSession> shouldEndSessionPredicate, Status endStatus) {
// TODO(b/372241975): investigate why external vibrations were not handled here before
- if (!(mNextVibration instanceof ExternalVibrationSession)
- && shouldEndSessionPredicate.test(mNextVibration)) {
- clearNextVibrationLocked(endStatus);
+ if (!(mNextSession instanceof ExternalVibrationSession)
+ && shouldEndSessionPredicate.test(mNextSession)) {
+ clearNextSessionLocked(endStatus);
}
- if (!(mCurrentVibration instanceof ExternalVibrationSession)
- && shouldEndSessionPredicate.test(mCurrentVibration)) {
- mCurrentVibration.requestEnd(endStatus);
+ if (!(mCurrentSession instanceof ExternalVibrationSession)
+ && shouldEndSessionPredicate.test(mCurrentSession)) {
+ mCurrentSession.requestEnd(endStatus);
}
}
@@ -1902,12 +2173,12 @@
*
* @return true if the vibration completed, or false if waiting timed out.
*/
- public boolean waitForCurrentVibrationEnd(long maxWaitMillis) {
+ public boolean waitForCurrentSessionEnd(long maxWaitMillis) {
long now = SystemClock.elapsedRealtime();
long deadline = now + maxWaitMillis;
synchronized (mLock) {
while (true) {
- if (mCurrentVibration == null) {
+ if (mCurrentSession == null) {
return true; // Done
}
if (now >= deadline) { // Note that thread.wait(0) waits indefinitely.
@@ -1965,7 +2236,7 @@
synchronized (mLock) {
if (!hasExternalControlCapability()) {
- endVibrationLocked(session, Status.IGNORED_UNSUPPORTED);
+ endSessionLocked(session, Status.IGNORED_UNSUPPORTED);
return session.getScale();
}
@@ -1976,17 +2247,17 @@
Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid()
+ " tried to play externally controlled vibration"
+ " without VIBRATE permission, ignoring.");
- endVibrationLocked(session, Status.IGNORED_MISSING_PERMISSION);
+ endSessionLocked(session, Status.IGNORED_MISSING_PERMISSION);
return session.getScale();
}
Status ignoreStatus = shouldIgnoreVibrationLocked(session.callerInfo);
if (ignoreStatus != null) {
- endVibrationLocked(session, ignoreStatus);
+ endSessionLocked(session, ignoreStatus);
return session.getScale();
}
- if ((mCurrentVibration instanceof ExternalVibrationSession evs)
+ if ((mCurrentSession instanceof ExternalVibrationSession evs)
&& evs.isHoldingSameVibration(vib)) {
// We are already playing this external vibration, so we can return the same
// scale calculated in the previous call to this method.
@@ -1994,17 +2265,17 @@
}
// Check if ongoing vibration is more important than this vibration.
- Vibration.EndInfo ignoreInfo = shouldIgnoreVibrationForOngoingLocked(session);
+ Vibration.EndInfo ignoreInfo = shouldIgnoreForOngoingLocked(session);
if (ignoreInfo != null) {
- endVibrationLocked(session, ignoreInfo.status, ignoreInfo.endedBy);
+ endSessionLocked(session, ignoreInfo.status, ignoreInfo.endedBy);
return session.getScale();
}
// First clear next request, so it won't start when the current one ends.
- clearNextVibrationLocked(Status.IGNORED_FOR_EXTERNAL, session.callerInfo);
- mNextVibration = session;
+ clearNextSessionLocked(Status.IGNORED_FOR_EXTERNAL, session.callerInfo);
+ mNextSession = session;
- if (mCurrentVibration != null) {
+ if (mCurrentSession != null) {
// Cancel any vibration that may be playing and ready the vibrator, even if
// we have an externally controlled vibration playing already.
// Since the interface defines that only one externally controlled
@@ -2016,36 +2287,36 @@
// as we would need to mute the old one still if it came from a different
// controller.
session.stats.reportInterruptedAnotherVibration(
- mCurrentVibration.getCallerInfo());
- mCurrentVibration.requestEnd(Status.CANCELLED_SUPERSEDED,
+ mCurrentSession.getCallerInfo());
+ mCurrentSession.requestEnd(Status.CANCELLED_SUPERSEDED,
session.callerInfo, /* immediate= */ true);
waitForCompletion = true;
}
}
// Wait for lock and interact with HAL to set external control outside main lock.
if (waitForCompletion) {
- if (!waitForCurrentVibrationEnd(VIBRATION_CANCEL_WAIT_MILLIS)) {
+ if (!waitForCurrentSessionEnd(VIBRATION_CANCEL_WAIT_MILLIS)) {
Slog.e(TAG, "Timed out waiting for vibration to cancel");
synchronized (mLock) {
- if (mNextVibration == session) {
- mNextVibration = null;
+ if (mNextSession == session) {
+ mNextSession = null;
}
- endVibrationLocked(session, Status.IGNORED_ERROR_CANCELLING);
+ endSessionLocked(session, Status.IGNORED_ERROR_CANCELLING);
return session.getScale();
}
}
}
synchronized (mLock) {
- if (mNextVibration == session) {
+ if (mNextSession == session) {
// This is still the next vibration to be played.
- mNextVibration = null;
+ mNextSession = null;
} else {
// A new request took the place of this one, maybe with higher importance.
// Next vibration already cleared with the right status, just return here.
return session.getScale();
}
if (!session.linkToDeath()) {
- endVibrationLocked(session, Status.IGNORED_ERROR_TOKEN);
+ endSessionLocked(session, Status.IGNORED_ERROR_TOKEN);
return session.getScale();
}
if (DEBUG) {
@@ -2062,7 +2333,7 @@
// should be ignored or scaled.
mVibrationSettings.update();
}
- mCurrentVibration = session;
+ mCurrentSession = session;
session.scale(mVibrationScaler, attrs.getUsage());
// Vibrator will start receiving data from external channels after this point.
@@ -2080,12 +2351,12 @@
Trace.traceBegin(TRACE_TAG_VIBRATOR, "onExternalVibrationStop");
try {
synchronized (mLock) {
- if ((mCurrentVibration instanceof ExternalVibrationSession evs)
+ if ((mCurrentSession instanceof ExternalVibrationSession evs)
&& evs.isHoldingSameVibration(vib)) {
if (DEBUG) {
Slog.d(TAG, "Stopping external vibration: " + vib);
}
- mCurrentVibration.requestEnd(Status.FINISHED);
+ mCurrentSession.requestEnd(Status.FINISHED);
}
}
} finally {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 5cff37a..10f096c 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -858,10 +858,12 @@
wpdData.mPadding, mDisplayId, wallpaper.mWhich, connection.mInfo,
wallpaper.getDescription());
} else {
+ WallpaperDescription desc = new WallpaperDescription.Builder().setComponent(
+ (connection.mInfo != null) ? connection.mInfo.getComponent()
+ : null).build();
connection.mService.attach(connection, mToken, TYPE_WALLPAPER, false,
wpdData.mWidth, wpdData.mHeight,
- wpdData.mPadding, mDisplayId, wallpaper.mWhich, connection.mInfo,
- /* description= */ null);
+ wpdData.mPadding, mDisplayId, wallpaper.mWhich, connection.mInfo, desc);
}
} catch (RemoteException e) {
Slog.w(TAG, "Failed attaching wallpaper on display", e);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index cf17804..4857b02e 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1725,9 +1725,6 @@
return;
}
Transition transit = task.mTransitionController.requestCloseTransitionIfNeeded(task);
- if (transit == null) {
- transit = task.mTransitionController.getCollectingTransition();
- }
if (transit != null) {
transit.collectClose(task);
if (!task.mTransitionController.useFullReadyTracking()) {
@@ -1739,7 +1736,15 @@
// before anything that may need it to wait (setReady(false)).
transit.setReady(task, true);
}
+ } else {
+ // If we failed to create a transition, there might be already a currently collecting
+ // transition. Let's use it if possible.
+ transit = task.mTransitionController.getCollectingTransition();
+ if (transit != null) {
+ transit.collectClose(task);
+ }
}
+
// Consume the stopping activities immediately so activity manager won't skip killing
// the process because it is still foreground state, i.e. RESUMED -> PAUSING set from
// removeActivities -> finishIfPossible.
diff --git a/services/core/java/com/android/server/wm/AppCompatUtils.java b/services/core/java/com/android/server/wm/AppCompatUtils.java
index db76eb9..ebb50db 100644
--- a/services/core/java/com/android/server/wm/AppCompatUtils.java
+++ b/services/core/java/com/android/server/wm/AppCompatUtils.java
@@ -164,41 +164,46 @@
appCompatTaskInfo.setIsFromLetterboxDoubleTap(reachabilityOverrides.isFromDoubleTap());
- final Rect bounds = top.getBounds();
- final Rect appBounds = getAppBounds(top);
- appCompatTaskInfo.topActivityLetterboxWidth = bounds.width();
- appCompatTaskInfo.topActivityLetterboxHeight = bounds.height();
- appCompatTaskInfo.topActivityLetterboxAppWidth = appBounds.width();
- appCompatTaskInfo.topActivityLetterboxAppHeight = appBounds.height();
+ final boolean isTopActivityLetterboxed = top.areBoundsLetterboxed();
+ appCompatTaskInfo.setTopActivityLetterboxed(isTopActivityLetterboxed);
+ if (isTopActivityLetterboxed) {
+ final Rect bounds = top.getBounds();
+ final Rect appBounds = getAppBounds(top);
+ appCompatTaskInfo.topActivityLetterboxWidth = bounds.width();
+ appCompatTaskInfo.topActivityLetterboxHeight = bounds.height();
+ appCompatTaskInfo.topActivityLetterboxAppWidth = appBounds.width();
+ appCompatTaskInfo.topActivityLetterboxAppHeight = appBounds.height();
- // We need to consider if letterboxed or pillarboxed.
- // TODO(b/336807329) Encapsulate reachability logic
- appCompatTaskInfo.setLetterboxDoubleTapEnabled(reachabilityOverrides
- .isLetterboxDoubleTapEducationEnabled());
- if (appCompatTaskInfo.isLetterboxDoubleTapEnabled()) {
- if (appCompatTaskInfo.isTopActivityPillarboxed()) {
- if (reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox()) {
- // Pillarboxed.
- appCompatTaskInfo.topActivityLetterboxHorizontalPosition =
- reachabilityOverrides.getLetterboxPositionForHorizontalReachability();
+ // We need to consider if letterboxed or pillarboxed.
+ // TODO(b/336807329) Encapsulate reachability logic
+ appCompatTaskInfo.setLetterboxDoubleTapEnabled(reachabilityOverrides
+ .isLetterboxDoubleTapEducationEnabled());
+ if (appCompatTaskInfo.isLetterboxDoubleTapEnabled()) {
+ if (appCompatTaskInfo.isTopActivityPillarboxShaped()) {
+ if (reachabilityOverrides.allowHorizontalReachabilityForThinLetterbox()) {
+ // Pillarboxed.
+ appCompatTaskInfo.topActivityLetterboxHorizontalPosition =
+ reachabilityOverrides
+ .getLetterboxPositionForHorizontalReachability();
+ } else {
+ appCompatTaskInfo.setLetterboxDoubleTapEnabled(false);
+ }
} else {
- appCompatTaskInfo.setLetterboxDoubleTapEnabled(false);
- }
- } else {
- if (reachabilityOverrides.allowVerticalReachabilityForThinLetterbox()) {
- // Letterboxed.
- appCompatTaskInfo.topActivityLetterboxVerticalPosition =
- reachabilityOverrides.getLetterboxPositionForVerticalReachability();
- } else {
- appCompatTaskInfo.setLetterboxDoubleTapEnabled(false);
+ if (reachabilityOverrides.allowVerticalReachabilityForThinLetterbox()) {
+ // Letterboxed.
+ appCompatTaskInfo.topActivityLetterboxVerticalPosition =
+ reachabilityOverrides.getLetterboxPositionForVerticalReachability();
+ } else {
+ appCompatTaskInfo.setLetterboxDoubleTapEnabled(false);
+ }
}
}
}
+
final boolean eligibleForAspectRatioButton =
!info.isTopActivityTransparent && !appCompatTaskInfo.isTopActivityInSizeCompat()
&& aspectRatioOverrides.shouldEnableUserAspectRatioSettings();
appCompatTaskInfo.setEligibleForUserAspectRatioButton(eligibleForAspectRatioButton);
- appCompatTaskInfo.setTopActivityLetterboxed(top.areBoundsLetterboxed());
appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode =
AppCompatCameraPolicy.getCameraCompatFreeformMode(top);
appCompatTaskInfo.setHasMinAspectRatioOverride(top.mAppCompatController
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index ee07d2e..76e8a70 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1736,7 +1736,7 @@
// Show IME over the keyguard if the target allows it.
final boolean showImeOverKeyguard =
- imeTarget != null && imeTarget.isOnScreen() && win.mIsImWindow && (
+ imeTarget != null && win.mIsImWindow && imeTarget.isDisplayed() && (
imeTarget.canShowWhenLocked() || !imeTarget.canBeHiddenByKeyguard());
if (showImeOverKeyguard) {
return false;
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index e983edf..2401f90 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -35,4 +35,5 @@
# Files related to activity security
per-file ActivityStarter.java = file:/ACTIVITY_SECURITY_OWNERS
+per-file ActivityStartController.java = file:/ACTIVITY_SECURITY_OWNERS
per-file ActivityTaskManagerService.java = file:/ACTIVITY_SECURITY_OWNERS
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 72d45e4..a603466 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -3586,6 +3586,10 @@
if (wc.mWmService.mAtmService.mBackNavigationController.isMonitorTransitionTarget(wc)) {
flags |= TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
}
+ final TaskDisplayArea tda = wc.asTaskDisplayArea();
+ if (tda != null) {
+ flags |= TransitionInfo.FLAG_IS_TASK_DISPLAY_AREA;
+ }
final Task task = wc.asTask();
if (task != null) {
final ActivityRecord topActivity = task.getTopNonFinishingActivity();
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 5bde8b5..44e237a 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -614,6 +614,12 @@
final int rotation = getRelativeDisplayRotation();
if (rotation == Surface.ROTATION_0) return mFixedRotationTransformLeash;
if (mFixedRotationTransformLeash != null) return mFixedRotationTransformLeash;
+ if (ActivityTaskManagerService.isPip2ExperimentEnabled() && asActivityRecord() != null
+ && mTransitionController.getWindowingModeAtStart(
+ asActivityRecord()) == WINDOWING_MODE_PINNED) {
+ // PiP handles fixed rotation animation in Shell, so do not create the rotation leash.
+ return null;
+ }
final SurfaceControl leash = makeSurface().setContainerLayer()
.setParent(getParentSurfaceControl())
diff --git a/services/core/jni/com_android_server_vibrator_VibratorManagerService.cpp b/services/core/jni/com_android_server_vibrator_VibratorManagerService.cpp
index a47ab9d..46be79e 100644
--- a/services/core/jni/com_android_server_vibrator_VibratorManagerService.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorManagerService.cpp
@@ -16,27 +16,32 @@
#define LOG_TAG "VibratorManagerService"
+#include "com_android_server_vibrator_VibratorManagerService.h"
+
#include <nativehelper/JNIHelp.h>
+#include <utils/Log.h>
+#include <utils/misc.h>
+#include <vibratorservice/VibratorManagerHalController.h>
+
+#include <unordered_map>
+
#include "android_runtime/AndroidRuntime.h"
#include "core_jni_helpers.h"
#include "jni.h"
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include <vibratorservice/VibratorManagerHalController.h>
-
-#include "com_android_server_vibrator_VibratorManagerService.h"
-
namespace android {
static JavaVM* sJvm = nullptr;
-static jmethodID sMethodIdOnComplete;
+static jmethodID sMethodIdOnSyncedVibrationComplete;
+static jmethodID sMethodIdOnVibrationSessionComplete;
static std::mutex gManagerMutex;
static vibrator::ManagerHalController* gManager GUARDED_BY(gManagerMutex) = nullptr;
class NativeVibratorManagerService {
public:
+ using IVibrationSession = aidl::android::hardware::vibrator::IVibrationSession;
+ using VibrationSessionConfig = aidl::android::hardware::vibrator::VibrationSessionConfig;
+
NativeVibratorManagerService(JNIEnv* env, jobject callbackListener)
: mHal(std::make_unique<vibrator::ManagerHalController>()),
mCallbackListener(env->NewGlobalRef(callbackListener)) {
@@ -52,15 +57,69 @@
vibrator::ManagerHalController* hal() const { return mHal.get(); }
- std::function<void()> createCallback(jlong vibrationId) {
+ std::function<void()> createSyncedVibrationCallback(jlong vibrationId) {
return [vibrationId, this]() {
auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
- jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnComplete, vibrationId);
+ jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnSyncedVibrationComplete,
+ vibrationId);
};
}
+ std::function<void()> createVibrationSessionCallback(jlong sessionId) {
+ return [sessionId, this]() {
+ auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
+ jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnVibrationSessionComplete,
+ sessionId);
+ std::lock_guard<std::mutex> lock(mSessionMutex);
+ auto it = mSessions.find(sessionId);
+ if (it != mSessions.end()) {
+ mSessions.erase(it);
+ }
+ };
+ }
+
+ bool startSession(jlong sessionId, const std::vector<int32_t>& vibratorIds) {
+ VibrationSessionConfig config;
+ auto callback = createVibrationSessionCallback(sessionId);
+ auto result = hal()->startSession(vibratorIds, config, callback);
+ if (!result.isOk()) {
+ return false;
+ }
+
+ std::lock_guard<std::mutex> lock(mSessionMutex);
+ mSessions[sessionId] = std::move(result.value());
+ return true;
+ }
+
+ void closeSession(jlong sessionId) {
+ std::lock_guard<std::mutex> lock(mSessionMutex);
+ auto it = mSessions.find(sessionId);
+ if (it != mSessions.end()) {
+ it->second->close();
+ // Keep session, it can still be aborted.
+ }
+ }
+
+ void abortSession(jlong sessionId) {
+ std::lock_guard<std::mutex> lock(mSessionMutex);
+ auto it = mSessions.find(sessionId);
+ if (it != mSessions.end()) {
+ it->second->abort();
+ mSessions.erase(it);
+ }
+ }
+
+ void clearSessions() {
+ hal()->clearSessions();
+ std::lock_guard<std::mutex> lock(mSessionMutex);
+ mSessions.clear();
+ }
+
private:
+ std::mutex mSessionMutex;
const std::unique_ptr<vibrator::ManagerHalController> mHal;
+ std::unordered_map<jlong, std::shared_ptr<IVibrationSession>> mSessions
+ GUARDED_BY(mSessionMutex);
const jobject mCallbackListener;
};
@@ -142,7 +201,7 @@
ALOGE("nativeTriggerSynced failed because native service was not initialized");
return JNI_FALSE;
}
- auto callback = service->createCallback(vibrationId);
+ auto callback = service->createSyncedVibrationCallback(vibrationId);
return service->hal()->triggerSynced(callback).isOk() ? JNI_TRUE : JNI_FALSE;
}
@@ -156,8 +215,47 @@
service->hal()->cancelSynced();
}
+static jboolean nativeStartSession(JNIEnv* env, jclass /* clazz */, jlong servicePtr,
+ jlong sessionId, jintArray vibratorIds) {
+ NativeVibratorManagerService* service =
+ reinterpret_cast<NativeVibratorManagerService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("nativeStartSession failed because native service was not initialized");
+ return JNI_FALSE;
+ }
+ jsize size = env->GetArrayLength(vibratorIds);
+ std::vector<int32_t> ids(size);
+ env->GetIntArrayRegion(vibratorIds, 0, size, reinterpret_cast<jint*>(ids.data()));
+ return service->startSession(sessionId, ids) ? JNI_TRUE : JNI_FALSE;
+}
+
+static void nativeEndSession(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong sessionId,
+ jboolean shouldAbort) {
+ NativeVibratorManagerService* service =
+ reinterpret_cast<NativeVibratorManagerService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("nativeEndSession failed because native service was not initialized");
+ return;
+ }
+ if (shouldAbort) {
+ service->abortSession(sessionId);
+ } else {
+ service->closeSession(sessionId);
+ }
+}
+
+static void nativeClearSessions(JNIEnv* env, jclass /* clazz */, jlong servicePtr) {
+ NativeVibratorManagerService* service =
+ reinterpret_cast<NativeVibratorManagerService*>(servicePtr);
+ if (service == nullptr) {
+ ALOGE("nativeClearSessions failed because native service was not initialized");
+ return;
+ }
+ service->clearSessions();
+}
+
inline static constexpr auto sNativeInitMethodSignature =
- "(Lcom/android/server/vibrator/VibratorManagerService$OnSyncedVibrationCompleteListener;)J";
+ "(Lcom/android/server/vibrator/VibratorManagerService$VibratorManagerNativeCallbacks;)J";
static const JNINativeMethod method_table[] = {
{"nativeInit", sNativeInitMethodSignature, (void*)nativeInit},
@@ -167,15 +265,20 @@
{"nativePrepareSynced", "(J[I)Z", (void*)nativePrepareSynced},
{"nativeTriggerSynced", "(JJ)Z", (void*)nativeTriggerSynced},
{"nativeCancelSynced", "(J)V", (void*)nativeCancelSynced},
+ {"nativeStartSession", "(JJ[I)Z", (void*)nativeStartSession},
+ {"nativeEndSession", "(JJZ)V", (void*)nativeEndSession},
+ {"nativeClearSessions", "(J)V", (void*)nativeClearSessions},
};
int register_android_server_vibrator_VibratorManagerService(JavaVM* jvm, JNIEnv* env) {
sJvm = jvm;
auto listenerClassName =
- "com/android/server/vibrator/VibratorManagerService$OnSyncedVibrationCompleteListener";
+ "com/android/server/vibrator/VibratorManagerService$VibratorManagerNativeCallbacks";
jclass listenerClass = FindClassOrDie(env, listenerClassName);
- sMethodIdOnComplete = GetMethodIDOrDie(env, listenerClass, "onComplete", "(J)V");
-
+ sMethodIdOnSyncedVibrationComplete =
+ GetMethodIDOrDie(env, listenerClass, "onSyncedVibrationComplete", "(J)V");
+ sMethodIdOnVibrationSessionComplete =
+ GetMethodIDOrDie(env, listenerClass, "onVibrationSessionComplete", "(J)V");
return jniRegisterNativeMethods(env, "com/android/server/vibrator/VibratorManagerService",
method_table, NELEM(method_table));
}
diff --git a/services/core/services-jarjar-rules.txt b/services/core/services-jarjar-rules.txt
new file mode 100644
index 0000000..0d296b2
--- /dev/null
+++ b/services/core/services-jarjar-rules.txt
@@ -0,0 +1,2 @@
+# For profiling flags
+rule android.os.profiling.** android.internal.os.profiling.@1
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index aca6f72..c653038 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -255,7 +255,6 @@
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING;
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.Settings.Global.PRIVATE_DNS_SPECIFIER;
import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
@@ -462,7 +461,6 @@
import android.provider.CalendarContract;
import android.provider.ContactsContract.QuickContact;
import android.provider.ContactsInternal;
-import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Telephony;
@@ -908,10 +906,6 @@
+ "management app's authentication policy";
private static final String NOT_SYSTEM_CALLER_MSG = "Only the system can %s";
- private static final String PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG =
- "enable_permission_based_access";
- private static final boolean DEFAULT_VALUE_PERMISSION_BASED_ACCESS_FLAG = false;
-
private static final int RETRY_COPY_ACCOUNT_ATTEMPTS = 3;
/**
@@ -3486,7 +3480,7 @@
@GuardedBy("getLockObject()")
private boolean maybeMigrateSuspendedPackagesLocked(String backupId) {
Slog.i(LOG_TAG, "Migrating suspended packages to policy engine");
- if (!Flags.unmanagedModeMigration()) {
+ if (!Flags.suspendPackagesCoexistence()) {
return false;
}
if (mOwners.isSuspendedPackagesMigrated()) {
@@ -3557,6 +3551,46 @@
return true;
}
+
+
+ @GuardedBy("getLockObject()")
+ private boolean maybeMigrateMemoryTaggingLocked(String backupId) {
+ if (!Flags.setMtePolicyCoexistence()) {
+ Slog.i(LOG_TAG, "Memory Tagging not migrated because coexistence "
+ + "support is disabled.");
+ return false;
+ }
+ if (mOwners.isMemoryTaggingMigrated()) {
+ // TODO: Remove log after Flags.setMtePolicyCoexistence full rollout.
+ Slog.v(LOG_TAG, "Memory Tagging was previously migrated to policy engine.");
+ return false;
+ }
+
+ Slog.i(LOG_TAG, "Migrating Memory Tagging to policy engine");
+
+ // Create backup if none exists
+ mDevicePolicyEngine.createBackup(backupId);
+ try {
+ iterateThroughDpcAdminsLocked((admin, enforcingAdmin) -> {
+ if (admin.mtePolicy != 0) {
+ Slog.i(LOG_TAG, "Setting Memory Tagging policy");
+ mDevicePolicyEngine.setGlobalPolicy(
+ PolicyDefinition.MEMORY_TAGGING,
+ enforcingAdmin,
+ new IntegerPolicyValue(admin.mtePolicy),
+ true /* No need to re-set system properties */);
+ }
+ });
+ } catch (Exception e) {
+ Slog.wtf(LOG_TAG,
+ "Failed to migrate Memory Tagging to policy engine", e);
+ }
+
+ Slog.i(LOG_TAG, "Marking Memory Tagging migration complete");
+ mOwners.markMemoryTaggingMigrated();
+ return true;
+ }
+
/** Register callbacks for statsd pulled atoms. */
private void registerStatsCallbacks() {
final StatsManager statsManager = mContext.getSystemService(StatsManager.class);
@@ -4646,22 +4680,13 @@
@GuardedBy("getLockObject()")
private List<ActiveAdmin> getActiveAdminsForLockscreenPoliciesLocked(int userHandle) {
if (isSeparateProfileChallengeEnabled(userHandle)) {
-
- if (isPermissionCheckFlagEnabled()) {
- return getActiveAdminsForAffectedUserInclPermissionBasedAdminLocked(userHandle);
- }
// If this user has a separate challenge, only return its restrictions.
return getUserDataUnchecked(userHandle).mAdminList;
}
// If isSeparateProfileChallengeEnabled is false and userHandle points to a managed profile
// we need to query the parent user who owns the credential.
- if (isPermissionCheckFlagEnabled()) {
- return getActiveAdminsForUserAndItsManagedProfilesInclPermissionBasedAdminLocked(getProfileParentId(userHandle),
- (user) -> !mLockPatternUtils.isSeparateProfileChallengeEnabled(user.id));
- } else {
- return getActiveAdminsForUserAndItsManagedProfilesLocked(getProfileParentId(userHandle),
- (user) -> !mLockPatternUtils.isSeparateProfileChallengeEnabled(user.id));
- }
+ return getActiveAdminsForUserAndItsManagedProfilesLocked(getProfileParentId(userHandle),
+ (user) -> !mLockPatternUtils.isSeparateProfileChallengeEnabled(user.id));
}
@@ -4684,33 +4709,6 @@
(user) -> mLockPatternUtils.isProfileWithUnifiedChallenge(user.id));
}
- /**
- * Get the list of active admins for an affected user:
- * <ul>
- * <li>The active admins associated with the userHandle itself</li>
- * <li>The parent active admins for each managed profile associated with the userHandle</li>
- * <li>The permission based admin associated with the userHandle itself</li>
- * </ul>
- *
- * @param userHandle the affected user for whom to get the active admins
- * @return the list of active admins for the affected user
- */
- @GuardedBy("getLockObject()")
- private List<ActiveAdmin> getActiveAdminsForAffectedUserInclPermissionBasedAdminLocked(
- int userHandle) {
- List<ActiveAdmin> list;
-
- if (isManagedProfile(userHandle)) {
- list = getUserDataUnchecked(userHandle).mAdminList;
- }
- list = getActiveAdminsForUserAndItsManagedProfilesInclPermissionBasedAdminLocked(userHandle,
- /* shouldIncludeProfileAdmins */ (user) -> false);
-
- if (getUserData(userHandle).mPermissionBasedAdmin != null) {
- list.add(getUserData(userHandle).mPermissionBasedAdmin);
- }
- return list;
- }
/**
* Returns the list of admins on the given user, as well as parent admins for each managed
@@ -4763,44 +4761,6 @@
return mDevicePolicyEngine.getResolvedPolicyAcrossUsers(policyDefinition, users);
}
- /**
- * Returns the list of admins on the given user, as well as parent admins for each managed
- * profile associated with the given user. Optionally also include the admin of each managed
- * profile.
- * <p> Should not be called on a profile user.
- */
- @GuardedBy("getLockObject()")
- private List<ActiveAdmin> getActiveAdminsForUserAndItsManagedProfilesInclPermissionBasedAdminLocked(int userHandle,
- Predicate<UserInfo> shouldIncludeProfileAdmins) {
- ArrayList<ActiveAdmin> admins = new ArrayList<>();
- mInjector.binderWithCleanCallingIdentity(() -> {
- for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
- DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
- if (userInfo.id == userHandle) {
- admins.addAll(policy.mAdminList);
- if (policy.mPermissionBasedAdmin != null) {
- admins.add(policy.mPermissionBasedAdmin);
- }
- } else if (userInfo.isManagedProfile()) {
- for (int i = 0; i < policy.mAdminList.size(); i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (admin.hasParentActiveAdmin()) {
- admins.add(admin.getParentActiveAdmin());
- }
- if (shouldIncludeProfileAdmins.test(userInfo)) {
- admins.add(admin);
- }
- }
- if (policy.mPermissionBasedAdmin != null
- && shouldIncludeProfileAdmins.test(userInfo)) {
- admins.add(policy.mPermissionBasedAdmin);
- }
- }
- }
- });
- return admins;
- }
-
private boolean isSeparateProfileChallengeEnabled(int userHandle) {
return mInjector.binderWithCleanCallingIdentity(() ->
mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle));
@@ -4893,25 +4853,15 @@
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
return;
}
- if (!isPermissionCheckFlagEnabled()) {
- Objects.requireNonNull(who, "ComponentName is null");
- }
+ Objects.requireNonNull(who, "ComponentName is null");
Preconditions.checkArgumentNonnegative(timeout, "Timeout must be >= 0 ms");
int userHandle = mInjector.userHandleGetCallingUserId();
int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
synchronized (getLockObject()) {
ActiveAdmin ap;
- if (isPermissionCheckFlagEnabled()) {
- CallerIdentity caller = getCallerIdentity(who, callerPackageName);
- ap = enforcePermissionAndGetEnforcingAdmin(
- who, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
- caller.getPackageName(), affectedUserId)
- .getActiveAdmin();
- } else {
- ap = getActiveAdminForCallerLocked(
- who, DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD, parent);
- }
+ ap = getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD, parent);
// Calling this API automatically bumps the expiration date
final long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
ap.passwordExpirationDate = expiration;
@@ -4972,28 +4922,14 @@
@Override
public boolean addCrossProfileWidgetProvider(ComponentName admin, String callerPackageName,
String packageName) {
- CallerIdentity caller;
+ CallerIdentity caller = getCallerIdentity(admin);
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(admin, callerPackageName);
- } else {
- caller = getCallerIdentity(admin);
- }
+ Objects.requireNonNull(admin, "ComponentName is null");
+ Preconditions.checkCallAuthorization(isProfileOwner(caller));
+
ActiveAdmin activeAdmin;
-
- if (isPermissionCheckFlagEnabled()) {
- EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
- admin,
- MANAGE_DEVICE_POLICY_PROFILE_INTERACTION,
- caller.getPackageName(),
- caller.getUserId());
- activeAdmin = enforcingAdmin.getActiveAdmin();
- } else {
- Objects.requireNonNull(admin, "ComponentName is null");
- Preconditions.checkCallAuthorization(isProfileOwner(caller));
- synchronized (getLockObject()) {
- activeAdmin = getProfileOwnerLocked(caller.getUserId());
- }
+ synchronized (getLockObject()) {
+ activeAdmin = getProfileOwnerLocked(caller.getUserId());
}
List<String> changedProviders = null;
@@ -5026,28 +4962,14 @@
@Override
public boolean removeCrossProfileWidgetProvider(ComponentName admin, String callerPackageName,
String packageName) {
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(admin, callerPackageName);
- } else {
- caller = getCallerIdentity(admin);
- }
+ CallerIdentity caller = getCallerIdentity(admin);
+
+ Objects.requireNonNull(admin, "ComponentName is null");
+ Preconditions.checkCallAuthorization(isProfileOwner(caller));
ActiveAdmin activeAdmin;
-
- if (isPermissionCheckFlagEnabled()) {
- EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
- admin,
- MANAGE_DEVICE_POLICY_PROFILE_INTERACTION,
- caller.getPackageName(),
- caller.getUserId());
- activeAdmin = enforcingAdmin.getActiveAdmin();
- } else {
- Objects.requireNonNull(admin, "ComponentName is null");
- Preconditions.checkCallAuthorization(isProfileOwner(caller));
- synchronized (getLockObject()) {
- activeAdmin = getProfileOwnerLocked(caller.getUserId());
- }
+ synchronized (getLockObject()) {
+ activeAdmin = getProfileOwnerLocked(caller.getUserId());
}
List<String> changedProviders = null;
@@ -5080,27 +5002,14 @@
@Override
public List<String> getCrossProfileWidgetProviders(ComponentName admin,
String callerPackageName) {
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(admin, callerPackageName);
- } else {
- caller = getCallerIdentity(admin);
- }
- ActiveAdmin activeAdmin;
+ CallerIdentity caller = getCallerIdentity(admin);
- if (isPermissionCheckFlagEnabled()) {
- EnforcingAdmin enforcingAdmin = enforceCanQueryAndGetEnforcingAdmin(
- admin,
- MANAGE_DEVICE_POLICY_PROFILE_INTERACTION,
- caller.getPackageName(),
- caller.getUserId());
- activeAdmin = enforcingAdmin.getActiveAdmin();
- } else {
- Objects.requireNonNull(admin, "ComponentName is null");
- Preconditions.checkCallAuthorization(isProfileOwner(caller));
- synchronized (getLockObject()) {
- activeAdmin = getProfileOwnerLocked(caller.getUserId());
- }
+ Objects.requireNonNull(admin, "ComponentName is null");
+ Preconditions.checkCallAuthorization(isProfileOwner(caller));
+
+ ActiveAdmin activeAdmin;
+ synchronized (getLockObject()) {
+ activeAdmin = getProfileOwnerLocked(caller.getUserId());
}
synchronized (getLockObject()) {
@@ -5449,24 +5358,17 @@
enforceUserUnlocked(userHandle, parent);
synchronized (getLockObject()) {
- if (isPermissionCheckFlagEnabled()) {
- int affectedUser = parent ? getProfileParentId(userHandle) : userHandle;
- enforcePermission(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
- callerPackageName, affectedUser);
- } else {
- // This API can only be called by an active device admin,
- // so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(
- null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
- }
+ // This API can only be called by an active device admin,
+ // so try to retrieve it to check that the caller is one.
+ getActiveAdminForCallerLocked(
+ null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
int credentialOwner = getCredentialOwner(userHandle, parent);
DevicePolicyData policy = getUserDataUnchecked(credentialOwner);
PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
final int userToCheck = getProfileParentUserIfRequested(userHandle, parent);
- boolean activePasswordSufficientForUserLocked = isActivePasswordSufficientForUserLocked(
+ return isActivePasswordSufficientForUserLocked(
policy.mPasswordValidAtLastCheckpoint, metrics, userToCheck);
- return activePasswordSufficientForUserLocked;
}
}
@@ -5622,21 +5524,11 @@
isDefaultDeviceOwner(caller) || isProfileOwner(caller) || isSystemUid(caller),
"Only profile owner, device owner and system may call this method on parent.");
} else {
- if (isPermissionCheckFlagEnabled()) {
- Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(REQUEST_PASSWORD_COMPLEXITY)
- || hasCallingOrSelfPermission(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS)
- || isDefaultDeviceOwner(caller) || isProfileOwner(caller),
- "Must have " + REQUEST_PASSWORD_COMPLEXITY + " or " +
- MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS
- + " permissions, or be a profile owner or device owner.");
- } else {
- Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(REQUEST_PASSWORD_COMPLEXITY)
- || isDefaultDeviceOwner(caller) || isProfileOwner(caller),
- "Must have " + REQUEST_PASSWORD_COMPLEXITY
- + " permission, or be a profile owner or device owner.");
- }
+ Preconditions.checkCallAuthorization(
+ hasCallingOrSelfPermission(REQUEST_PASSWORD_COMPLEXITY)
+ || isDefaultDeviceOwner(caller) || isProfileOwner(caller),
+ "Must have " + REQUEST_PASSWORD_COMPLEXITY
+ + " permission, or be a profile owner or device owner.");
}
synchronized (getLockObject()) {
@@ -5728,26 +5620,15 @@
private void setRequiredPasswordComplexityPreCoexistence(
String callerPackageName, int passwordComplexity, boolean calledOnParent) {
CallerIdentity caller = getCallerIdentity(callerPackageName);
- if (!isPermissionCheckFlagEnabled()) {
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwner(caller));
- Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
- }
+
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwner(caller));
+ Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
synchronized (getLockObject()) {
ActiveAdmin admin;
- if (isPermissionCheckFlagEnabled()) {
- // TODO: Make sure this returns the parent of the fake admin
- // TODO: Deal with null componentname
- int affectedUser = calledOnParent
- ? getProfileParentId(caller.getUserId()) : caller.getUserId();
- admin = enforcePermissionAndGetEnforcingAdmin(
- null, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
- caller.getPackageName(), affectedUser).getActiveAdmin();
- } else {
- admin = getParentOfAdminIfRequired(
- getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), calledOnParent);
- }
+ admin = getParentOfAdminIfRequired(
+ getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), calledOnParent);
if (admin.mPasswordComplexity != passwordComplexity) {
// We require the caller to explicitly clear any password quality requirements set
@@ -5907,14 +5788,8 @@
if (!isSystemUid(caller)) {
// This API can be called by an active device admin or by keyguard code.
if (!hasCallingPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE)) {
- if (isPermissionCheckFlagEnabled()) {
- int affectedUser = parent ? getProfileParentId(userHandle) : userHandle;
- enforcePermission(MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
- callerPackageName, affectedUser);
- } else {
- getActiveAdminForCallerLocked(
- null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
- }
+ getActiveAdminForCallerLocked(
+ null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
}
}
@@ -5931,31 +5806,18 @@
return;
}
- if (!isPermissionCheckFlagEnabled()) {
- Objects.requireNonNull(who, "ComponentName is null");
- }
-
+ Objects.requireNonNull(who, "ComponentName is null");
int userId = mInjector.userHandleGetCallingUserId();
int affectedUserId = parent ? getProfileParentId(userId) : userId;
synchronized (getLockObject()) {
- ActiveAdmin ap;
- if (isPermissionCheckFlagEnabled()) {
- CallerIdentity caller = getCallerIdentity(who, callerPackageName);
- ap = enforcePermissionAndGetEnforcingAdmin(
- who,
- /*permission=*/ MANAGE_DEVICE_POLICY_WIPE_DATA,
- /* adminPolicy=*/ DeviceAdminInfo.USES_POLICY_WIPE_DATA,
- caller.getPackageName(), affectedUserId).getActiveAdmin();
- } else {
- // This API can only be called by an active device admin,
- // so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(
- who, DeviceAdminInfo.USES_POLICY_WIPE_DATA, parent);
- ap = getActiveAdminForCallerLocked(
- who, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
- }
+ // This API can only be called by an active device admin,
+ // so try to retrieve it to check that the caller is one.
+ getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_WIPE_DATA, parent);
+ ActiveAdmin ap = getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
if (ap.maximumFailedPasswordsForWipe != num) {
ap.maximumFailedPasswordsForWipe = num;
@@ -6210,25 +6072,14 @@
if (!mHasFeature) {
return;
}
- if (!isPermissionCheckFlagEnabled()) {
- Objects.requireNonNull(who, "ComponentName is null");
- }
+
+ Objects.requireNonNull(who, "ComponentName is null");
+
int userHandle = mInjector.userHandleGetCallingUserId();
int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
synchronized (getLockObject()) {
- ActiveAdmin ap;
- if (isPermissionCheckFlagEnabled()) {
- CallerIdentity caller = getCallerIdentity(who, callerPackageName);
- ap = enforcePermissionAndGetEnforcingAdmin(
- who,
- /*permission=*/ MANAGE_DEVICE_POLICY_LOCK,
- /*AdminPolicy=*/DeviceAdminInfo.USES_POLICY_FORCE_LOCK,
- caller.getPackageName(),
- affectedUserId).getActiveAdmin();
- } else {
- ap = getActiveAdminForCallerLocked(
- who, DeviceAdminInfo.USES_POLICY_FORCE_LOCK, parent);
- }
+ ActiveAdmin ap = getActiveAdminForCallerLocked(
+ who, DeviceAdminInfo.USES_POLICY_FORCE_LOCK, parent);
if (ap.maximumTimeToUnlock != timeMs) {
ap.maximumTimeToUnlock = timeMs;
@@ -6334,16 +6185,13 @@
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
return;
}
+
Preconditions.checkArgument(timeoutMs >= 0, "Timeout must not be a negative number.");
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- } else {
- caller = getCallerIdentity(who);
- Objects.requireNonNull(who, "ComponentName is null");
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwner(caller));
- }
+ CallerIdentity caller = getCallerIdentity(who);
+ Objects.requireNonNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwner(caller));
+
// timeoutMs with value 0 means that the admin doesn't participate
// timeoutMs is clamped to the interval in case the internal constants change in the future
final long minimumStrongAuthTimeout = getMinimumStrongAuthTimeoutMs();
@@ -6357,17 +6205,8 @@
final int userHandle = caller.getUserId();
boolean changed = false;
synchronized (getLockObject()) {
- ActiveAdmin ap;
- if (isPermissionCheckFlagEnabled()) {
- int affectedUser = parent
- ? getProfileParentId(caller.getUserId()) : caller.getUserId();
- ap = enforcePermissionAndGetEnforcingAdmin(
- who, MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS,
- caller.getPackageName(), affectedUser).getActiveAdmin();
- } else {
- ap = getParentOfAdminIfRequired(
- getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), parent);
- }
+ ActiveAdmin ap = getParentOfAdminIfRequired(
+ getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), parent);
if (ap.strongAuthUnlockTimeout != timeoutMs) {
ap.strongAuthUnlockTimeout = timeoutMs;
saveSettingsLocked(userHandle);
@@ -6664,16 +6503,9 @@
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
final boolean isCallerDelegate = isCallerDelegate(caller, DELEGATION_CERT_INSTALL);
final boolean isCredentialManagementApp = isCredentialManagementApp(caller);
- if (isPermissionCheckFlagEnabled()) {
- Preconditions.checkCallAuthorization(
- hasPermission(MANAGE_DEVICE_POLICY_CERTIFICATES,
- caller.getPackageName(), caller.getUserId())
- || isCredentialManagementApp);
- } else {
- Preconditions.checkCallAuthorization((caller.hasAdminComponent()
- && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
- || (caller.hasPackage() && (isCallerDelegate || isCredentialManagementApp)));
- }
+ Preconditions.checkCallAuthorization((caller.hasAdminComponent()
+ && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
+ || (caller.hasPackage() && (isCallerDelegate || isCredentialManagementApp)));
if (isCredentialManagementApp) {
Preconditions.checkCallAuthorization(!isUserSelectable, "The credential "
+ "management app is not allowed to install a user selectable key pair");
@@ -6733,16 +6565,9 @@
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
final boolean isCallerDelegate = isCallerDelegate(caller, DELEGATION_CERT_INSTALL);
final boolean isCredentialManagementApp = isCredentialManagementApp(caller);
- if (isPermissionCheckFlagEnabled()) {
- Preconditions.checkCallAuthorization(
- hasPermission(MANAGE_DEVICE_POLICY_CERTIFICATES,
- caller.getPackageName(), caller.getUserId())
- || isCredentialManagementApp);
- } else {
- Preconditions.checkCallAuthorization((caller.hasAdminComponent()
- && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
- || (caller.hasPackage() && (isCallerDelegate || isCredentialManagementApp)));
- }
+ Preconditions.checkCallAuthorization((caller.hasAdminComponent()
+ && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
+ || (caller.hasPackage() && (isCallerDelegate || isCredentialManagementApp)));
if (isCredentialManagementApp) {
Preconditions.checkCallAuthorization(
isAliasInCredentialManagementAppPolicy(caller, alias),
@@ -6802,13 +6627,8 @@
}
private boolean canInstallCertificates(CallerIdentity caller) {
- if (isPermissionCheckFlagEnabled()) {
- return hasPermission(MANAGE_DEVICE_POLICY_CERTIFICATES,
- caller.getPackageName(), caller.getUserId());
- } else {
- return isProfileOwner(caller) || isDefaultDeviceOwner(caller)
- || isCallerDelegate(caller, DELEGATION_CERT_INSTALL);
- }
+ return isProfileOwner(caller) || isDefaultDeviceOwner(caller)
+ || isCallerDelegate(caller, DELEGATION_CERT_INSTALL);
}
private boolean canChooseCertificates(CallerIdentity caller) {
@@ -7001,16 +6821,9 @@
caller.getPackageName(), caller.getUid()));
enforceIndividualAttestationSupportedIfRequested(attestationUtilsFlags);
} else {
- if (isPermissionCheckFlagEnabled()) {
- Preconditions.checkCallAuthorization(
- hasPermission(MANAGE_DEVICE_POLICY_CERTIFICATES,
- caller.getPackageName(), caller.getUserId())
- || isCredentialManagementApp);
- } else {
- Preconditions.checkCallAuthorization((caller.hasAdminComponent() && (isProfileOwner(
- caller) || isDefaultDeviceOwner(caller))) || (caller.hasPackage() && (
- isCallerDelegate || isCredentialManagementApp)));
- }
+ Preconditions.checkCallAuthorization((caller.hasAdminComponent() && (isProfileOwner(
+ caller) || isDefaultDeviceOwner(caller))) || (caller.hasPackage() && (
+ isCallerDelegate || isCredentialManagementApp)));
if (isCredentialManagementApp) {
Preconditions.checkCallAuthorization(
isAliasInCredentialManagementAppPolicy(caller, alias),
@@ -7143,16 +6956,9 @@
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
final boolean isCallerDelegate = isCallerDelegate(caller, DELEGATION_CERT_INSTALL);
final boolean isCredentialManagementApp = isCredentialManagementApp(caller);
- if (isPermissionCheckFlagEnabled()) {
- Preconditions.checkCallAuthorization(
- hasPermission(MANAGE_DEVICE_POLICY_CERTIFICATES,
- caller.getPackageName(), caller.getUserId())
- || isCredentialManagementApp);
- } else {
- Preconditions.checkCallAuthorization((caller.hasAdminComponent()
- && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
- || (caller.hasPackage() && (isCallerDelegate || isCredentialManagementApp)));
- }
+ Preconditions.checkCallAuthorization((caller.hasAdminComponent()
+ && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
+ || (caller.hasPackage() && (isCallerDelegate || isCredentialManagementApp)));
if (isCredentialManagementApp) {
Preconditions.checkCallAuthorization(
isAliasInCredentialManagementAppPolicy(caller, alias),
@@ -8285,29 +8091,21 @@
if (!mHasFeature) {
return;
}
- if (!isPermissionCheckFlagEnabled()) {
- Preconditions.checkNotNull(who, "ComponentName is null");
- }
+
+ Preconditions.checkNotNull(who, "ComponentName is null");
+
CallerIdentity caller = getCallerIdentity(who, callerPackageName);
- if (!isPermissionCheckFlagEnabled()) {
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller));
- }
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
+
checkCanExecuteOrThrowUnsafe(DevicePolicyManager
.OPERATION_SET_FACTORY_RESET_PROTECTION_POLICY);
final int frpManagementAgentUid = getFrpManagementAgentUidOrThrow();
synchronized (getLockObject()) {
ActiveAdmin admin;
- if (isPermissionCheckFlagEnabled()) {
- admin = enforcePermissionAndGetEnforcingAdmin(
- who, MANAGE_DEVICE_POLICY_FACTORY_RESET, caller.getPackageName(),
- UserHandle.USER_ALL)
- .getActiveAdmin();
- } else {
- admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
- }
+ admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
admin.mFactoryResetProtectionPolicy = policy;
saveSettingsLocked(caller.getUserId());
}
@@ -8347,7 +8145,7 @@
|| hasCallingPermission(permission.MASTER_CLEAR)
|| hasCallingPermission(MANAGE_DEVICE_POLICY_FACTORY_RESET),
"Must be called by the FRP management agent on device");
- admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceOrSystemPermissionBasedAdminLocked();
+ admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked();
} else {
Preconditions.checkCallAuthorization(
isDefaultDeviceOwner(caller)
@@ -10247,15 +10045,6 @@
return admin;
}
- ActiveAdmin getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceOrSystemPermissionBasedAdminLocked() {
- ensureLocked();
- ActiveAdmin doOrPo = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked();
- if (isPermissionCheckFlagEnabled() && doOrPo == null) {
- return getUserData(0).mPermissionBasedAdmin;
- }
- return doOrPo;
- }
-
@Override
public void clearDeviceOwner(String packageName) {
Objects.requireNonNull(packageName, "packageName is null");
@@ -10998,8 +10787,6 @@
* (2.1.1) The caller is the profile owner.
* (2.1.2) The caller is from another app in the same user as the profile owner, AND
* the caller is the delegated cert installer.
- * (3) The caller holds the
- * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CERTIFICATES} permission.
*
* For the device owner case, simply check that the caller is the device owner or the
* delegated certificate installer.
@@ -11013,24 +10800,18 @@
@VisibleForTesting
boolean hasDeviceIdAccessUnchecked(String packageName, int uid) {
final int userId = UserHandle.getUserId(uid);
- // TODO(b/280048070): Introduce a permission to handle device ID access
- if (isPermissionCheckFlagEnabled()
- && !(isUidProfileOwnerLocked(uid) || isUidDeviceOwnerLocked(uid))) {
- return hasPermission(MANAGE_DEVICE_POLICY_CERTIFICATES, packageName, userId);
- } else {
- ComponentName deviceOwner = getDeviceOwnerComponent(true);
- if (deviceOwner != null && (deviceOwner.getPackageName().equals(packageName)
- || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
- return true;
- }
- ComponentName profileOwner = getProfileOwnerAsUser(userId);
- final boolean isCallerProfileOwnerOrDelegate = profileOwner != null
- && (profileOwner.getPackageName().equals(packageName)
- || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL));
- if (isCallerProfileOwnerOrDelegate && (isProfileOwnerOfOrganizationOwnedDevice(userId)
- || isUserAffiliatedWithDevice(userId))) {
- return true;
- }
+ ComponentName deviceOwner = getDeviceOwnerComponent(true);
+ if (deviceOwner != null && (deviceOwner.getPackageName().equals(packageName)
+ || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
+ return true;
+ }
+ ComponentName profileOwner = getProfileOwnerAsUser(userId);
+ final boolean isCallerProfileOwnerOrDelegate = profileOwner != null
+ && (profileOwner.getPackageName().equals(packageName)
+ || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL));
+ if (isCallerProfileOwnerOrDelegate && (isProfileOwnerOfOrganizationOwnedDevice(userId)
+ || isUserAffiliatedWithDevice(userId))) {
+ return true;
}
return false;
}
@@ -11731,25 +11512,12 @@
@Override
public void setDefaultSmsApplication(ComponentName admin, String callerPackageName,
String packageName, boolean parent) {
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(admin, callerPackageName);
- } else {
- caller = getCallerIdentity(admin);
- }
+ CallerIdentity caller = getCallerIdentity(admin);
- final int userId;
- if (isPermissionCheckFlagEnabled()) {
- enforcePermission(
- MANAGE_DEVICE_POLICY_DEFAULT_SMS,
- caller.getPackageName(),
- getAffectedUser(parent));
- } else {
- Objects.requireNonNull(admin, "ComponentName is null");
- Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller));
- }
+ Objects.requireNonNull(admin, "ComponentName is null");
+ Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
if (!parent && isManagedProfile(caller.getUserId())
&& getManagedSubscriptionsPolicy().getPolicyType()
@@ -11759,6 +11527,7 @@
+ "ManagedSubscriptions policy is set");
}
+ final int userId;
if (parent) {
userId = getProfileParentId(mInjector.userHandleGetCallingUserId());
mInjector.binderWithCleanCallingIdentity(() -> enforcePackageIsSystemPackage(
@@ -11957,10 +11726,7 @@
return;
}
- if (!isPermissionCheckFlagEnabled()) {
- Objects.requireNonNull(admin, "admin is null");
- }
-
+ Objects.requireNonNull(admin, "admin is null");
Objects.requireNonNull(agent, "agent is null");
PolicySizeVerifier.enforceMaxPackageNameLength(agent.getPackageName());
@@ -11972,19 +11738,8 @@
int userHandle = mInjector.userHandleGetCallingUserId();
synchronized (getLockObject()) {
- ActiveAdmin ap;
- if (isPermissionCheckFlagEnabled()) {
- CallerIdentity caller = getCallerIdentity(admin, callerPackageName);
- int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
- ap = enforcePermissionAndGetEnforcingAdmin(
- admin,
- /*permission=*/MANAGE_DEVICE_POLICY_KEYGUARD,
- /*adminPolicy=*/DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES,
- caller.getPackageName(), affectedUserId).getActiveAdmin();
- } else {
- ap = getActiveAdminForCallerLocked(admin,
- DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES, parent);
- }
+ ActiveAdmin ap = getActiveAdminForCallerLocked(admin,
+ DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES, parent);
checkCanExecuteOrThrowUnsafe(
DevicePolicyManager.OPERATION_SET_TRUST_AGENT_CONFIGURATION);
@@ -12080,27 +11835,16 @@
@Override
public void addCrossProfileIntentFilter(ComponentName who, String callerPackageName,
IntentFilter filter, int flags) {
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- } else {
- caller = getCallerIdentity(who);
- }
- int callingUserId = caller.getUserId();
+ CallerIdentity caller = getCallerIdentity(who);
- if (isPermissionCheckFlagEnabled()) {
- enforcePermission(
- MANAGE_DEVICE_POLICY_PROFILE_INTERACTION,
- caller.getPackageName(),
- callingUserId);
- } else {
- Objects.requireNonNull(who, "ComponentName is null");
- Preconditions.checkCallAuthorization(
- isProfileOwner(caller) || isDefaultDeviceOwner(caller));
- }
+ Objects.requireNonNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(
+ isProfileOwner(caller) || isDefaultDeviceOwner(caller));
+
synchronized (getLockObject()) {
long id = mInjector.binderClearCallingIdentity();
try {
+ int callingUserId = caller.getUserId();
UserInfo parent = mUserManager.getProfileParent(callingUserId);
if (parent == null) {
Slogf.e(LOG_TAG, "Cannot call addCrossProfileIntentFilter if there is no "
@@ -12144,28 +11888,16 @@
@Override
public void clearCrossProfileIntentFilters(ComponentName who, String callerPackageName) {
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- } else {
- caller = getCallerIdentity(who);
- }
- int callingUserId = caller.getUserId();
+ CallerIdentity caller = getCallerIdentity(who);
- if (isPermissionCheckFlagEnabled()) {
- enforcePermission(
- MANAGE_DEVICE_POLICY_PROFILE_INTERACTION,
- caller.getPackageName(),
- callingUserId);
- } else {
- Objects.requireNonNull(who, "ComponentName is null");
- Preconditions.checkCallAuthorization(
- isProfileOwner(caller) || isDefaultDeviceOwner(caller));
- }
+ Objects.requireNonNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(
+ isProfileOwner(caller) || isDefaultDeviceOwner(caller));
synchronized (getLockObject()) {
long id = mInjector.binderClearCallingIdentity();
try {
+ int callingUserId = caller.getUserId();
UserInfo parent = mUserManager.getProfileParent(callingUserId);
if (parent == null) {
Slogf.e(LOG_TAG, "Cannot call clearCrossProfileIntentFilter if there is no "
@@ -13360,7 +13092,7 @@
@Override
public String[] setPackagesSuspended(ComponentName who, String callerPackage,
String[] packageNames, boolean suspended) {
- if (!Flags.unmanagedModeMigration()) {
+ if (!Flags.suspendPackagesCoexistence()) {
return setPackagesSuspendedPreCoexistence(who, callerPackage, packageNames, suspended);
}
@@ -13450,7 +13182,7 @@
public boolean isPackageSuspended(ComponentName who, String callerPackage, String packageName) {
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
- if (Flags.unmanagedModeMigration()) {
+ if (Flags.suspendPackagesCoexistence()) {
enforcePermission(
MANAGE_DEVICE_POLICY_PACKAGE_STATE,
caller.getPackageName(),
@@ -15166,19 +14898,12 @@
if (!mHasFeature) {
return;
}
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- enforcePermission(MANAGE_DEVICE_POLICY_WIFI, caller.getPackageName(),
- UserHandle.USER_ALL);
- } else {
- caller = getCallerIdentity(who);
- Preconditions.checkNotNull(who, "ComponentName is null");
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller));
- }
+ CallerIdentity caller = getCallerIdentity(who);
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
mInjector.binderWithCleanCallingIdentity(() ->
mInjector.settingsGlobalPutInt(Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN,
@@ -15197,16 +14922,10 @@
return false;
}
CallerIdentity caller = getCallerIdentity(who);
- if (isPermissionCheckFlagEnabled()) {
- enforcePermission(MANAGE_DEVICE_POLICY_WIFI, who.getPackageName(),
- UserHandle.USER_ALL);
- } else {
- Preconditions.checkNotNull(who, "ComponentName is null");
-
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller));
- }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
return mInjector.binderWithCleanCallingIdentity(() ->
mInjector.settingsGlobalGetInt(Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0) > 0);
@@ -15294,18 +15013,11 @@
@Override
public boolean setTime(@Nullable ComponentName who, String callerPackageName, long millis) {
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- // This is a global action.
- enforcePermission(SET_TIME, caller.getPackageName(), UserHandle.USER_ALL);
- } else {
- caller = getCallerIdentity(who);
- Objects.requireNonNull(who, "ComponentName is null");
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller));
- }
+ CallerIdentity caller = getCallerIdentity(who);
+ Objects.requireNonNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
// Don't allow set time when auto time is on.
if (mInjector.settingsGlobalGetInt(Global.AUTO_TIME, 0) == 1) {
@@ -15322,18 +15034,11 @@
@Override
public boolean setTimeZone(@Nullable ComponentName who, String callerPackageName,
String timeZone) {
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- // This is a global action.
- enforcePermission(SET_TIME_ZONE, caller.getPackageName(), UserHandle.USER_ALL);
- } else {
- caller = getCallerIdentity(who);
- Objects.requireNonNull(who, "ComponentName is null");
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller));
- }
+ CallerIdentity caller = getCallerIdentity(who);
+ Objects.requireNonNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
// Don't allow set timezone when auto timezone is on.
if (mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) == 1) {
@@ -16537,22 +16242,15 @@
policy.validateAgainstPreviousFreezePeriod(record.first, record.second,
LocalDate.now());
}
- CallerIdentity caller;
+
+ CallerIdentity caller = getCallerIdentity(who);
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isDefaultDeviceOwner(caller));
+
+ checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_SYSTEM_UPDATE_POLICY);
synchronized (getLockObject()) {
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- enforcePermission(MANAGE_DEVICE_POLICY_SYSTEM_UPDATES, caller.getPackageName(),
- UserHandle.USER_ALL);
- } else {
- caller = getCallerIdentity(who);
- Preconditions.checkCallAuthorization(
- isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isDefaultDeviceOwner(caller));
- }
-
- checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_SYSTEM_UPDATE_POLICY);
-
if (policy == null) {
mOwners.clearSystemUpdatePolicy();
} else {
@@ -16699,7 +16397,6 @@
if (!mUserManager.getUserInfo(UserHandle.getCallingUserId()).isMain()) {
Slogf.w(LOG_TAG, "Only the system update service in the main user can broadcast "
+ "update information.");
- return;
}
});
@@ -16723,7 +16420,7 @@
}
}
// Get running users.
- final int runningUserIds[];
+ final int[] runningUserIds;
try {
runningUserIds = mInjector.getIActivityManager().getRunningUserIds();
} catch (RemoteException e) {
@@ -16966,10 +16663,7 @@
return false;
}
}
- if (!isRuntimePermission(permission)) {
- return false;
- }
- return true;
+ return isRuntimePermission(permission);
}
private void enforcePermissionGrantStateOnFinancedDevice(
@@ -17384,18 +17078,12 @@
@Override
public String getWifiMacAddress(ComponentName admin, String callerPackageName) {
-// if (!isPermissionCheckFlagEnabled()) {
- Objects.requireNonNull(admin, "ComponentName is null");
-// }
+ Objects.requireNonNull(admin, "ComponentName is null");
final CallerIdentity caller = getCallerIdentity(admin, callerPackageName);
-// if (isPermissionCheckFlagEnabled()) {
-// enforcePermission(MANAGE_DEVICE_POLICY_WIFI, UserHandle.USER_ALL);
-// } else {
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller));
-// }
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
return mInjector.binderWithCleanCallingIdentity(() -> {
String[] macAddresses = mInjector.getWifiManager().getFactoryMacAddresses();
@@ -17462,25 +17150,15 @@
if (!mHasFeature) {
return;
}
- CallerIdentity caller;
- ActiveAdmin admin;
message = PolicySizeVerifier.truncateIfLonger(message, MAX_SHORT_SUPPORT_MESSAGE_LENGTH);
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
- who,
- MANAGE_DEVICE_POLICY_SUPPORT_MESSAGE,
- caller.getPackageName(),
- caller.getUserId());
- admin = enforcingAdmin.getActiveAdmin();
- } else {
- caller = getCallerIdentity(who);
- Objects.requireNonNull(who, "ComponentName is null");
- synchronized (getLockObject()) {
- admin = getActiveAdminForUidLocked(who, caller.getUid());
- }
+ CallerIdentity caller = getCallerIdentity(who);
+ Objects.requireNonNull(who, "ComponentName is null");
+
+ ActiveAdmin admin;
+ synchronized (getLockObject()) {
+ admin = getActiveAdminForUidLocked(who, caller.getUid());
}
synchronized (getLockObject()) {
@@ -17501,23 +17179,13 @@
if (!mHasFeature) {
return null;
}
- CallerIdentity caller;
- ActiveAdmin admin;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
- who,
- MANAGE_DEVICE_POLICY_SUPPORT_MESSAGE,
- caller.getPackageName(),
- caller.getUserId());
- admin = enforcingAdmin.getActiveAdmin();
- } else {
- caller = getCallerIdentity(who);
- Objects.requireNonNull(who, "ComponentName is null");
- synchronized (getLockObject()) {
- admin = getActiveAdminForUidLocked(who, caller.getUid());
- }
+ CallerIdentity caller = getCallerIdentity(who);
+ Objects.requireNonNull(who, "ComponentName is null");
+
+ ActiveAdmin admin;
+ synchronized (getLockObject()) {
+ admin = getActiveAdminForUidLocked(who, caller.getUid());
}
return admin.shortSupportMessage;
}
@@ -17680,26 +17348,14 @@
return;
}
CallerIdentity caller = getCallerIdentity(who);
- ActiveAdmin admin = null;
- if (isPermissionCheckFlagEnabled()) {
- EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
- who,
- MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
- caller.getPackageName(),
- caller.getUserId());
- admin = enforcingAdmin.getActiveAdmin();
- } else {
- Objects.requireNonNull(who, "ComponentName is null");
- Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
- }
+ Objects.requireNonNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
text = PolicySizeVerifier.truncateIfLonger(text, MAX_ORG_NAME_LENGTH);
synchronized (getLockObject()) {
- if (!isPermissionCheckFlagEnabled()) {
- admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
- }
+ ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
if (!TextUtils.equals(admin.organizationName, text)) {
admin.organizationName = (text == null || text.length() == 0)
? null : text.toString();
@@ -17714,23 +17370,14 @@
return null;
}
CallerIdentity caller = getCallerIdentity(who);
+
+ Objects.requireNonNull(who, "ComponentName is null");
+ Preconditions.checkCallingUser(isManagedProfile(caller.getUserId()));
+ Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
+
ActiveAdmin admin;
-
- if (isPermissionCheckFlagEnabled()) {
- EnforcingAdmin enforcingAdmin = enforceCanQueryAndGetEnforcingAdmin(
- who,
- MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
- caller.getPackageName(),
- caller.getUserId());
- admin = enforcingAdmin.getActiveAdmin();
- } else {
- Objects.requireNonNull(who, "ComponentName is null");
- Preconditions.checkCallingUser(isManagedProfile(caller.getUserId()));
- Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
-
- synchronized (getLockObject()) {
- admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
- }
+ synchronized (getLockObject()) {
+ admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
}
return admin.organizationName;
@@ -18214,28 +17861,19 @@
}
final CallerIdentity caller = getCallerIdentity(admin, packageName);
- if (isPermissionCheckFlagEnabled()) {
- synchronized (getLockObject()) {
- Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
- || areAllUsersAffiliatedWithDeviceLocked());
- enforcePermission(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, caller.getPackageName(),
- UserHandle.USER_ALL);
- }
+ if (admin != null) {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isDefaultDeviceOwner(caller));
} else {
- if (admin != null) {
- Preconditions.checkCallAuthorization(
- isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isDefaultDeviceOwner(caller));
- } else {
- // A delegate app passes a null admin component, which is expected
- Preconditions.checkCallAuthorization(
- isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
- }
+ // A delegate app passes a null admin component, which is expected
+ Preconditions.checkCallAuthorization(
+ isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
+ }
- synchronized (getLockObject()) {
- Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
- || areAllUsersAffiliatedWithDeviceLocked());
- }
+ synchronized (getLockObject()) {
+ Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
+ || areAllUsersAffiliatedWithDeviceLocked());
}
DevicePolicyEventLogger
@@ -18259,7 +17897,7 @@
return new ParceledListSlice<SecurityEvent>(output);
} catch (IOException e) {
Slogf.w(LOG_TAG, "Fail to read previous events" , e);
- return new ParceledListSlice<SecurityEvent>(Collections.<SecurityEvent>emptyList());
+ return new ParceledListSlice<SecurityEvent>(Collections.emptyList());
}
}
@@ -18752,8 +18390,8 @@
}
private boolean hasIncompatibleAccounts(int userId) {
- return mHasIncompatibleAccounts == null ? true
- : mHasIncompatibleAccounts.getOrDefault(userId, /* default= */ false);
+ return mHasIncompatibleAccounts == null || mHasIncompatibleAccounts.getOrDefault(
+ userId, /* default= */ false);
}
/**
@@ -18870,7 +18508,7 @@
return false;
}
}
- };
+ }
private boolean isAdb(CallerIdentity caller) {
return isShellUid(caller) || isRootUid(caller);
@@ -20168,21 +19806,12 @@
@Override
public void installUpdateFromFile(ComponentName admin, String callerPackageName,
ParcelFileDescriptor updateFileDescriptor, StartInstallingUpdateCallback callback) {
- if (!isPermissionCheckFlagEnabled()) {
- Objects.requireNonNull(admin, "ComponentName is null");
- }
+ Objects.requireNonNull(admin, "ComponentName is null");
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(admin, callerPackageName);
- enforcePermission(MANAGE_DEVICE_POLICY_SYSTEM_UPDATES, caller.getPackageName(),
- UserHandle.USER_ALL);
- } else {
- caller = getCallerIdentity(admin);
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller));
- }
+ CallerIdentity caller = getCallerIdentity(admin);
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_INSTALL_SYSTEM_UPDATE);
DevicePolicyEventLogger
@@ -20752,32 +20381,15 @@
@Override
public void setCommonCriteriaModeEnabled(ComponentName who, String callerPackageName,
boolean enabled) {
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(who, callerPackageName);
- } else {
- caller = getCallerIdentity(who);
- }
- final ActiveAdmin admin;
+ CallerIdentity caller = getCallerIdentity(who);
- if (isPermissionCheckFlagEnabled()) {
- EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
- who,
- MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE,
- caller.getPackageName(),
- caller.getUserId());
- admin = enforcingAdmin.getActiveAdmin();
- } else {
- Objects.requireNonNull(who, "ComponentName is null");
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
- "Common Criteria mode can only be controlled by a device owner or "
- + "a profile owner on an organization-owned device.");
- synchronized (getLockObject()) {
- admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
- }
- }
+ Objects.requireNonNull(who, "ComponentName is null");
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
+ "Common Criteria mode can only be controlled by a device owner or "
+ + "a profile owner on an organization-owned device.");
synchronized (getLockObject()) {
+ final ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
admin.mCommonCriteriaMode = enabled;
saveSettingsLocked(caller.getUserId());
}
@@ -20809,7 +20421,7 @@
// their ActiveAdmin, instead of iterating through all admins.
ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked();
- return admin != null ? admin.mCommonCriteriaMode : false;
+ return admin != null && admin.mCommonCriteriaMode;
}
}
@@ -22209,7 +21821,7 @@
} else {
owner = getDeviceOrProfileOwnerAdminLocked(userId);
}
- boolean canGrant = owner != null ? owner.mAdminCanGrantSensorsPermissions : false;
+ boolean canGrant = owner != null && owner.mAdminCanGrantSensorsPermissions;
mPolicyCache.setAdminCanGrantSensorsPermissions(canGrant);
}
}
@@ -22408,27 +22020,15 @@
@Override
public void setMinimumRequiredWifiSecurityLevel(String callerPackageName, int level) {
- CallerIdentity caller;
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(callerPackageName);
- } else {
- caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
- "Wi-Fi minimum security level can only be controlled by a device owner or "
- + "a profile owner on an organization-owned device.");
- }
+ CallerIdentity caller = getCallerIdentity();
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
+ "Wi-Fi minimum security level can only be controlled by a device owner or "
+ + "a profile owner on an organization-owned device.");
boolean valueChanged = false;
synchronized (getLockObject()) {
- ActiveAdmin admin;
- if (isPermissionCheckFlagEnabled()) {
- admin = enforcePermissionAndGetEnforcingAdmin(/* admin= */ null,
- MANAGE_DEVICE_POLICY_WIFI, caller.getPackageName(), caller.getUserId())
- .getActiveAdmin();
- } else {
- admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
- }
+ ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
if (admin.mWifiMinimumSecurityLevel != level) {
admin.mWifiMinimumSecurityLevel = level;
saveSettingsLocked(caller.getUserId());
@@ -22450,21 +22050,16 @@
@Override
public WifiSsidPolicy getWifiSsidPolicy(String callerPackageName) {
final CallerIdentity caller = getCallerIdentity();
- if (isPermissionCheckFlagEnabled()) {
- enforcePermission(MANAGE_DEVICE_POLICY_WIFI, callerPackageName,
- caller.getUserId());
- } else {
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller)
- || canQueryAdminPolicy(caller),
- "SSID policy can only be retrieved by a device owner or "
- + "a profile owner on an organization-owned device or "
- + "an app with the QUERY_ADMIN_POLICY permission.");
- }
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || canQueryAdminPolicy(caller),
+ "SSID policy can only be retrieved by a device owner or "
+ + "a profile owner on an organization-owned device or "
+ + "an app with the QUERY_ADMIN_POLICY permission.");
synchronized (getLockObject()) {
ActiveAdmin admin;
- admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceOrSystemPermissionBasedAdminLocked();
+ admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked();
return admin != null ? admin.mWifiSsidPolicy : null;
}
}
@@ -22485,29 +22080,15 @@
@Override
public void setWifiSsidPolicy(String callerPackageName, WifiSsidPolicy policy) {
- CallerIdentity caller;
-
- if (isPermissionCheckFlagEnabled()) {
- caller = getCallerIdentity(callerPackageName);
- } else {
- caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
- "SSID denylist can only be controlled by a device owner or "
- + "a profile owner on an organization-owned device.");
- }
+ CallerIdentity caller = getCallerIdentity();
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller),
+ "SSID denylist can only be controlled by a device owner or "
+ + "a profile owner on an organization-owned device.");
boolean changed = false;
synchronized (getLockObject()) {
- ActiveAdmin admin;
- if (isPermissionCheckFlagEnabled()) {
- admin = enforcePermissionAndGetEnforcingAdmin(
- /* admin= */ null, MANAGE_DEVICE_POLICY_WIFI,
- caller.getPackageName(),
- caller.getUserId()).getActiveAdmin();
- } else {
- admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
- }
+ ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
if (!Objects.equals(policy, admin.mWifiSsidPolicy)) {
admin.mWifiSsidPolicy = policy;
changed = true;
@@ -22715,7 +22296,7 @@
}
private final class DevicePolicyManagementRoleObserver implements OnRoleHoldersChangedListener {
- private RoleManager mRm;
+ private final RoleManager mRm;
private final Executor mExecutor;
private final Context mContext;
@@ -22732,13 +22313,11 @@
@Override
public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
mDevicePolicyEngine.handleRoleChanged(roleName, user.getIdentifier());
- if (RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) {
- handleDevicePolicyManagementRoleChange(user);
- return;
- }
- if (RoleManager.ROLE_FINANCED_DEVICE_KIOSK.equals(roleName)) {
- handleFinancedDeviceKioskRoleChange();
- return;
+ switch (roleName) {
+ case RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT ->
+ handleDevicePolicyManagementRoleChange(user);
+ case RoleManager.ROLE_FINANCED_DEVICE_KIOSK ->
+ handleFinancedDeviceKioskRoleChange();
}
}
@@ -23390,26 +22969,6 @@
/**
* Checks if the calling process has been granted permission to apply a device policy on a
- * specific user.
- * The given permission will be checked along with its associated cross-user permission if it
- * exists and the target user is different to the calling user.
- * Returns an {@link EnforcingAdmin} for the caller.
- *
- * @param admin the component name of the admin.
- * @param callerPackageName The package name of the calling application.
- * @param permission The name of the permission being checked.
- * @param deviceAdminPolicy The userId of the user which the caller needs permission to act on.
- * @throws SecurityException if the caller has not been granted the given permission,
- * the associated cross-user permission if the caller's user is different to the target user.
- */
- private EnforcingAdmin enforcePermissionAndGetEnforcingAdmin(@Nullable ComponentName admin,
- String permission, int deviceAdminPolicy, String callerPackageName, int targetUserId) {
- enforcePermission(permission, deviceAdminPolicy, callerPackageName, targetUserId);
- return getEnforcingAdminForCaller(admin, callerPackageName);
- }
-
- /**
- * Checks if the calling process has been granted permission to apply a device policy on a
* specific user. Only one permission provided in the list needs to be granted to pass this
* check.
* The given permissions will be checked along with their associated cross-user permissions if
@@ -23431,23 +22990,6 @@
}
/**
- * Checks whether the calling process has been granted permission to query a device policy on
- * a specific user.
- * The given permission will be checked along with its associated cross-user permission if it
- * exists and the target user is different to the calling user.
- *
- * @param permission The name of the permission being checked.
- * @param targetUserId The userId of the user which the caller needs permission to act on.
- * @throws SecurityException if the caller has not been granted the given permission,
- * the associated cross-user permission if the caller's user is different to the target user.
- */
- private EnforcingAdmin enforceCanQueryAndGetEnforcingAdmin(@Nullable ComponentName admin,
- String permission, String callerPackageName, int targetUserId) {
- enforceCanQuery(permission, callerPackageName, targetUserId);
- return getEnforcingAdminForCaller(admin, callerPackageName);
- }
-
- /**
* Checks if the calling process has been granted permission to apply a device policy.
*
* @param callerPackageName The package name of the calling application.
@@ -23754,13 +23296,6 @@
return NOT_A_DPC;
}
- private boolean isPermissionCheckFlagEnabled() {
- return DeviceConfig.getBoolean(
- NAMESPACE_DEVICE_POLICY_MANAGER,
- PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG,
- DEFAULT_VALUE_PERMISSION_BASED_ACCESS_FLAG);
- }
-
private static boolean isSetStatusBarDisabledCoexistenceEnabled() {
return false;
}
@@ -23837,58 +23372,83 @@
Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller));
}
- if (isPermissionCheckFlagEnabled()) {
+ if (Flags.setMtePolicyCoexistence()) {
enforcePermission(MANAGE_DEVICE_POLICY_MTE, caller.getPackageName(),
UserHandle.USER_ALL);
} else {
Preconditions.checkCallAuthorization(
isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller));
+ || isProfileOwnerOfOrganizationOwnedDevice(caller));
}
+
synchronized (getLockObject()) {
- ActiveAdmin admin =
- getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked();
-
- if (admin != null) {
- final String memtagProperty = "arm64.memtag.bootctl";
- if (flags == DevicePolicyManager.MTE_ENABLED) {
- mInjector.systemPropertiesSet(memtagProperty, "memtag");
- } else if (flags == DevicePolicyManager.MTE_DISABLED) {
- mInjector.systemPropertiesSet(memtagProperty, "memtag-off");
- } else if (flags == DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY) {
- if (admin.mtePolicy != DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY) {
- mInjector.systemPropertiesSet(memtagProperty, "default");
- }
+ if (Flags.setMtePolicyCoexistence()) {
+ final EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(null,
+ MANAGE_DEVICE_POLICY_MTE, callerPackageName, caller.getUserId());
+ if (flags != DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY) {
+ mDevicePolicyEngine.setGlobalPolicy(
+ PolicyDefinition.MEMORY_TAGGING,
+ admin,
+ new IntegerPolicyValue(flags));
+ } else {
+ mDevicePolicyEngine.removeGlobalPolicy(
+ PolicyDefinition.MEMORY_TAGGING,
+ admin);
}
- admin.mtePolicy = flags;
- saveSettingsLocked(caller.getUserId());
-
- DevicePolicyEventLogger.createEvent(DevicePolicyEnums.SET_MTE_POLICY)
- .setInt(flags)
- .setAdmin(caller.getPackageName())
- .write();
+ } else {
+ ActiveAdmin admin =
+ getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked();
+ if (admin != null) {
+ final String memtagProperty = "arm64.memtag.bootctl";
+ if (flags == DevicePolicyManager.MTE_ENABLED) {
+ mInjector.systemPropertiesSet(memtagProperty, "memtag");
+ } else if (flags == DevicePolicyManager.MTE_DISABLED) {
+ mInjector.systemPropertiesSet(memtagProperty, "memtag-off");
+ } else if (flags == DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY) {
+ if (admin.mtePolicy != DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY) {
+ mInjector.systemPropertiesSet(memtagProperty, "default");
+ }
+ }
+ admin.mtePolicy = flags;
+ saveSettingsLocked(caller.getUserId());
+ }
}
+
+ DevicePolicyEventLogger.createEvent(DevicePolicyEnums.SET_MTE_POLICY)
+ .setInt(flags)
+ .setAdmin(caller.getPackageName())
+ .write();
}
}
@Override
public int getMtePolicy(String callerPackageName) {
final CallerIdentity caller = getCallerIdentity(callerPackageName);
- if (isPermissionCheckFlagEnabled()) {
+ if (Flags.setMtePolicyCoexistence()) {
enforcePermission(MANAGE_DEVICE_POLICY_MTE, caller.getPackageName(),
UserHandle.USER_ALL);
} else {
Preconditions.checkCallAuthorization(
isDefaultDeviceOwner(caller)
- || isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isSystemUid(caller));
+ || isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isSystemUid(caller));
}
+
synchronized (getLockObject()) {
- ActiveAdmin admin =
+ if (Flags.setMtePolicyCoexistence()) {
+ final EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(null,
+ MANAGE_DEVICE_POLICY_MTE, callerPackageName, caller.getUserId());
+ final Integer policyFromAdmin = mDevicePolicyEngine.getGlobalPolicySetByAdmin(
+ PolicyDefinition.MEMORY_TAGGING, admin);
+ return (policyFromAdmin != null ? policyFromAdmin
+ : DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY);
+ } else {
+ ActiveAdmin admin =
getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked();
- return admin != null
- ? admin.mtePolicy
- : DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY;
+ return admin != null
+ ? admin.mtePolicy
+ : DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY;
+ }
}
}
@@ -24235,21 +23795,24 @@
maybeMigrateSecurityLoggingPolicyLocked();
// ID format: <sdk-int>.<auto_increment_id>.<descriptions>'
String unmanagedBackupId = "35.1.unmanaged-mode";
- boolean unmanagedMigrated = false;
- unmanagedMigrated =
- unmanagedMigrated | maybeMigrateRequiredPasswordComplexityLocked(unmanagedBackupId);
- unmanagedMigrated =
- unmanagedMigrated | maybeMigrateSuspendedPackagesLocked(unmanagedBackupId);
+ boolean unmanagedMigrated = maybeMigrateRequiredPasswordComplexityLocked(unmanagedBackupId);
if (unmanagedMigrated) {
Slogf.i(LOG_TAG, "Backup made: " + unmanagedBackupId);
}
String supervisionBackupId = "36.2.supervision-support";
boolean supervisionMigrated = maybeMigrateResetPasswordTokenLocked(supervisionBackupId);
+ supervisionMigrated |= maybeMigrateSuspendedPackagesLocked(supervisionBackupId);
if (supervisionMigrated) {
Slogf.i(LOG_TAG, "Backup made: " + supervisionBackupId);
}
+ String memoryTaggingBackupId = "36.3.memory-tagging";
+ boolean memoryTaggingMigrated = maybeMigrateMemoryTaggingLocked(memoryTaggingBackupId);
+ if (memoryTaggingMigrated) {
+ Slogf.i(LOG_TAG, "Backup made: " + memoryTaggingBackupId);
+ }
+
// Additional migration steps should repeat the pattern above with a new backupId.
}
@@ -24666,7 +24229,7 @@
|| isCallerDevicePolicyManagementRoleHolder(caller)
|| isCallerSystemSupervisionRoleHolder(caller));
return getFinancedDeviceKioskRoleHolderOnAnyUser() != null;
- };
+ }
@Override
public String getFinancedDeviceKioskRoleHolder(String callerPackageName) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index b3c8408..be4eea4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -682,6 +682,19 @@
}
}
+ void markMemoryTaggingMigrated() {
+ synchronized (mData) {
+ mData.mMemoryTaggingMigrated = true;
+ mData.writeDeviceOwner();
+ }
+ }
+
+ boolean isMemoryTaggingMigrated() {
+ synchronized (mData) {
+ return mData.mMemoryTaggingMigrated;
+ }
+ }
+
@GuardedBy("mData")
void pushToAppOpsLocked() {
if (!mSystemReady) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
index 10e43d9..1cae924 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
@@ -93,6 +93,9 @@
private static final String ATTR_SUSPENDED_PACKAGES_MIGRATED = "suspendedPackagesMigrated";
private static final String ATTR_RESET_PASSWORD_WITH_TOKEN_MIGRATED =
"resetPasswordWithTokenMigrated";
+ private static final String ATTR_MEMORY_TAGGING_MIGRATED =
+ "memoryTaggingMigrated";
+
private static final String ATTR_MIGRATED_POST_UPGRADE = "migratedPostUpgrade";
// Internal state for the device owner package.
@@ -125,6 +128,7 @@
boolean mRequiredPasswordComplexityMigrated = false;
boolean mSuspendedPackagesMigrated = false;
boolean mResetPasswordWithTokenMigrated = false;
+ boolean mMemoryTaggingMigrated = false;
boolean mPoliciesMigratedPostUpdate = false;
@@ -416,6 +420,8 @@
if (Flags.unmanagedModeMigration()) {
out.attributeBoolean(null, ATTR_REQUIRED_PASSWORD_COMPLEXITY_MIGRATED,
mRequiredPasswordComplexityMigrated);
+ }
+ if (Flags.suspendPackagesCoexistence()) {
out.attributeBoolean(null, ATTR_SUSPENDED_PACKAGES_MIGRATED,
mSuspendedPackagesMigrated);
@@ -424,6 +430,10 @@
out.attributeBoolean(null, ATTR_RESET_PASSWORD_WITH_TOKEN_MIGRATED,
mResetPasswordWithTokenMigrated);
}
+ if (Flags.setMtePolicyCoexistence()) {
+ out.attributeBoolean(null, ATTR_MEMORY_TAGGING_MIGRATED,
+ mMemoryTaggingMigrated);
+ }
out.endTag(null, TAG_POLICY_ENGINE_MIGRATION);
}
@@ -491,13 +501,15 @@
mRequiredPasswordComplexityMigrated = Flags.unmanagedModeMigration()
&& parser.getAttributeBoolean(null,
ATTR_REQUIRED_PASSWORD_COMPLEXITY_MIGRATED, false);
- mSuspendedPackagesMigrated = Flags.unmanagedModeMigration()
+ mSuspendedPackagesMigrated = Flags.suspendPackagesCoexistence()
&& parser.getAttributeBoolean(null,
ATTR_SUSPENDED_PACKAGES_MIGRATED, false);
mResetPasswordWithTokenMigrated = Flags.resetPasswordWithTokenCoexistence()
&& parser.getAttributeBoolean(null,
ATTR_RESET_PASSWORD_WITH_TOKEN_MIGRATED, false);
-
+ mMemoryTaggingMigrated = Flags.setMtePolicyCoexistence()
+ && parser.getAttributeBoolean(null,
+ ATTR_MEMORY_TAGGING_MIGRATED, false);
break;
default:
Slog.e(TAG, "Unexpected tag: " + tag);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
index 6cb1756..f1711f5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -337,6 +337,13 @@
PolicyEnforcerCallbacks::noOp,
new PackageSetPolicySerializer());
+ static PolicyDefinition<Integer> MEMORY_TAGGING = new PolicyDefinition<>(
+ new NoArgsPolicyKey(
+ DevicePolicyIdentifiers.MEMORY_TAGGING_POLICY),
+ new TopPriority<>(List.of(EnforcingAdmin.DPC_AUTHORITY)),
+ PolicyEnforcerCallbacks::setMtePolicy,
+ new IntegerPolicySerializer());
+
private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>();
private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>();
@@ -383,6 +390,8 @@
PASSWORD_COMPLEXITY);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.PACKAGES_SUSPENDED_POLICY,
PACKAGES_SUSPENDED);
+ POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.MEMORY_TAGGING_POLICY,
+ MEMORY_TAGGING);
// User Restriction Policies
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
index 1454162..fdc0ec1 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
@@ -47,6 +47,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.permission.AdminPermissionControlParams;
import android.permission.PermissionControllerManager;
@@ -210,6 +211,7 @@
private static class BlockingCallback {
private final CountDownLatch mLatch = new CountDownLatch(1);
private final AtomicReference<Boolean> mValue = new AtomicReference<>();
+
public void trigger(Boolean value) {
mValue.set(value);
mLatch.countDown();
@@ -435,4 +437,43 @@
return AndroidFuture.completedFuture(true);
});
}
+
+ static CompletableFuture<Boolean> setMtePolicy(
+ @Nullable Integer mtePolicy, @NonNull Context context, int userId,
+ @NonNull PolicyKey policyKey) {
+ if (mtePolicy == null) {
+ mtePolicy = DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY;
+ }
+ final Set<Integer> allowedModes =
+ Set.of(
+ DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY,
+ DevicePolicyManager.MTE_DISABLED,
+ DevicePolicyManager.MTE_ENABLED);
+ if (!allowedModes.contains(mtePolicy)) {
+ Slog.wtf(LOG_TAG, "MTE policy is not a known one: " + mtePolicy);
+ return AndroidFuture.completedFuture(false);
+ }
+
+ final String mteDpmSystemProperty =
+ "ro.arm64.memtag.bootctl_device_policy_manager";
+ final String mteSettingsSystemProperty =
+ "ro.arm64.memtag.bootctl_settings_toggle";
+ final String mteControlProperty = "arm64.memtag.bootctl";
+
+ final boolean isAvailable = SystemProperties.getBoolean(mteDpmSystemProperty,
+ SystemProperties.getBoolean(mteSettingsSystemProperty, false));
+ if (!isAvailable) {
+ return AndroidFuture.completedFuture(false);
+ }
+
+ if (mtePolicy == DevicePolicyManager.MTE_ENABLED) {
+ SystemProperties.set(mteControlProperty, "memtag");
+ } else if (mtePolicy == DevicePolicyManager.MTE_DISABLED) {
+ SystemProperties.set(mteControlProperty, "memtag-off");
+ } else if (mtePolicy == DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY) {
+ SystemProperties.set(mteControlProperty, "default");
+ }
+
+ return AndroidFuture.completedFuture(true);
+ }
}
diff --git a/services/proguard.flags b/services/proguard.flags
index cdd41ab..977bd19 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -82,7 +82,7 @@
-keep,allowoptimization,allowaccessmodification class com.android.server.usb.UsbAlsaJackDetector { *; }
-keep,allowoptimization,allowaccessmodification class com.android.server.usb.UsbAlsaMidiDevice { *; }
-keep,allowoptimization,allowaccessmodification class com.android.server.vibrator.VibratorController$OnVibrationCompleteListener { *; }
--keep,allowoptimization,allowaccessmodification class com.android.server.vibrator.VibratorManagerService$OnSyncedVibrationCompleteListener { *; }
+-keep,allowoptimization,allowaccessmodification class com.android.server.vibrator.VibratorManagerService$VibratorManagerNativeCallbacks { *; }
-keepclasseswithmembers,allowoptimization,allowaccessmodification class com.android.server.** {
*** *FromNative(...);
}
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
index a804f24..c30ab73 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
@@ -101,13 +101,13 @@
TEST_SETTING_ACTIVITY_NAME, subtypes, TEST_IS_DEFAULT_RES_ID,
TEST_FORCE_DEFAULT, supportsSwitchingToNextInputMethod, TEST_IS_VR_IME);
if (subtypes == null) {
- items.add(new ImeSubtypeListItem(imeName, null /* variableName */, imi,
- NOT_A_SUBTYPE_INDEX, null, SYSTEM_LOCALE));
+ items.add(new ImeSubtypeListItem(imeName, null /* subtypeName */, null /* layoutName */,
+ imi, NOT_A_SUBTYPE_INDEX, null, SYSTEM_LOCALE));
} else {
for (int i = 0; i < subtypes.size(); ++i) {
final String subtypeLocale = subtypeLocales.get(i);
- items.add(new ImeSubtypeListItem(imeName, subtypeLocale, imi, i, subtypeLocale,
- SYSTEM_LOCALE));
+ items.add(new ImeSubtypeListItem(imeName, subtypeLocale, null /* layoutName */,
+ imi, i, subtypeLocale, SYSTEM_LOCALE));
}
}
}
@@ -138,8 +138,8 @@
final InputMethodInfo imi = new InputMethodInfo(ri, TEST_IS_AUX_IME,
TEST_SETTING_ACTIVITY_NAME, subtypes, TEST_IS_DEFAULT_RES_ID,
TEST_FORCE_DEFAULT, true /* supportsSwitchingToNextInputMethod */, TEST_IS_VR_IME);
- return new ImeSubtypeListItem(imeName, subtypeName, imi, subtypeIndex, subtypeLocale,
- SYSTEM_LOCALE);
+ return new ImeSubtypeListItem(imeName, subtypeName, null /* layoutName */, imi,
+ subtypeIndex, subtypeLocale, SYSTEM_LOCALE);
}
@NonNull
diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java
index 06f1b27..a8708f9 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java
@@ -223,7 +223,8 @@
mIntRangeUserPerceptionEnabled);
mSynchronizer.startSynchronizing();
verify(mDisplayManagerMock).registerDisplayListener(mDisplayListenerCaptor.capture(),
- isA(Handler.class), eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ isA(Handler.class), eq(0L),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
mDisplayListener = mDisplayListenerCaptor.getValue();
verify(mContentResolverSpy).registerContentObserver(eq(BRIGHTNESS_URI), eq(false),
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index b917af4..c741cae 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -203,11 +203,13 @@
private static final String VIRTUAL_DISPLAY_NAME = "Test Virtual Display";
private static final String PACKAGE_NAME = "com.android.frameworks.displayservicetests";
- private static final long STANDARD_DISPLAY_EVENTS = DisplayManager.EVENT_FLAG_DISPLAY_ADDED
- | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED;
+ private static final long STANDARD_DISPLAY_EVENTS =
+ DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED;
private static final long STANDARD_AND_CONNECTION_DISPLAY_EVENTS =
- STANDARD_DISPLAY_EVENTS | DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED;
+ STANDARD_DISPLAY_EVENTS
+ | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED;
private static final String EVENT_DISPLAY_ADDED = "EVENT_DISPLAY_ADDED";
private static final String EVENT_DISPLAY_REMOVED = "EVENT_DISPLAY_REMOVED";
@@ -2379,7 +2381,7 @@
// register display listener callback
FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback();
long allEventsExceptDisplayAdded = STANDARD_DISPLAY_EVENTS
- & ~DisplayManager.EVENT_FLAG_DISPLAY_ADDED;
+ & ~DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED;
displayManagerBinderService.registerCallbackWithEventMask(callback,
allEventsExceptDisplayAdded);
@@ -2450,7 +2452,7 @@
FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback();
long allEventsExceptDisplayRemoved = STANDARD_DISPLAY_EVENTS
- & ~DisplayManager.EVENT_FLAG_DISPLAY_REMOVED;
+ & ~DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED;
displayManagerBinderService.registerCallbackWithEventMask(callback,
allEventsExceptDisplayRemoved);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index 27fd1e6..e64d985 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -139,6 +139,7 @@
private TestLooper mTestLooper;
private Handler mHandler;
private DisplayPowerControllerHolder mHolder;
+ private DisplayBrightnessState mDisplayBrightnessState;
private Sensor mProxSensor;
@Mock
@@ -187,6 +188,7 @@
mClock = new OffsettableClock.Stopped();
mTestLooper = new TestLooper(mClock::now);
mHandler = new Handler(mTestLooper.getLooper());
+ mDisplayBrightnessState = DisplayBrightnessState.builder().build();
// Set some settings to minimize unexpected events and have a consistent starting state
Settings.System.putInt(mContext.getContentResolver(),
@@ -1453,10 +1455,11 @@
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(.2f);
when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(.1f);
- when(mHolder.clamperController.clamp(any(), anyFloat(), anyBoolean(), anyInt())).thenAnswer(
- invocation -> DisplayBrightnessState.builder()
- .setIsSlowChange(invocation.getArgument(2))
- .setBrightness(invocation.getArgument(1))
+ when(mHolder.clamperController.clamp(any(), any(), anyFloat(),
+ anyBoolean(), anyInt())).thenAnswer(
+ invocation -> DisplayBrightnessState.Builder.from(mDisplayBrightnessState)
+ .setIsSlowChange(invocation.getArgument(3))
+ .setBrightness(invocation.getArgument(2))
.setMaxBrightness(PowerManager.BRIGHTNESS_MAX)
.setCustomAnimationRate(transitionRate).build());
@@ -1477,10 +1480,11 @@
when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(.2f);
when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(.1f);
- when(mHolder.clamperController.clamp(any(), anyFloat(), anyBoolean(), anyInt())).thenAnswer(
- invocation -> DisplayBrightnessState.builder()
- .setIsSlowChange(invocation.getArgument(2))
- .setBrightness(invocation.getArgument(1))
+ when(mHolder.clamperController.clamp(any(), any(), anyFloat(),
+ anyBoolean(), anyInt())).thenAnswer(
+ invocation -> DisplayBrightnessState.Builder.from(mDisplayBrightnessState)
+ .setIsSlowChange(invocation.getArgument(3))
+ .setBrightness(invocation.getArgument(2))
.setMaxBrightness(PowerManager.BRIGHTNESS_MAX)
.setCustomAnimationRate(transitionRate).build());
@@ -2574,10 +2578,11 @@
BrightnessClamperController clamperController = mock(BrightnessClamperController.class);
when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX);
- when(clamperController.clamp(any(), anyFloat(), anyBoolean(), anyInt())).thenAnswer(
- invocation -> DisplayBrightnessState.builder()
- .setIsSlowChange(invocation.getArgument(2))
- .setBrightness(invocation.getArgument(1))
+ when(clamperController.clamp(any(), any(), anyFloat(), anyBoolean(),
+ anyInt())).thenAnswer(
+ invocation -> DisplayBrightnessState.Builder.from(mDisplayBrightnessState)
+ .setIsSlowChange(invocation.getArgument(3))
+ .setBrightness(invocation.getArgument(2))
.setMaxBrightness(PowerManager.BRIGHTNESS_MAX)
.setCustomAnimationRate(-1).build());
diff --git a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
index 3ac7fb0..e0b0fec 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
@@ -335,6 +335,10 @@
@Override
public void onStopped() {
}
+
+ @Override
+ public void onRequestedBrightnessChanged(float brightness) {
+ }
};
}
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
index da79f30..2aafdfa 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
@@ -98,6 +98,7 @@
@Mock
private DeviceConfig.Properties mMockProperties;
private BrightnessClamperController mClamperController;
+ private DisplayBrightnessState mDisplayBrightnessState;
private TestInjector mTestInjector;
@Before
@@ -109,6 +110,7 @@
when(mMockDisplayDeviceData.getAmbientLightSensor()).thenReturn(mMockSensorData);
mClamperController = createBrightnessClamperController();
+ mDisplayBrightnessState = DisplayBrightnessState.builder().build();
}
@Test
@@ -192,7 +194,8 @@
public void testClamp_AppliesModifier() {
float initialBrightness = 0.2f;
boolean initialSlowChange = true;
- mClamperController.clamp(mMockRequest, initialBrightness, initialSlowChange, STATE_ON);
+ mClamperController.clamp(mDisplayBrightnessState, mMockRequest, initialBrightness,
+ initialSlowChange, STATE_ON);
verify(mMockModifier).apply(eq(mMockRequest), any());
verify(mMockDisplayListenerModifier).apply(eq(mMockRequest), any());
@@ -204,7 +207,8 @@
float initialBrightness = 0.2f;
boolean initialSlowChange = true;
when(mMockModifier.shouldListenToLightSensor()).thenReturn(true);
- mClamperController.clamp(mMockRequest, initialBrightness, initialSlowChange, STATE_ON);
+ mClamperController.clamp(mDisplayBrightnessState, mMockRequest, initialBrightness,
+ initialSlowChange, STATE_ON);
verify(mMockLightSensorController).restart();
}
@@ -214,7 +218,8 @@
float initialBrightness = 0.2f;
boolean initialSlowChange = true;
clearInvocations(mMockLightSensorController);
- mClamperController.clamp(mMockRequest, initialBrightness, initialSlowChange, STATE_OFF);
+ mClamperController.clamp(mDisplayBrightnessState, mMockRequest, initialBrightness,
+ initialSlowChange, STATE_OFF);
verify(mMockLightSensorController).stop();
}
@@ -232,8 +237,8 @@
mTestInjector.mCapturedChangeListener.onChanged();
mTestHandler.flush();
- DisplayBrightnessState state = mClamperController.clamp(mMockRequest, initialBrightness,
- initialSlowChange, STATE_ON);
+ DisplayBrightnessState state = mClamperController.clamp(mDisplayBrightnessState,
+ mMockRequest, initialBrightness, initialSlowChange, STATE_ON);
assertEquals(initialBrightness, state.getBrightness(), FLOAT_TOLERANCE);
assertEquals(PowerManager.BRIGHTNESS_MAX, state.getMaxBrightness(), FLOAT_TOLERANCE);
@@ -256,8 +261,8 @@
mTestInjector.mCapturedChangeListener.onChanged();
mTestHandler.flush();
- DisplayBrightnessState state = mClamperController.clamp(mMockRequest, initialBrightness,
- initialSlowChange, STATE_ON);
+ DisplayBrightnessState state = mClamperController.clamp(mDisplayBrightnessState,
+ mMockRequest, initialBrightness, initialSlowChange, STATE_ON);
assertEquals(clampedBrightness, state.getBrightness(), FLOAT_TOLERANCE);
assertEquals(clampedBrightness, state.getMaxBrightness(), FLOAT_TOLERANCE);
@@ -280,8 +285,8 @@
mTestInjector.mCapturedChangeListener.onChanged();
mTestHandler.flush();
- DisplayBrightnessState state = mClamperController.clamp(mMockRequest, initialBrightness,
- initialSlowChange, STATE_ON);
+ DisplayBrightnessState state = mClamperController.clamp(mDisplayBrightnessState,
+ mMockRequest, initialBrightness, initialSlowChange, STATE_ON);
assertEquals(initialBrightness, state.getBrightness(), FLOAT_TOLERANCE);
assertEquals(clampedBrightness, state.getMaxBrightness(), FLOAT_TOLERANCE);
@@ -304,11 +309,11 @@
mTestInjector.mCapturedChangeListener.onChanged();
mTestHandler.flush();
// first call of clamp method
- mClamperController.clamp(mMockRequest, initialBrightness,
+ mClamperController.clamp(mDisplayBrightnessState, mMockRequest, initialBrightness,
initialSlowChange, STATE_ON);
// immediately second call of clamp method
- DisplayBrightnessState state = mClamperController.clamp(mMockRequest, initialBrightness,
- initialSlowChange, STATE_ON);
+ DisplayBrightnessState state = mClamperController.clamp(mDisplayBrightnessState,
+ mMockRequest, initialBrightness, initialSlowChange, STATE_ON);
assertEquals(clampedBrightness, state.getBrightness(), FLOAT_TOLERANCE);
assertEquals(clampedBrightness, state.getMaxBrightness(), FLOAT_TOLERANCE);
@@ -319,6 +324,22 @@
}
@Test
+ public void testClamp_activeClamperApplied_confirmBrightnessOverrideStateReturned() {
+ float initialBrightness = 0.8f;
+ boolean initialSlowChange = false;
+ mTestInjector.mCapturedChangeListener.onChanged();
+ mTestHandler.flush();
+
+ mDisplayBrightnessState = DisplayBrightnessState.builder().setBrightnessReason(
+ BrightnessReason.REASON_OVERRIDE).build();
+
+ DisplayBrightnessState state = mClamperController.clamp(mDisplayBrightnessState,
+ mMockRequest, initialBrightness, initialSlowChange, STATE_ON);
+
+ assertEquals(BrightnessReason.REASON_OVERRIDE, state.getBrightnessReason().getReason());
+ }
+
+ @Test
public void testAmbientLuxChanges() {
mTestInjector.mCapturedLightSensorListener.onAmbientLuxChange(50);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt b/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt
index 3c77ec9..3aef6aa 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt
@@ -97,11 +97,14 @@
private fun setUpLowBrightnessZone() {
whenever(mockInjector.getBrightnessInfo(Display.DEFAULT_DISPLAY)).thenReturn(
- BrightnessInfo(/* brightness = */ 0.05f, /* adjustedBrightness = */ 0.05f,
- /* brightnessMinimum = */ 0.0f, /* brightnessMaximum = */ 1.0f,
- BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
- /* highBrightnessTransitionPoint = */ 1.0f,
- BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE))
+ BrightnessInfo(/* brightness = */ 0.05f, /* adjustedBrightness = */ 0.05f,
+ /* brightnessMinimum = */ 0.0f, /* brightnessMaximum = */ 1.0f,
+ BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF,
+ /* highBrightnessTransitionPoint = */ 1.0f,
+ BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE,
+ false /* isBrightnessOverrideByWindow */
+ )
+ )
whenever(mockDeviceConfig.highDisplayBrightnessThresholds).thenReturn(floatArrayOf())
whenever(mockDeviceConfig.highAmbientBrightnessThresholds).thenReturn(floatArrayOf())
whenever(mockDeviceConfig.lowDisplayBrightnessThresholds).thenReturn(floatArrayOf(0.1f))
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
index 58f0ab4..4e0bab8 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
@@ -1225,8 +1225,8 @@
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener displayListener = displayListenerCaptor.getValue();
setBrightness(10, 10, displayListener);
@@ -1256,8 +1256,8 @@
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener displayListener = displayListenerCaptor.getValue();
setBrightness(10, 10, displayListener);
@@ -1291,8 +1291,8 @@
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener displayListener = displayListenerCaptor.getValue();
setBrightness(10, 10, displayListener);
@@ -1325,8 +1325,8 @@
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener displayListener = displayListenerCaptor.getValue();
ArgumentCaptor<SensorEventListener> sensorListenerCaptor =
@@ -1404,8 +1404,8 @@
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener displayListener = displayListenerCaptor.getValue();
ArgumentCaptor<SensorEventListener> sensorListenerCaptor =
@@ -1464,8 +1464,8 @@
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener displayListener = displayListenerCaptor.getValue();
ArgumentCaptor<SensorEventListener> listenerCaptor =
@@ -1630,8 +1630,8 @@
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener displayListener = displayListenerCaptor.getValue();
// Get the sensor listener so that we can give it new light sensor events
@@ -1730,8 +1730,8 @@
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
- | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener displayListener = displayListenerCaptor.getValue();
// Get the sensor listener so that we can give it new light sensor events
@@ -2877,8 +2877,8 @@
ArgumentCaptor<DisplayListener> captor =
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener listener = captor.getValue();
// Specify Limitation
@@ -3000,8 +3000,8 @@
ArgumentCaptor<DisplayListener> captor =
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener listener = captor.getValue();
final int initialRefreshRate = 60;
@@ -3075,8 +3075,8 @@
ArgumentCaptor<DisplayListener> captor =
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener listener = captor.getValue();
// Specify Limitation for different display
@@ -3115,8 +3115,8 @@
ArgumentCaptor<DisplayListener> captor =
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener listener = captor.getValue();
// Specify Limitation
@@ -3200,8 +3200,8 @@
ArgumentCaptor<DisplayListener> captor = ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener listener = captor.getValue();
// Specify Sunlight limitations
@@ -3239,8 +3239,8 @@
ArgumentCaptor<DisplayListener> captor =
ArgumentCaptor.forClass(DisplayListener.class);
verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
- eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
- | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+ eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
+ eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
DisplayListener listener = captor.getValue();
// Specify Limitation for different display
@@ -3786,8 +3786,9 @@
when(mInjector.getBrightnessInfo(DISPLAY_ID)).thenReturn(
new BrightnessInfo(floatBri, floatAdjBri, 0.0f, 1.0f,
- BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF, TRANSITION_POINT,
- BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE));
+ BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF, TRANSITION_POINT,
+ BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE,
+ false /* isBrightnessOverrideByWindow */));
listener.onDisplayChanged(DISPLAY_ID);
}
@@ -3897,7 +3898,12 @@
public void registerDisplayListener(DisplayListener listener, Handler handler) {}
@Override
- public void registerDisplayListener(DisplayListener listener, Handler handler, long flag) {}
+ public void registerDisplayListener(DisplayListener listener, Handler handler,
+ long flags) {}
+
+ @Override
+ public void registerDisplayListener(DisplayListener listener, Handler handler, long flag,
+ long privateFlag) {}
@Override
public Display getDisplay(int displayId) {
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index c81d6be..be698b2 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
java_defaults {
- name: "FrameworkMockingServicesTests-jni-defaults",
+ name: "FrameworksMockingServicesTests-jni-defaults",
jni_libs: [
"libmockingservicestestjni",
],
@@ -30,7 +30,7 @@
android_test {
name: "FrameworksMockingServicesTests",
defaults: [
- "FrameworkMockingServicesTests-jni-defaults",
+ "FrameworksMockingServicesTests-jni-defaults",
"modules-utils-testable-device-config-defaults",
],
@@ -77,7 +77,10 @@
"flag-junit",
"am_flags_lib",
"device_policy_aconfig_flags_lib",
- ],
+ ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), {
+ "true": ["service-crashrecovery.impl"],
+ default: [],
+ }),
libs: [
"android.test.mock.stubs.system",
diff --git a/services/tests/mockingservicestests/src/com/android/server/BatteryServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/BatteryServiceTest.java
new file mode 100644
index 0000000..5e2f80b
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/BatteryServiceTest.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+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.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.hardware.health.HealthInfo;
+import android.os.HandlerThread;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.R;
+import com.android.internal.app.IBatteryStats;
+import com.android.modules.utils.testing.ExtendedMockitoRule;
+import com.android.server.am.BatteryStatsService;
+import com.android.server.flags.Flags;
+import com.android.server.lights.LightsManager;
+import com.android.server.lights.LogicalLight;
+
+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 java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class BatteryServiceTest {
+
+ private static final int CURRENT_BATTERY_VOLTAGE = 3000;
+ private static final int VOLTAGE_LESS_THEN_ONE_PERCENT = 3029;
+ private static final int VOLTAGE_MORE_THEN_ONE_PERCENT = 3030;
+ private static final int CURRENT_BATTERY_TEMP = 300;
+ private static final int TEMP_LESS_THEN_ONE_DEGREE_CELSIUS = 305;
+ private static final int TEMP_MORE_THEN_ONE_DEGREE_CELSIUS = 310;
+ private static final int CURRENT_BATTERY_HEALTH = 2;
+ private static final int UPDATED_BATTERY_HEALTH = 3;
+ private static final int CURRENT_CHARGE_COUNTER = 4680000;
+ private static final int UPDATED_CHARGE_COUNTER = 4218000;
+ private static final int HANDLER_IDLE_TIME_MS = 5000;
+ @Rule
+ public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
+ .mockStatic(SystemProperties.class)
+ .mockStatic(ActivityManager.class)
+ .mockStatic(BatteryStatsService.class)
+ .build();
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Mock
+ private Context mContextMock;
+ @Mock
+ private LightsManager mLightsManagerMock;
+ @Mock
+ private ActivityManagerInternal mActivityManagerInternalMock;
+ @Mock
+ private IBatteryStats mIBatteryStatsMock;
+
+ private BatteryService mBatteryService;
+ private String mSystemUiPackage;
+
+ /**
+ * Creates a mock and registers it to {@link LocalServices}.
+ */
+ private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
+ LocalServices.removeServiceForTest(clazz);
+ LocalServices.addService(clazz, mock);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mSystemUiPackage = InstrumentationRegistry.getInstrumentation().getTargetContext()
+ .getResources().getString(R.string.config_systemUi);
+
+ when(mLightsManagerMock.getLight(anyInt())).thenReturn(mock(LogicalLight.class));
+ when(mActivityManagerInternalMock.isSystemReady()).thenReturn(true);
+ when(mContextMock.getResources()).thenReturn(
+ InstrumentationRegistry.getInstrumentation().getTargetContext().getResources());
+ ExtendedMockito.when(BatteryStatsService.getService()).thenReturn(mIBatteryStatsMock);
+
+ doNothing().when(mIBatteryStatsMock).setBatteryState(anyInt(), anyInt(), anyInt(), anyInt(),
+ anyInt(), anyInt(), anyInt(), anyInt(), anyLong());
+ doNothing().when(() -> SystemProperties.set(anyString(), anyString()));
+ doNothing().when(() -> ActivityManager.broadcastStickyIntent(any(),
+ eq(new String[]{mSystemUiPackage}), eq(AppOpsManager.OP_NONE),
+ eq(BatteryService.BATTERY_CHANGED_OPTIONS), eq(UserHandle.USER_ALL)));
+
+ addLocalServiceMock(LightsManager.class, mLightsManagerMock);
+ addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock);
+
+ createBatteryService();
+ }
+
+ @Test
+ public void createBatteryService_withNullLooper_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> new BatteryService(mContextMock));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void onlyVoltageUpdated_lessThenOnePercent_broadcastNotSent() {
+ mBatteryService.update(createHealthInfo(VOLTAGE_LESS_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
+ CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(0);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void onlyVoltageUpdated_beforeTwentySeconds_broadcastNotSent() {
+ mBatteryService.update(
+ createHealthInfo(VOLTAGE_MORE_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
+ CURRENT_CHARGE_COUNTER,
+ CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(0);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void onlyVoltageUpdated_broadcastSent() {
+ mBatteryService.mLastBroadcastVoltageUpdateTime = SystemClock.elapsedRealtime() - 20000;
+ mBatteryService.update(createHealthInfo(VOLTAGE_MORE_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
+ CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(1);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void onlyTempUpdated_lessThenOneDegreeCelsius_broadcastNotSent() {
+ mBatteryService.update(
+ createHealthInfo(CURRENT_BATTERY_VOLTAGE, TEMP_LESS_THEN_ONE_DEGREE_CELSIUS,
+ CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(0);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void tempUpdated_broadcastSent() {
+ long lastVoltageUpdateTime = mBatteryService.mLastBroadcastVoltageUpdateTime;
+ mBatteryService.update(
+ createHealthInfo(VOLTAGE_LESS_THEN_ONE_PERCENT, TEMP_MORE_THEN_ONE_DEGREE_CELSIUS,
+ UPDATED_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ assertTrue(lastVoltageUpdateTime < mBatteryService.mLastBroadcastVoltageUpdateTime);
+ verifyNumberOfTimesBroadcastSent(1);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void batteryHealthUpdated_voltageAndTempConst_broadcastSent() {
+ mBatteryService.update(
+ createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
+ CURRENT_CHARGE_COUNTER,
+ UPDATED_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(1);
+
+ // updating counter just after the health update does not triggers broadcast.
+ mBatteryService.update(
+ createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
+ UPDATED_CHARGE_COUNTER,
+ UPDATED_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(1);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void voltageUpdated_lessThanOnePercent_flagDisabled_broadcastSent() {
+ mBatteryService.update(createHealthInfo(VOLTAGE_LESS_THEN_ONE_PERCENT, CURRENT_BATTERY_TEMP,
+ CURRENT_CHARGE_COUNTER, CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(1);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void onlyChargeCounterUpdated_broadcastNotSent() {
+ mBatteryService.update(
+ createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
+ UPDATED_CHARGE_COUNTER,
+ CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(0);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void chargeCounterUpdated_tempUpdatedLessThanOneDegree_broadcastNotSent() {
+ mBatteryService.update(
+ createHealthInfo(CURRENT_BATTERY_VOLTAGE, TEMP_LESS_THEN_ONE_DEGREE_CELSIUS,
+ UPDATED_CHARGE_COUNTER,
+ CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(0);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_RATE_LIMIT_BATTERY_CHANGED_BROADCAST)
+ public void onlyChargeCounterUpdated_broadcastSent() {
+ mBatteryService.update(
+ createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
+ UPDATED_CHARGE_COUNTER,
+ CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+
+ verifyNumberOfTimesBroadcastSent(1);
+ }
+
+ private HealthInfo createHealthInfo(
+ int batteryVoltage,
+ int batteryTemperature,
+ int batteryChargeCounter,
+ int batteryHealth) {
+ HealthInfo h = new HealthInfo();
+ h.batteryVoltageMillivolts = batteryVoltage;
+ h.batteryTemperatureTenthsCelsius = batteryTemperature;
+ h.batteryChargeCounterUah = batteryChargeCounter;
+ h.batteryStatus = 5;
+ h.batteryHealth = batteryHealth;
+ h.batteryPresent = true;
+ h.batteryLevel = 100;
+ h.maxChargingCurrentMicroamps = 298125;
+ h.batteryCurrentAverageMicroamps = -2812;
+ h.batteryCurrentMicroamps = 298125;
+ h.maxChargingVoltageMicrovolts = 3000;
+ h.batteryCycleCount = 50;
+ h.chargingState = 4;
+ h.batteryCapacityLevel = 100;
+ return h;
+ }
+
+ // Creates a new battery service objects and sets the initial values.
+ private void createBatteryService() throws InterruptedException {
+ final HandlerThread handlerThread = new HandlerThread("BatteryServiceTest");
+ handlerThread.start();
+
+ mBatteryService = new BatteryService(mContextMock, handlerThread.getLooper());
+
+ // trigger the update to set the initial values.
+ mBatteryService.update(
+ createHealthInfo(CURRENT_BATTERY_VOLTAGE, CURRENT_BATTERY_TEMP,
+ CURRENT_CHARGE_COUNTER,
+ CURRENT_BATTERY_HEALTH));
+
+ waitForHandlerToExecute();
+ }
+
+ private void waitForHandlerToExecute() {
+ final CountDownLatch latch = new CountDownLatch(1);
+ mBatteryService.getHandlerForTest().post(latch::countDown);
+ boolean isExecutionComplete = false;
+
+ try {
+ isExecutionComplete = latch.await(HANDLER_IDLE_TIME_MS, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ fail("Handler interrupted before executing the message " + e);
+ }
+
+ assertTrue("Timed out while waiting for Handler to execute.", isExecutionComplete);
+ }
+
+ private void verifyNumberOfTimesBroadcastSent(int numberOfTimes) {
+ // Increase the numberOfTimes by 1 as one broadcast was sent initially during the test
+ // setUp.
+ verify(() -> ActivityManager.broadcastStickyIntent(any(),
+ eq(new String[]{mSystemUiPackage}), eq(AppOpsManager.OP_NONE),
+ eq(BatteryService.BATTERY_CHANGED_OPTIONS), eq(UserHandle.USER_ALL)),
+ times(++numberOfTimes));
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index cbc8538..37d1c30 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -15,7 +15,12 @@
*/
package com.android.server;
+import static android.os.PowerExemptionManager.REASON_OTHER;
+import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.NULL_DEFAULT;
+
import static androidx.test.InstrumentationRegistry.getContext;
+
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -31,6 +36,7 @@
import static com.android.server.DeviceIdleController.LIGHT_STATE_OVERRIDE;
import static com.android.server.DeviceIdleController.LIGHT_STATE_WAITING_FOR_NETWORK;
import static com.android.server.DeviceIdleController.MSG_REPORT_STATIONARY_STATUS;
+import static com.android.server.DeviceIdleController.MSG_TEMP_APP_WHITELIST_TIMEOUT;
import static com.android.server.DeviceIdleController.STATE_ACTIVE;
import static com.android.server.DeviceIdleController.STATE_IDLE;
import static com.android.server.DeviceIdleController.STATE_IDLE_MAINTENANCE;
@@ -41,6 +47,7 @@
import static com.android.server.DeviceIdleController.STATE_SENSING;
import static com.android.server.DeviceIdleController.lightStateToString;
import static com.android.server.DeviceIdleController.stateToString;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -83,6 +90,8 @@
import android.os.PowerSaveState;
import android.os.SystemClock;
import android.os.WearModeManagerInternal;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DeviceConfig;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
@@ -90,12 +99,16 @@
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.app.IBatteryStats;
+import com.android.server.am.BatteryStatsService;
import com.android.server.deviceidle.ConstraintController;
+import com.android.server.deviceidle.Flags;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -115,6 +128,9 @@
@SuppressWarnings("GuardedBy")
@RunWith(AndroidJUnit4.class)
public class DeviceIdleControllerTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(NULL_DEFAULT);
+
private DeviceIdleController mDeviceIdleController;
private DeviceIdleController.MyHandler mHandler;
private AnyMotionDetectorForTest mAnyMotionDetector;
@@ -157,7 +173,8 @@
LocationManager locationManager;
ConstraintController constraintController;
// Freeze time for testing.
- long nowElapsed;
+ volatile long nowElapsed;
+ volatile long nowUptime;
boolean useMotionSensor = true;
boolean isLocationPrefetchEnabled = true;
@@ -193,6 +210,11 @@
}
@Override
+ long getUptimeMillis() {
+ return nowUptime;
+ }
+
+ @Override
LocationManager getLocationManager() {
return locationManager;
}
@@ -314,11 +336,13 @@
mMockingSession = mockitoSession()
.initMocks(this)
.strictness(Strictness.LENIENT)
+ .mockStatic(BatteryStatsService.class)
.spyStatic(DeviceConfig.class)
.spyStatic(LocalServices.class)
.startMocking();
spyOn(getContext());
doReturn(null).when(getContext()).registerReceiver(any(), any());
+ doReturn(mock(IBatteryStats.class)).when(() -> BatteryStatsService.getService());
doReturn(mock(ActivityManagerInternal.class))
.when(() -> LocalServices.getService(ActivityManagerInternal.class));
doReturn(mock(ActivityTaskManagerInternal.class))
@@ -401,6 +425,46 @@
}
@Test
+ @EnableFlags(Flags.FLAG_USE_CPU_TIME_FOR_TEMP_ALLOWLIST)
+ public void testTempAllowlistCountsUptime() {
+ doNothing().when(getContext()).sendBroadcastAsUser(any(), any(), any(), any());
+ final int testUid = 12345;
+ final long durationMs = 4300;
+ final long startTime = 100; // Arbitrary starting point in time.
+ mInjector.nowUptime = mInjector.nowElapsed = startTime;
+
+ mDeviceIdleController.addPowerSaveTempWhitelistAppDirectInternal(0, testUid, durationMs,
+ TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, true, REASON_OTHER, "test");
+
+ assertEquals(startTime + durationMs,
+ mDeviceIdleController.mTempWhitelistAppIdEndTimes.get(testUid).first.value);
+
+ final InOrder inorder = inOrder(mHandler);
+ // mHandler is already stubbed to do nothing on handleMessage.
+ inorder.verify(mHandler).sendMessageDelayed(
+ argThat(m -> m.what == MSG_TEMP_APP_WHITELIST_TIMEOUT && m.arg1 == testUid),
+ eq(durationMs));
+
+ mInjector.nowElapsed += durationMs;
+ mInjector.nowUptime += 2;
+ // Elapsed time moved past the expiration but not uptime. The check should be rescheduled.
+ mDeviceIdleController.checkTempAppWhitelistTimeout(testUid);
+ inorder.verify(mHandler).sendMessageDelayed(
+ argThat(m -> m.what == MSG_TEMP_APP_WHITELIST_TIMEOUT && m.arg1 == testUid),
+ eq(durationMs - 2));
+ assertEquals(startTime + durationMs,
+ mDeviceIdleController.mTempWhitelistAppIdEndTimes.get(testUid).first.value);
+
+ mInjector.nowUptime += durationMs;
+ // Uptime moved past the expiration time. Uid should be removed from the temp allowlist.
+ mDeviceIdleController.checkTempAppWhitelistTimeout(testUid);
+ inorder.verify(mHandler, never()).sendMessageDelayed(
+ argThat(m -> m.what == MSG_TEMP_APP_WHITELIST_TIMEOUT && m.arg1 == testUid),
+ anyLong());
+ assertFalse(mDeviceIdleController.mTempWhitelistAppIdEndTimes.contains(testUid));
+ }
+
+ @Test
public void testUpdateInteractivityLocked() {
doReturn(false).when(mPowerManager).isInteractive();
mDeviceIdleController.updateInteractivityLocked();
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index f2acbc3..f40d803 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -45,13 +45,11 @@
import android.os.RecoverySystem;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DeviceConfig;
import android.provider.Settings;
-import android.util.ArraySet;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
@@ -74,11 +72,9 @@
import org.mockito.stubbing.Answer;
import java.lang.reflect.Field;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -250,37 +246,6 @@
}
@Test
- @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
- Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
- public void testBootLoop() {
- // this is old test where the flag needs to be disabled
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
- HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
-
- noteBoot(1);
-
- // Record DeviceConfig accesses
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
- DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2);
-
- final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
-
- noteBoot(2);
- noteBoot(3);
-
- noteBoot(4);
- assertTrue(RescueParty.isRebootPropertySet());
-
- setCrashRecoveryPropAttemptingReboot(false);
- noteBoot(5);
- assertTrue(RescueParty.isFactoryResetPropertySet());
- }
- @Test
@EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testBootLoopNoFlags() {
// this is old test where the flag needs to be disabled
@@ -293,61 +258,6 @@
}
@Test
- @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testBootLoopRecoverability() {
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
- HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
-
- // Record DeviceConfig accesses
- DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2);
-
- final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
-
-
- noteBoot(1);
-
- noteBoot(2);
- assertTrue(RescueParty.isRebootPropertySet());
-
- noteBoot(3);
-
- verifyOnlySettingsReset(Settings.RESET_MODE_UNTRUSTED_DEFAULTS);
-
- noteBoot(4);
- verifyOnlySettingsReset(Settings.RESET_MODE_UNTRUSTED_CHANGES);
-
- noteBoot(5);
- verifyOnlySettingsReset(Settings.RESET_MODE_TRUSTED_DEFAULTS);
-
- setCrashRecoveryPropAttemptingReboot(false);
- noteBoot(6);
- assertTrue(RescueParty.isFactoryResetPropertySet());
- }
-
- @Test
- @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
- Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
- public void testPersistentAppCrash() {
- // this is old test where the flag needs to be disabled
- noteAppCrash(1, true);
- noteAppCrash(2, true);
- noteAppCrash(3, true);
-
- noteAppCrash(4, true);
- assertTrue(RescueParty.isRebootPropertySet());
-
- setCrashRecoveryPropAttemptingReboot(false);
- noteAppCrash(5, true);
- assertTrue(RescueParty.isFactoryResetPropertySet());
- }
-
- @Test
@EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testPersistentAppCrashNoFlags() {
// this is old test where the flag needs to be disabled
@@ -360,98 +270,6 @@
}
@Test
- @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testPersistentAppCrashRecoverability() {
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
- HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
-
- // Record DeviceConfig accesses
- DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
- monitorCallback.onDeviceConfigAccess(PERSISTENT_PACKAGE, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2);
-
- final String[] expectedResetNamespaces = new String[]{NAMESPACE1};
- final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
-
- noteAppCrash(1, true);
-
- noteAppCrash(2, true);
-
- noteAppCrash(3, true);
- assertTrue(RescueParty.isRebootPropertySet());
-
- noteAppCrash(4, true);
- verifyOnlySettingsReset(Settings.RESET_MODE_UNTRUSTED_DEFAULTS);
-
- noteAppCrash(5, true);
- verifyOnlySettingsReset(Settings.RESET_MODE_UNTRUSTED_CHANGES);
-
- noteAppCrash(6, true);
- verifyOnlySettingsReset(Settings.RESET_MODE_TRUSTED_DEFAULTS);
-
- setCrashRecoveryPropAttemptingReboot(false);
- noteAppCrash(7, true);
- assertTrue(RescueParty.isFactoryResetPropertySet());
- }
-
- @Test
- @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
- Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
- public void testNonPersistentApp() {
- // this is old test where the flag needs to be disabled
- noteAppCrash(1, false);
- noteAppCrash(2, false);
- noteAppCrash(3, false);
- assertFalse(RescueParty.isRebootPropertySet());
-
- noteAppCrash(5, false);
- assertFalse(RescueParty.isFactoryResetPropertySet());
- }
-
- @Test
- @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testNonPersistentAppOnlyPerformsFlagResetsRecoverabilityDetection() {
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
- HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>();
-
- // Record DeviceConfig accesses
- DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
- monitorCallback.onDeviceConfigAccess(NON_PERSISTENT_PACKAGE, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2);
-
- final String[] expectedResetNamespaces = new String[]{NAMESPACE1};
- final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2};
-
- noteAppCrash(1, false);
-
- noteAppCrash(2, false);
-
- noteAppCrash(3, false);
- assertFalse(RescueParty.isRebootPropertySet());
-
- noteAppCrash(4, false);
- verifyNoSettingsReset(Settings.RESET_MODE_UNTRUSTED_DEFAULTS);
- noteAppCrash(5, false);
- verifyNoSettingsReset(Settings.RESET_MODE_UNTRUSTED_CHANGES);
- noteAppCrash(6, false);
- verifyNoSettingsReset(Settings.RESET_MODE_TRUSTED_DEFAULTS);
-
- setCrashRecoveryPropAttemptingReboot(false);
- noteAppCrash(7, false);
- assertFalse(RescueParty.isFactoryResetPropertySet());
- }
-
- @Test
public void testIsRecoveryTriggeredReboot() {
for (int i = 0; i < LEVEL_FACTORY_RESET; i++) {
noteBoot(i + 1);
@@ -522,6 +340,7 @@
@Test
public void testNotThrottlingAfterTimeoutOnAppCrash() {
+ when(mMockContext.getPackageManager()).thenReturn(mPackageManager);
setCrashRecoveryPropAttemptingReboot(false);
long now = System.currentTimeMillis();
long afterTimeout = now - TimeUnit.MINUTES.toMillis(
@@ -534,30 +353,15 @@
}
@Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testNativeRescuePartyResets() {
- doReturn(true).when(() -> SettingsToPropertiesMapper.isNativeFlagsResetPerformed());
- doReturn(FAKE_RESET_NATIVE_NAMESPACES).when(
- () -> SettingsToPropertiesMapper.getResetNativeCategories());
-
- RescueParty.onSettingsProviderPublished(mMockContext);
-
- verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
- FAKE_NATIVE_NAMESPACE1));
- verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
- FAKE_NATIVE_NAMESPACE2));
- }
-
- @Test
public void testExplicitlyEnablingAndDisablingRescue() {
SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false));
SystemProperties.set(PROP_DISABLE_RESCUE, Boolean.toString(true));
- assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false);
+ assertEquals(RescuePartyObserver.getInstance(mMockContext).onExecuteHealthCheckMitigation(
+ sFailingPackage, PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false);
SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true));
- assertTrue(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1));
+ assertTrue(RescuePartyObserver.getInstance(mMockContext).onExecuteHealthCheckMitigation(
+ sFailingPackage, PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1));
}
@Test
@@ -565,8 +369,8 @@
SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false));
SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(true));
- assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false);
+ assertEquals(RescuePartyObserver.getInstance(mMockContext).onExecuteHealthCheckMitigation(
+ sFailingPackage, PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false);
// Restore the property value initialized in SetUp()
SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true));
@@ -587,75 +391,6 @@
}
@Test
- @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
- Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
- public void testHealthCheckLevels() {
- // this is old test where the flag needs to be disabled
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
-
- // Ensure that no action is taken for cases where the failure reason is unknown
- assertEquals(observer.onHealthCheckFailed(null, PackageWatchdog.FAILURE_REASON_UNKNOWN, 1),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_0);
-
- // Ensure the correct user impact is returned for each mitigation count.
- assertEquals(observer.onHealthCheckFailed(null,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_10);
-
- assertEquals(observer.onHealthCheckFailed(null,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_10);
-
- assertEquals(observer.onHealthCheckFailed(null,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_50);
-
- assertEquals(observer.onHealthCheckFailed(null,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_50);
- }
-
- @Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
- public void testHealthCheckLevelsRecoverabilityDetection() {
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
-
- // Ensure that no action is taken for cases where the failure reason is unknown
- assertEquals(observer.onHealthCheckFailed(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_UNKNOWN, 1),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_0);
-
- // Ensure the correct user impact is returned for each mitigation count.
- assertEquals(observer.onHealthCheckFailed(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_10);
-
- assertEquals(observer.onHealthCheckFailed(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
-
- assertEquals(observer.onHealthCheckFailed(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 3),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
-
- assertEquals(observer.onHealthCheckFailed(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 4),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
-
- assertEquals(observer.onHealthCheckFailed(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 5),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
-
- assertEquals(observer.onHealthCheckFailed(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 6),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
-
- assertEquals(observer.onHealthCheckFailed(sFailingPackage,
- PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 7),
- PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
- }
- @Test
@EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
public void testHealthCheckLevelsNoFlags() {
// this is old test where the flag needs to be disabled
@@ -674,36 +409,6 @@
PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 2),
PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
}
- @Test
- @DisableFlags({Flags.FLAG_RECOVERABILITY_DETECTION,
- Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS})
- public void testBootLoopLevels() {
- // this is old test where the flag needs to be disabled
-
-
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
-
- assertEquals(observer.onBootLoop(0), PackageHealthObserverImpact.USER_IMPACT_LEVEL_0);
- assertEquals(observer.onBootLoop(1), PackageHealthObserverImpact.USER_IMPACT_LEVEL_10);
- assertEquals(observer.onBootLoop(2), PackageHealthObserverImpact.USER_IMPACT_LEVEL_10);
- assertEquals(observer.onBootLoop(3), PackageHealthObserverImpact.USER_IMPACT_LEVEL_50);
- assertEquals(observer.onBootLoop(4), PackageHealthObserverImpact.USER_IMPACT_LEVEL_50);
- assertEquals(observer.onBootLoop(5), PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
- }
-
- @Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- @EnableFlags(Flags.FLAG_RECOVERABILITY_DETECTION)
- public void testBootLoopLevelsRecoverabilityDetection() {
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
-
- assertEquals(observer.onBootLoop(1), PackageHealthObserverImpact.USER_IMPACT_LEVEL_40);
- assertEquals(observer.onBootLoop(2), PackageHealthObserverImpact.USER_IMPACT_LEVEL_50);
- assertEquals(observer.onBootLoop(3), PackageHealthObserverImpact.USER_IMPACT_LEVEL_71);
- assertEquals(observer.onBootLoop(4), PackageHealthObserverImpact.USER_IMPACT_LEVEL_75);
- assertEquals(observer.onBootLoop(5), PackageHealthObserverImpact.USER_IMPACT_LEVEL_80);
- assertEquals(observer.onBootLoop(6), PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
- }
@Test
@EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
@@ -714,129 +419,6 @@
assertEquals(observer.onBootLoop(2), PackageHealthObserverImpact.USER_IMPACT_LEVEL_100);
}
- @Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testResetDeviceConfigForPackagesOnlyRuntimeMap() {
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
-
- // Record DeviceConfig accesses
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
- DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE2);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3);
- // Fake DeviceConfig value changes
- monitorCallback.onNamespaceUpdate(NAMESPACE1);
- monitorCallback.onNamespaceUpdate(NAMESPACE2);
- monitorCallback.onNamespaceUpdate(NAMESPACE3);
-
- doReturn("").when(() -> DeviceConfig.getString(
- eq(RescueParty.NAMESPACE_CONFIGURATION),
- eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG),
- eq("")));
-
- RescueParty.resetDeviceConfigForPackages(Arrays.asList(new String[]{CALLING_PACKAGE1}));
- ArraySet<String> expectedNamespacesWiped = new ArraySet<String>(
- Arrays.asList(new String[]{NAMESPACE1, NAMESPACE2}));
- assertEquals(mNamespacesWiped, expectedNamespacesWiped);
- }
-
- @Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testResetDeviceConfigForPackagesOnlyPresetMap() {
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
-
- String presetMapping = NAMESPACE1 + ":" + CALLING_PACKAGE1 + ","
- + NAMESPACE2 + ":" + CALLING_PACKAGE2 + ","
- + NAMESPACE3 + ":" + CALLING_PACKAGE1;
- doReturn(presetMapping).when(() -> DeviceConfig.getString(
- eq(RescueParty.NAMESPACE_CONFIGURATION),
- eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG),
- eq("")));
-
- RescueParty.resetDeviceConfigForPackages(Arrays.asList(new String[]{CALLING_PACKAGE1}));
- ArraySet<String> expectedNamespacesWiped = new ArraySet<String>(
- Arrays.asList(new String[]{NAMESPACE1, NAMESPACE3}));
- assertEquals(mNamespacesWiped, expectedNamespacesWiped);
- }
-
- @Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testResetDeviceConfigForPackagesBothMaps() {
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
-
- // Record DeviceConfig accesses
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
- DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE2);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE2);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE3, NAMESPACE4);
- // Fake DeviceConfig value changes
- monitorCallback.onNamespaceUpdate(NAMESPACE1);
- monitorCallback.onNamespaceUpdate(NAMESPACE2);
- monitorCallback.onNamespaceUpdate(NAMESPACE3);
- monitorCallback.onNamespaceUpdate(NAMESPACE4);
-
- String presetMapping = NAMESPACE1 + ":" + CALLING_PACKAGE1 + ","
- + NAMESPACE2 + ":" + CALLING_PACKAGE2 + ","
- + NAMESPACE4 + ":" + CALLING_PACKAGE3;
- doReturn(presetMapping).when(() -> DeviceConfig.getString(
- eq(RescueParty.NAMESPACE_CONFIGURATION),
- eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG),
- eq("")));
-
- RescueParty.resetDeviceConfigForPackages(
- Arrays.asList(new String[]{CALLING_PACKAGE1, CALLING_PACKAGE2}));
- ArraySet<String> expectedNamespacesWiped = new ArraySet<String>(
- Arrays.asList(new String[]{NAMESPACE1, NAMESPACE2, NAMESPACE3}));
- assertEquals(mNamespacesWiped, expectedNamespacesWiped);
- }
-
- @Test
- @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
- public void testResetDeviceConfigNoExceptionWhenFlagMalformed() {
- RescueParty.onSettingsProviderPublished(mMockContext);
- verify(() -> DeviceConfig.setMonitorCallback(eq(mMockContentResolver),
- any(Executor.class),
- mMonitorCallbackCaptor.capture()));
-
- // Record DeviceConfig accesses
- RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);
- DeviceConfig.MonitorCallback monitorCallback = mMonitorCallbackCaptor.getValue();
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE1, NAMESPACE1);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE2, NAMESPACE3);
- monitorCallback.onDeviceConfigAccess(CALLING_PACKAGE3, NAMESPACE4);
- // Fake DeviceConfig value changes
- monitorCallback.onNamespaceUpdate(NAMESPACE1);
- monitorCallback.onNamespaceUpdate(NAMESPACE2);
- monitorCallback.onNamespaceUpdate(NAMESPACE3);
- monitorCallback.onNamespaceUpdate(NAMESPACE4);
-
- String invalidPresetMapping = NAMESPACE2 + ":" + CALLING_PACKAGE2 + ","
- + NAMESPACE1 + "." + CALLING_PACKAGE2;
- doReturn(invalidPresetMapping).when(() -> DeviceConfig.getString(
- eq(RescueParty.NAMESPACE_CONFIGURATION),
- eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG),
- eq("")));
-
- RescueParty.resetDeviceConfigForPackages(
- Arrays.asList(new String[]{CALLING_PACKAGE1, CALLING_PACKAGE2}));
- ArraySet<String> expectedNamespacesWiped = new ArraySet<String>(
- Arrays.asList(new String[]{NAMESPACE1, NAMESPACE3}));
- assertEquals(mNamespacesWiped, expectedNamespacesWiped);
- }
private void verifySettingsResets(int resetMode, String[] resetNamespaces,
HashMap<String, Integer> configResetVerifiedTimesMap) {
@@ -858,13 +440,14 @@
}
private void noteBoot(int mitigationCount) {
- RescuePartyObserver.getInstance(mMockContext).executeBootLoopMitigation(mitigationCount);
+ RescuePartyObserver.getInstance(mMockContext).onExecuteBootLoopMitigation(mitigationCount);
}
private void noteAppCrash(int mitigationCount, boolean isPersistent) {
String packageName = isPersistent ? PERSISTENT_PACKAGE : NON_PERSISTENT_PACKAGE;
- RescuePartyObserver.getInstance(mMockContext).execute(new VersionedPackage(
- packageName, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH, mitigationCount);
+ RescuePartyObserver.getInstance(mMockContext).onExecuteHealthCheckMitigation(
+ new VersionedPackage(packageName, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH,
+ mitigationCount);
}
// Mock CrashRecoveryProperties as they cannot be accessed due to SEPolicy restrictions
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsLegacyRestrictionsTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsLegacyRestrictionsTest.java
index 1973428..f7c2e8b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsLegacyRestrictionsTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsLegacyRestrictionsTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertEquals;
+import android.app.PropertyInvalidatedCache;
import android.content.Context;
import android.os.Handler;
@@ -63,6 +64,7 @@
@Before
public void setUp() {
+ PropertyInvalidatedCache.disableForTestMode();
mSession = ExtendedMockito.mockitoSession()
.initMocks(this)
.strictness(Strictness.LENIENT)
diff --git a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
index 7ac7aca..1f88c29 100644
--- a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
+++ b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp
@@ -36,7 +36,10 @@
"services.core",
"truth",
"flag-junit",
- ],
+ ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), {
+ "true": ["service-crashrecovery.impl"],
+ default: [],
+ }),
libs: [
"android.test.mock.stubs.system",
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index 4e1f741..dd7ce21 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -2351,6 +2351,7 @@
/** Tests that jobs are removed from the pending list if the user stops the app. */
@Test
+ @RequiresFlagsDisabled(android.app.job.Flags.FLAG_GET_PENDING_JOB_REASONS_API)
public void testUserStopRemovesPending() {
spyOn(mService);
@@ -2402,6 +2403,60 @@
assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReason(job2b));
}
+ /** Tests that jobs are removed from the pending list if the user stops the app. */
+ @Test
+ @RequiresFlagsEnabled(android.app.job.Flags.FLAG_GET_PENDING_JOB_REASONS_API)
+ public void testUserStopRemovesPending_withPendingJobReasonsApi() {
+ spyOn(mService);
+
+ JobStatus job1a = createJobStatus("testUserStopRemovesPending",
+ createJobInfo(1), 1, "pkg1");
+ JobStatus job1b = createJobStatus("testUserStopRemovesPending",
+ createJobInfo(2), 1, "pkg1");
+ JobStatus job2a = createJobStatus("testUserStopRemovesPending",
+ createJobInfo(1), 2, "pkg2");
+ JobStatus job2b = createJobStatus("testUserStopRemovesPending",
+ createJobInfo(2), 2, "pkg2");
+ doReturn(1).when(mPackageManagerInternal).getPackageUid("pkg1", 0, 0);
+ doReturn(11).when(mPackageManagerInternal).getPackageUid("pkg1", 0, 1);
+ doReturn(2).when(mPackageManagerInternal).getPackageUid("pkg2", 0, 0);
+
+ mService.getPendingJobQueue().clear();
+ mService.getPendingJobQueue().add(job1a);
+ mService.getPendingJobQueue().add(job1b);
+ mService.getPendingJobQueue().add(job2a);
+ mService.getPendingJobQueue().add(job2b);
+ mService.getJobStore().add(job1a);
+ mService.getJobStore().add(job1b);
+ mService.getJobStore().add(job2a);
+ mService.getJobStore().add(job2b);
+
+ mService.notePendingUserRequestedAppStopInternal("pkg1", 1, "test");
+ assertEquals(4, mService.getPendingJobQueue().size());
+ assertTrue(mService.getPendingJobQueue().contains(job1a));
+ assertTrue(mService.getPendingJobQueue().contains(job1b));
+ assertTrue(mService.getPendingJobQueue().contains(job2a));
+ assertTrue(mService.getPendingJobQueue().contains(job2b));
+
+ mService.notePendingUserRequestedAppStopInternal("pkg1", 0, "test");
+ assertEquals(2, mService.getPendingJobQueue().size());
+ assertFalse(mService.getPendingJobQueue().contains(job1a));
+ assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReasons(job1a)[0]);
+ assertFalse(mService.getPendingJobQueue().contains(job1b));
+ assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReasons(job1b)[0]);
+ assertTrue(mService.getPendingJobQueue().contains(job2a));
+ assertTrue(mService.getPendingJobQueue().contains(job2b));
+
+ mService.notePendingUserRequestedAppStopInternal("pkg2", 0, "test");
+ assertEquals(0, mService.getPendingJobQueue().size());
+ assertFalse(mService.getPendingJobQueue().contains(job1a));
+ assertFalse(mService.getPendingJobQueue().contains(job1b));
+ assertFalse(mService.getPendingJobQueue().contains(job2a));
+ assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReasons(job2a)[0]);
+ assertFalse(mService.getPendingJobQueue().contains(job2b));
+ assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReasons(job2b)[0]);
+ }
+
/**
* Unit tests {@link JobSchedulerService#checkIfRestricted(JobStatus)} with single {@link
* JobRestriction} registered.
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 1cba3c5..8a10040 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -195,12 +195,12 @@
doNothing().when(mSpiedContext).sendBroadcastAsUser(any(), any(), any());
mockIsLowRamDevice(false);
- // Called when getting boot user. config_bootToHeadlessSystemUser is false by default.
+ // Called when getting boot user. config_bootToHeadlessSystemUser is 0 by default.
mSpyResources = spy(mSpiedContext.getResources());
when(mSpiedContext.getResources()).thenReturn(mSpyResources);
- doReturn(false)
+ doReturn(0)
.when(mSpyResources)
- .getBoolean(com.android.internal.R.bool.config_bootToHeadlessSystemUser);
+ .getInteger(com.android.internal.R.integer.config_hsumBootStrategy);
// Must construct UserManagerService in the UiThread
mTestDir = new File(mRealContext.getDataDir(), "umstest");
@@ -859,15 +859,50 @@
}
@Test
- public void testGetBootUser_enableBootToHeadlessSystemUser() {
+ public void testGetBootUser_Headless_BootToSystemUserWhenDeviceIsProvisioned() {
setSystemUserHeadless(true);
- doReturn(true)
+ addUser(USER_ID);
+ addUser(OTHER_USER_ID);
+ mockProvisionedDevice(true);
+ doReturn(1)
.when(mSpyResources)
- .getBoolean(com.android.internal.R.bool.config_bootToHeadlessSystemUser);
+ .getInteger(com.android.internal.R.integer.config_hsumBootStrategy);
assertThat(mUms.getBootUser()).isEqualTo(UserHandle.USER_SYSTEM);
}
+ @Test
+ public void testGetBootUser_Headless_BootToFirstSwitchableFullUserWhenDeviceNotProvisioned() {
+ setSystemUserHeadless(true);
+ addUser(USER_ID);
+ addUser(OTHER_USER_ID);
+ mockProvisionedDevice(false);
+ doReturn(1)
+ .when(mSpyResources)
+ .getInteger(com.android.internal.R.integer.config_hsumBootStrategy);
+ // Even if the headless system user switchable flag is true, the boot user should be the
+ // first switchable full user.
+ doReturn(true)
+ .when(mSpyResources)
+ .getBoolean(com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser);
+
+ assertThat(mUms.getBootUser()).isEqualTo(USER_ID);
+ }
+
+ @Test
+ public void testGetBootUser_Headless_ThrowsIfBootFailsNoFullUserWhenDeviceNotProvisioned()
+ throws Exception {
+ setSystemUserHeadless(true);
+ removeNonSystemUsers();
+ mockProvisionedDevice(false);
+ doReturn(1)
+ .when(mSpyResources)
+ .getInteger(com.android.internal.R.integer.config_hsumBootStrategy);
+
+ assertThrows(ServiceSpecificException.class,
+ () -> mUms.getBootUser());
+ }
+
/**
* Returns true if the user's XML file has Default restrictions
* @param userId Id of the user.
@@ -935,6 +970,11 @@
any(), eq(android.provider.Settings.Global.USER_SWITCHER_ENABLED), anyInt()));
}
+ private void mockProvisionedDevice(boolean isProvisionedDevice) {
+ doReturn(isProvisionedDevice ? 1 : 0).when(() -> Settings.Global.getInt(
+ any(), eq(android.provider.Settings.Global.DEVICE_PROVISIONED), anyInt()));
+ }
+
private void mockIsLowRamDevice(boolean isLowRamDevice) {
doReturn(isLowRamDevice).when(ActivityManager::isLowRamDeviceStatic);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
index 677ecf4..2f23e02 100644
--- a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp
@@ -34,7 +34,10 @@
"services.core",
"truth",
"flag-junit",
- ],
+ ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), {
+ "true": ["service-crashrecovery.impl"],
+ default: [],
+ }),
libs: [
"android.test.mock.stubs.system",
diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java b/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java
index e0c7bfe..347dc81 100644
--- a/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/rollback/RollbackPackageHealthObserverTest.java
@@ -109,14 +109,11 @@
private static final String PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG =
"persist.device_config.configuration.disable_high_impact_rollback";
- private SystemConfig mSysConfig;
@Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
@Before
public void setup() {
- mSysConfig = new SystemConfigTestClass();
-
mSession = ExtendedMockito.mockitoSession()
.initMocks(this)
.strictness(Strictness.LENIENT)
@@ -184,7 +181,7 @@
@Test
public void testHealthCheckLevels() {
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
VersionedPackage testFailedPackage = new VersionedPackage(APP_A, VERSION_CODE);
VersionedPackage secondFailedPackage = new VersionedPackage(APP_B, VERSION_CODE);
@@ -228,14 +225,14 @@
@Test
public void testIsPersistent() {
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
assertTrue(observer.isPersistent());
}
@Test
public void testMayObservePackage_withoutAnyRollback() {
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of());
assertFalse(observer.mayObservePackage(APP_A));
@@ -245,7 +242,7 @@
public void testMayObservePackage_forPersistentApp()
throws PackageManager.NameNotFoundException {
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ApplicationInfo info = new ApplicationInfo();
info.flags = ApplicationInfo.FLAG_PERSISTENT | ApplicationInfo.FLAG_SYSTEM;
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -260,7 +257,7 @@
public void testMayObservePackage_forNonPersistentApp()
throws PackageManager.NameNotFoundException {
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(mRollbackInfo));
when(mRollbackInfo.getPackages()).thenReturn(List.of(mPackageRollbackInfo));
@@ -286,7 +283,7 @@
false, null, 111,
PackageManager.ROLLBACK_USER_IMPACT_LOW);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
VersionedPackage secondFailedPackage = new VersionedPackage(APP_B, VERSION_CODE);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -317,7 +314,7 @@
false, null, 111,
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
VersionedPackage secondFailedPackage = new VersionedPackage(APP_B, VERSION_CODE);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -348,7 +345,7 @@
false, null, 111,
PackageManager.ROLLBACK_USER_IMPACT_ONLY_MANUAL);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
VersionedPackage secondFailedPackage = new VersionedPackage(APP_B, VERSION_CODE);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -386,7 +383,7 @@
false, null, 222,
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
VersionedPackage failedPackage = new VersionedPackage(APP_C, VERSION_CODE);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -419,7 +416,7 @@
PackageManager.ROLLBACK_USER_IMPACT_LOW);
VersionedPackage secondFailedPackage = new VersionedPackage(APP_B, VERSION_CODE);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
// Make the rollbacks available
@@ -427,7 +424,7 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.execute(secondFailedPackage,
+ observer.onExecuteHealthCheckMitigation(secondFailedPackage,
PackageWatchdog.FAILURE_REASON_NATIVE_CRASH, 1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
@@ -461,7 +458,7 @@
false, null, 222,
PackageManager.ROLLBACK_USER_IMPACT_LOW);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -471,7 +468,8 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.execute(appBFrom, PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ observer.onExecuteHealthCheckMitigation(appBFrom, PackageWatchdog.FAILURE_REASON_APP_CRASH,
+ 1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager).commitRollback(argument.capture(), any(), any());
@@ -506,7 +504,7 @@
PackageManager.ROLLBACK_USER_IMPACT_LOW);
VersionedPackage failedPackage = new VersionedPackage(APP_C, VERSION_CODE);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -516,7 +514,8 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.execute(failedPackage, PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ observer.onExecuteHealthCheckMitigation(failedPackage,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, times(2)).commitRollback(
@@ -552,7 +551,7 @@
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
VersionedPackage failedPackage = new VersionedPackage(APP_C, VERSION_CODE);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -562,7 +561,8 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.execute(failedPackage, PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ observer.onExecuteHealthCheckMitigation(failedPackage,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, times(1)).commitRollback(
@@ -590,7 +590,7 @@
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
VersionedPackage failedPackage = new VersionedPackage(APP_C, VERSION_CODE);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -599,7 +599,8 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.execute(failedPackage, PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ observer.onExecuteHealthCheckMitigation(failedPackage,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, never()).commitRollback(argument.capture(), any(), any());
@@ -621,7 +622,7 @@
false, null, 111,
PackageManager.ROLLBACK_USER_IMPACT_LOW);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
// Make the rollbacks available
@@ -646,7 +647,7 @@
false, null, 111,
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
// Make the rollbacks available
@@ -672,7 +673,7 @@
false, null, 111,
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
// Make the rollbacks available
@@ -701,7 +702,7 @@
false, null, 111,
PackageManager.ROLLBACK_USER_IMPACT_ONLY_MANUAL);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
// Make the rollbacks available
@@ -737,7 +738,7 @@
false, null, 222,
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
// Make the rollbacks available
@@ -776,7 +777,7 @@
false, null, 222,
PackageManager.ROLLBACK_USER_IMPACT_LOW);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -786,7 +787,7 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.executeBootLoopMitigation(1);
+ observer.onExecuteBootLoopMitigation(1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, times(2)).commitRollback(
@@ -821,7 +822,7 @@
false, null, 222,
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -831,7 +832,7 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.executeBootLoopMitigation(1);
+ observer.onExecuteBootLoopMitigation(1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, times(1)).commitRollback(
@@ -857,7 +858,7 @@
false, null, 111,
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -866,7 +867,7 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.executeBootLoopMitigation(1);
+ observer.onExecuteBootLoopMitigation(1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, times(1)).commitRollback(
@@ -902,7 +903,7 @@
PackageManager.ROLLBACK_USER_IMPACT_ONLY_MANUAL);
VersionedPackage failedPackage = new VersionedPackage(APP_C, VERSION_CODE);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -912,7 +913,8 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.execute(failedPackage, PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ observer.onExecuteHealthCheckMitigation(failedPackage,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, times(1)).commitRollback(
@@ -938,7 +940,7 @@
PackageManager.ROLLBACK_USER_IMPACT_ONLY_MANUAL);
VersionedPackage failedPackage = new VersionedPackage(APP_C, VERSION_CODE);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -947,7 +949,8 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.execute(failedPackage, PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ observer.onExecuteHealthCheckMitigation(failedPackage,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, never()).commitRollback(argument.capture(), any(), any());
@@ -980,7 +983,7 @@
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
VersionedPackage failedPackage = new VersionedPackage(APP_C, VERSION_CODE);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -990,7 +993,7 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.executeBootLoopMitigation(1);
+ observer.onExecuteBootLoopMitigation(1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, times(1)).commitRollback(
@@ -1026,7 +1029,7 @@
false, null, 111,
PackageManager.ROLLBACK_USER_IMPACT_HIGH);
RollbackPackageHealthObserver observer =
- spy(new RollbackPackageHealthObserver(mMockContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mMockContext));
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
when(mMockContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
@@ -1036,7 +1039,7 @@
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getModuleInfo(any(), eq(0))).thenReturn(null);
- observer.executeBootLoopMitigation(1);
+ observer.onExecuteBootLoopMitigation(1);
waitForIdleHandler(observer.getHandler(), Duration.ofSeconds(10));
verify(mRollbackManager, never()).commitRollback(
diff --git a/services/tests/powerservicetests/Android.bp b/services/tests/powerservicetests/Android.bp
index f03043e..2f06331 100644
--- a/services/tests/powerservicetests/Android.bp
+++ b/services/tests/powerservicetests/Android.bp
@@ -12,6 +12,7 @@
],
static_libs: [
+ "truth",
"flag-junit",
"frameworks-base-testutils",
"platform-compat-test-rules",
diff --git a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
index 1c7fc63..96741e0 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
@@ -19,13 +19,17 @@
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
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.atLeast;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -42,6 +46,7 @@
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.display.DisplayManagerInternal;
import android.os.BatteryStats;
+import android.os.BatteryStatsInternal;
import android.os.Handler;
import android.os.IWakeLockCallback;
import android.os.Looper;
@@ -50,6 +55,7 @@
import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.os.WorkSource;
+import android.os.WorkSource.WorkChain;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.testing.TestableContext;
@@ -67,12 +73,15 @@
import com.android.server.input.InputManagerInternal;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.power.FrameworkStatsLogger.WakelockEventType;
import com.android.server.power.batterysaver.BatterySaverStateMachine;
import com.android.server.power.feature.PowerManagerFlags;
import com.android.server.statusbar.StatusBarManagerInternal;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -87,6 +96,14 @@
private static final int DISPLAY_PORT = 0xFF;
private static final long DISPLAY_MODEL = 0xEEEEEEEEL;
+ private static final int UID = 1234;
+ private static final int OWNER_UID = 1235;
+ private static final int WORK_SOURCE_UID_1 = 2345;
+ private static final int WORK_SOURCE_UID_2 = 2346;
+ private static final int OWNER_WORK_SOURCE_UID_1 = 3456;
+ private static final int OWNER_WORK_SOURCE_UID_2 = 3457;
+ private static final int PID = 5678;
+
@Mock private BatterySaverStateMachine mBatterySaverStateMachineMock;
@Mock private PowerManagerService.NativeWrapper mNativeWrapperMock;
@Mock private Notifier mNotifierMock;
@@ -110,13 +127,15 @@
@Mock private AppOpsManager mAppOpsManager;
+ @Mock private BatteryStatsInternal mBatteryStatsInternal;
+ @Mock private FrameworkStatsLogger mLogger;
+
private PowerManagerService mService;
private Context mContextSpy;
private Resources mResourcesSpy;
private TestLooper mTestLooper = new TestLooper();
private FakeExecutor mTestExecutor = new FakeExecutor();
private Notifier mNotifier;
-
private DisplayInfo mDefaultDisplayInfo = new DisplayInfo();
@Before
@@ -411,6 +430,246 @@
}
@Test
+ public void testOnWakeLockReleased_FrameworkStatsLogged_NoChains() {
+ when(mPowerManagerFlags.isMoveWscLoggingToNotifierEnabled()).thenReturn(true);
+ createNotifier();
+
+ clearInvocations(mLogger, mWakeLockLog, mBatteryStats, mAppOpsManager);
+
+ when(mBatteryStatsInternal.getOwnerUid(UID)).thenReturn(OWNER_UID);
+ when(mBatteryStatsInternal.getOwnerUid(WORK_SOURCE_UID_1))
+ .thenReturn(OWNER_WORK_SOURCE_UID_1);
+
+ mNotifier.onWakeLockAcquired(
+ PowerManager.PARTIAL_WAKE_LOCK,
+ "wakelockTag",
+ "my.package.name",
+ UID,
+ PID,
+ /* workSource= */ null,
+ /* historyTag= */ null,
+ /* callback= */ null);
+
+ WorkSource ws = new WorkSource(WORK_SOURCE_UID_1);
+
+ mNotifier.onWakeLockChanging(
+ /* existing WakeLock params */
+ PowerManager.PARTIAL_WAKE_LOCK,
+ "wakelockTag",
+ "my.package.name",
+ UID,
+ PID,
+ /* workSource= */ null,
+ /* historyTag= */ null,
+ /* callback= */ null,
+ /* updated WakeLock params */
+ PowerManager.PARTIAL_WAKE_LOCK,
+ "wakelockTag",
+ "my.package.name",
+ UID,
+ PID,
+ ws,
+ /* historyTag= */ null,
+ /* callback= */ null);
+
+ mNotifier.onWakeLockReleased(
+ PowerManager.PARTIAL_WAKE_LOCK,
+ "wakelockTag",
+ "my.package.name",
+ UID,
+ PID,
+ ws,
+ /* historyTag= */ null,
+ /* callback= */ null);
+
+ verify(mBatteryStatsInternal, atLeast(1)).getOwnerUid(eq(UID));
+ verify(mBatteryStatsInternal, atLeast(1)).getOwnerUid(eq(WORK_SOURCE_UID_1));
+
+ // ACQUIRE before RELEASE
+ InOrder inOrder1 = inOrder(mLogger);
+ inOrder1.verify(mLogger)
+ .wakelockStateChanged(
+ eq(OWNER_UID),
+ eq("wakelockTag"),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.ACQUIRE));
+ inOrder1.verify(mLogger)
+ .wakelockStateChanged(
+ eq(OWNER_UID),
+ eq("wakelockTag"),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.RELEASE));
+
+ InOrder inOrder2 = inOrder(mLogger);
+ inOrder2.verify(mLogger)
+ .wakelockStateChanged(
+ eq(OWNER_WORK_SOURCE_UID_1),
+ eq("wakelockTag"),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.ACQUIRE));
+ inOrder2.verify(mLogger)
+ .wakelockStateChanged(
+ eq(OWNER_WORK_SOURCE_UID_1),
+ eq("wakelockTag"),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.RELEASE));
+ }
+
+ @Test
+ public void testOnWakeLockReleased_FrameworkStatsLogged_MultipleWorkSourceUids() {
+ // UIDs stored directly in WorkSource
+ WorkSource ws = new WorkSource(WORK_SOURCE_UID_1);
+ ws.add(WORK_SOURCE_UID_2);
+ testWorkSource(ws);
+
+ InOrder inOrder = inOrder(mLogger);
+ ArgumentCaptor<Integer> captorInt = ArgumentCaptor.forClass(int.class);
+
+ // ACQUIRE
+ inOrder.verify(mLogger, times(2))
+ .wakelockStateChanged(
+ /* uid= */ captorInt.capture(),
+ eq("wakelockTag"),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.ACQUIRE));
+ assertThat(captorInt.getAllValues())
+ .containsExactly(OWNER_WORK_SOURCE_UID_1, OWNER_WORK_SOURCE_UID_2);
+
+ // RELEASE
+ captorInt = ArgumentCaptor.forClass(int.class);
+ inOrder.verify(mLogger, times(2))
+ .wakelockStateChanged(
+ /* uid= */ captorInt.capture(),
+ eq("wakelockTag"),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.RELEASE));
+ assertThat(captorInt.getAllValues())
+ .containsExactly(OWNER_WORK_SOURCE_UID_1, OWNER_WORK_SOURCE_UID_2);
+ }
+
+ @Test
+ public void testOnWakeLockReleased_FrameworkStatsLogged_OneChain() {
+ // UIDs stored in a WorkChain of the WorkSource
+ WorkSource ws = new WorkSource();
+ WorkChain wc = ws.createWorkChain();
+ wc.addNode(WORK_SOURCE_UID_1, "tag1");
+ wc.addNode(WORK_SOURCE_UID_2, "tag2");
+ testWorkSource(ws);
+
+ WorkChain expectedWorkChain = new WorkChain();
+ expectedWorkChain.addNode(OWNER_WORK_SOURCE_UID_1, "tag1");
+ expectedWorkChain.addNode(OWNER_WORK_SOURCE_UID_2, "tag2");
+
+ InOrder inOrder = inOrder(mLogger);
+
+ // ACQUIRE
+ inOrder.verify(mLogger)
+ .wakelockStateChanged(
+ eq("wakelockTag"),
+ eq(expectedWorkChain),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.ACQUIRE));
+ // RELEASE
+ inOrder.verify(mLogger)
+ .wakelockStateChanged(
+ eq("wakelockTag"),
+ eq(expectedWorkChain),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.RELEASE));
+ }
+
+ @Test
+ public void testOnWakeLockReleased_FrameworkStatsLogged_OneUid_OneChain() {
+ WorkSource ws = new WorkSource(WORK_SOURCE_UID_1);
+ WorkChain wc = ws.createWorkChain();
+ wc.addNode(WORK_SOURCE_UID_2, "someTag");
+ testWorkSource(ws);
+
+ WorkChain expectedWorkChain = new WorkChain();
+ expectedWorkChain.addNode(OWNER_WORK_SOURCE_UID_2, "someTag");
+
+ InOrder inOrder1 = inOrder(mLogger);
+ InOrder inOrder2 = inOrder(mLogger);
+
+ // ACQUIRE
+ inOrder1.verify(mLogger)
+ .wakelockStateChanged(
+ eq(OWNER_WORK_SOURCE_UID_1),
+ eq("wakelockTag"),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.ACQUIRE));
+ inOrder2.verify(mLogger)
+ .wakelockStateChanged(
+ eq("wakelockTag"),
+ eq(expectedWorkChain),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.ACQUIRE));
+ // RELEASE
+ inOrder1.verify(mLogger)
+ .wakelockStateChanged(
+ eq(OWNER_WORK_SOURCE_UID_1),
+ eq("wakelockTag"),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.RELEASE));
+ inOrder2.verify(mLogger)
+ .wakelockStateChanged(
+ eq("wakelockTag"),
+ eq(expectedWorkChain),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.RELEASE));
+ }
+
+ @Test
+ public void testOnWakeLockReleased_FrameworkStatsLogged_TwoChains() {
+ // UIDs stored in a WorkChain of the WorkSource
+ WorkSource ws = new WorkSource();
+ WorkChain wc1 = ws.createWorkChain();
+ wc1.addNode(WORK_SOURCE_UID_1, "tag1");
+
+ WorkChain wc2 = ws.createWorkChain();
+ wc2.addNode(WORK_SOURCE_UID_2, "tag2");
+
+ testWorkSource(ws);
+
+ WorkChain expectedWorkChain1 = new WorkChain();
+ expectedWorkChain1.addNode(OWNER_WORK_SOURCE_UID_1, "tag1");
+
+ WorkChain expectedWorkChain2 = new WorkChain();
+ expectedWorkChain2.addNode(OWNER_WORK_SOURCE_UID_2, "tag2");
+
+ InOrder inOrder1 = inOrder(mLogger);
+ InOrder inOrder2 = inOrder(mLogger);
+
+ // ACQUIRE
+ inOrder1.verify(mLogger)
+ .wakelockStateChanged(
+ eq("wakelockTag"),
+ eq(expectedWorkChain1),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.ACQUIRE));
+ inOrder2.verify(mLogger)
+ .wakelockStateChanged(
+ eq("wakelockTag"),
+ eq(expectedWorkChain2),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.ACQUIRE));
+
+ // RELEASE
+ inOrder1.verify(mLogger)
+ .wakelockStateChanged(
+ eq("wakelockTag"),
+ eq(expectedWorkChain1),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.RELEASE));
+ inOrder2.verify(mLogger)
+ .wakelockStateChanged(
+ eq("wakelockTag"),
+ eq(expectedWorkChain2),
+ eq(PowerManager.PARTIAL_WAKE_LOCK),
+ eq(WakelockEventType.RELEASE));
+ }
+
+ @Test
public void testOnWakeLockListener_RemoteException_NoRethrow() throws RemoteException {
when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true);
createNotifier();
@@ -708,22 +967,33 @@
}
private void createNotifier() {
- Notifier.Injector injector = new Notifier.Injector() {
- @Override
- public long currentTimeMillis() {
- return 1;
- }
+ Notifier.Injector injector =
+ new Notifier.Injector() {
+ @Override
+ public long currentTimeMillis() {
+ return 1;
+ }
- @Override
- public WakeLockLog getWakeLockLog(Context context) {
- return mWakeLockLog;
- }
+ @Override
+ public WakeLockLog getWakeLockLog(Context context) {
+ return mWakeLockLog;
+ }
- @Override
- public AppOpsManager getAppOpsManager(Context context) {
- return mAppOpsManager;
- }
- };
+ @Override
+ public AppOpsManager getAppOpsManager(Context context) {
+ return mAppOpsManager;
+ }
+
+ @Override
+ public FrameworkStatsLogger getFrameworkStatsLogger() {
+ return mLogger;
+ }
+
+ @Override
+ public BatteryStatsInternal getBatteryStatsInternal() {
+ return mBatteryStatsInternal;
+ }
+ };
mNotifier = new Notifier(
mTestLooper.getLooper(),
@@ -760,4 +1030,38 @@
}
}
+ private void testWorkSource(WorkSource ws) {
+ when(mPowerManagerFlags.isMoveWscLoggingToNotifierEnabled()).thenReturn(true);
+ createNotifier();
+ clearInvocations(
+ mBatteryStatsInternal, mLogger, mWakeLockLog, mBatteryStats, mAppOpsManager);
+
+ when(mBatteryStatsInternal.getOwnerUid(WORK_SOURCE_UID_1))
+ .thenReturn(OWNER_WORK_SOURCE_UID_1);
+ when(mBatteryStatsInternal.getOwnerUid(WORK_SOURCE_UID_2))
+ .thenReturn(OWNER_WORK_SOURCE_UID_2);
+
+ mNotifier.onWakeLockAcquired(
+ PowerManager.PARTIAL_WAKE_LOCK,
+ "wakelockTag",
+ "my.package.name",
+ UID,
+ PID,
+ ws,
+ /* historyTag= */ null,
+ /* callback= */ null);
+
+ mNotifier.onWakeLockReleased(
+ PowerManager.PARTIAL_WAKE_LOCK,
+ "wakelockTag",
+ "my.package.name",
+ UID,
+ PID,
+ ws,
+ /* historyTag= */ null,
+ /* callback= */ null);
+
+ verify(mBatteryStatsInternal, atLeast(1)).getOwnerUid(eq(WORK_SOURCE_UID_1));
+ verify(mBatteryStatsInternal, atLeast(1)).getOwnerUid(eq(WORK_SOURCE_UID_2));
+ }
}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
index f02a389..d83dc11 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
@@ -67,6 +67,7 @@
import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
import com.android.internal.os.KernelSingleUidTimeReader;
import com.android.internal.os.LongArrayMultiStateCounter;
+import com.android.internal.os.MonotonicClock;
import com.android.internal.os.PowerProfile;
import com.android.server.power.feature.flags.Flags;
@@ -120,6 +121,7 @@
}});
private final MockClock mMockClock = new MockClock();
+ private final MonotonicClock mMonotonicClock = new MonotonicClock(777666, mMockClock);
private MockBatteryStatsImpl mBatteryStatsImpl;
private Handler mHandler;
private PowerStatsStore mPowerStatsStore;
@@ -160,7 +162,7 @@
mPowerStatsStore = new PowerStatsStore(systemDir, mHandler);
mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mPowerAttributor,
mPowerProfile, mBatteryStatsImpl.getCpuScalingPolicies(), mPowerStatsStore, 0,
- mMockClock);
+ mMockClock, mMonotonicClock);
}
@Test
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java
index 813dd84..5d50e6c 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsAtomTest.java
@@ -191,7 +191,7 @@
"cpu",
1650.0f,
9300.0f,
- 8400L
+ 8300L
);
verify(statsLogger).buildStatsEvent(
1000L,
@@ -205,7 +205,7 @@
"cpu",
1650.0f,
9400.0f,
- 0L
+ 8400L
);
verify(statsLogger).buildStatsEvent(
1000L,
@@ -502,17 +502,17 @@
.setPackageWithHighestDrain("myPackage0")
.setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 1000)
.setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND, 2000)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_CPU, 400)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 450)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1, 500)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.POWER_COMPONENT_CPU, 600)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1, 800);
final BatteryConsumer.Key keyFg = uidBuilder.getKey(BatteryConsumer.POWER_COMPONENT_CPU,
@@ -524,14 +524,14 @@
final BatteryConsumer.Key keyCached = uidBuilder.getKey(BatteryConsumer.POWER_COMPONENT_CPU,
BatteryConsumer.PROCESS_STATE_CACHED);
- uidBuilder.setConsumedPower(keyFg, 9100, BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setUsageDurationMillis(keyFg, 8100)
- .setConsumedPower(keyBg, 9200, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
- .setUsageDurationMillis(keyBg, 8200)
- .setConsumedPower(keyFgs, 9300, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
- .setUsageDurationMillis(keyFgs, 8300)
- .setConsumedPower(keyCached, 9400, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
- .setUsageDurationMillis(keyFgs, 8400);
+ uidBuilder.addConsumedPower(keyFg, 9100, BatteryConsumer.POWER_MODEL_POWER_PROFILE)
+ .addUsageDurationMillis(keyFg, 8100)
+ .addConsumedPower(keyBg, 9200, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
+ .addUsageDurationMillis(keyBg, 8200)
+ .addConsumedPower(keyFgs, 9300, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
+ .addUsageDurationMillis(keyFgs, 8300)
+ .addConsumedPower(keyCached, 9400, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
+ .addUsageDurationMillis(keyCached, 8400);
final BatteryConsumer.Key keyCustomFg = uidBuilder.getKey(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
@@ -539,9 +539,9 @@
final BatteryConsumer.Key keyCustomBg = uidBuilder.getKey(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
BatteryConsumer.PROCESS_STATE_BACKGROUND);
- uidBuilder.setConsumedPower(
+ uidBuilder.addConsumedPower(
keyCustomFg, 100, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
- uidBuilder.setConsumedPower(
+ uidBuilder.addConsumedPower(
keyCustomBg, 350, BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
builder.getOrCreateUidBatteryConsumerBuilder(UID_1)
@@ -549,36 +549,36 @@
.setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 1234);
builder.getOrCreateUidBatteryConsumerBuilder(UID_2)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN,
+ .addConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN,
766);
builder.getOrCreateUidBatteryConsumerBuilder(UID_3);
builder.getAggregateBatteryConsumerBuilder(AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
- .setConsumedPower(30000)
- .setConsumedPower(
+ .addConsumedPower(30000)
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_CPU, 20100,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_AUDIO, 0,
BatteryConsumer.POWER_MODEL_POWER_PROFILE) // Empty
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_CAMERA, 20150,
BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20200)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.POWER_COMPONENT_CPU, 20300)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20400);
// Not used; just to make sure extraneous data doesn't mess things up.
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_CPU, 10100,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200);
return builder.build();
@@ -596,8 +596,8 @@
BatteryConsumer.PROCESS_STATE_FOREGROUND, 1 * 60 * 1000)
.setTimeInProcessStateMs(
BatteryConsumer.PROCESS_STATE_BACKGROUND, 2 * 60 * 1000)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 30)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 40);
+ .addConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 30)
+ .addConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 40);
}
// Add a UID with much larger battery footprint
@@ -605,16 +605,16 @@
builder.getOrCreateUidBatteryConsumerBuilder(largeConsumerUid)
.setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 10 * 60 * 1000)
.setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND, 20 * 60 * 1000)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 400);
+ .addConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 300)
+ .addConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 400);
// Add a UID with much larger usage duration
final int highUsageUid = 3002;
builder.getOrCreateUidBatteryConsumerBuilder(highUsageUid)
.setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_FOREGROUND, 60 * 60 * 1000)
.setTimeInProcessStateMs(BatteryConsumer.PROCESS_STATE_BACKGROUND, 120 * 60 * 1000)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 3)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 4);
+ .addConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, 3)
+ .addConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 4);
BatteryUsageStats batteryUsageStats = builder.build();
final byte[] bytes = batteryUsageStats.getStatsProto();
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
index 8239e09..709f83b 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
@@ -47,6 +47,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.os.BatteryStatsHistoryIterator;
+import com.android.internal.os.MonotonicClock;
import com.android.internal.os.PowerProfile;
import com.android.server.power.stats.processor.MultiStatePowerAttributor;
@@ -80,6 +81,7 @@
.setAveragePower(PowerProfile.POWER_BATTERY_CAPACITY, 4000.0);
private MockClock mMockClock = mStatsRule.getMockClock();
+ private MonotonicClock mMonotonicClock = new MonotonicClock(666777, mMockClock);
private Context mContext;
@Before
@@ -146,7 +148,8 @@
BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
mock(PowerAttributor.class), mStatsRule.getPowerProfile(),
- mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock);
+ mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock,
+ mMonotonicClock);
final BatteryUsageStats batteryUsageStats =
provider.getBatteryUsageStats(batteryStats,
@@ -273,7 +276,8 @@
BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
powerAttributor, mStatsRule.getPowerProfile(),
- mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock);
+ mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock,
+ mMonotonicClock);
return provider.getBatteryUsageStats(batteryStats, BatteryUsageStatsQuery.DEFAULT);
}
@@ -303,7 +307,8 @@
BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
mock(PowerAttributor.class), mStatsRule.getPowerProfile(),
- mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock);
+ mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock,
+ mMonotonicClock);
final BatteryUsageStats batteryUsageStats =
provider.getBatteryUsageStats(batteryStats,
@@ -396,7 +401,8 @@
BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
mock(PowerAttributor.class), mStatsRule.getPowerProfile(),
- mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock);
+ mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock,
+ mMonotonicClock);
final BatteryUsageStats batteryUsageStats =
provider.getBatteryUsageStats(batteryStats,
@@ -487,7 +493,8 @@
BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
mock(PowerAttributor.class), mStatsRule.getPowerProfile(),
- mStatsRule.getCpuScalingPolicies(), powerStatsStore, 0, mMockClock);
+ mStatsRule.getCpuScalingPolicies(), powerStatsStore, 0, mMockClock,
+ mMonotonicClock);
batteryStats.saveBatteryUsageStatsOnReset(provider, powerStatsStore,
/* accumulateBatteryUsageStats */ false);
@@ -590,7 +597,10 @@
private void accumulateBatteryUsageStats(int accumulatedBatteryUsageStatsSpanSize,
int expectedNumberOfUpdates) throws Throwable {
- BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
+ BatteryStatsImpl batteryStats = spy(mStatsRule.getBatteryStats());
+ // Note - these two are in microseconds
+ when(batteryStats.computeBatteryTimeRemaining(anyLong())).thenReturn(111_000L);
+ when(batteryStats.computeChargeTimeRemaining(anyLong())).thenReturn(777_000L);
batteryStats.forceRecordAllHistory();
setTime(5 * MINUTE_IN_MS);
@@ -623,7 +633,7 @@
BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
powerAttributor, mStatsRule.getPowerProfile(),
mStatsRule.getCpuScalingPolicies(), powerStatsStore,
- accumulatedBatteryUsageStatsSpanSize, mMockClock);
+ accumulatedBatteryUsageStatsSpanSize, mMockClock, mMonotonicClock);
provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());
@@ -677,9 +687,14 @@
BatteryUsageStats stats = provider.getBatteryUsageStats(batteryStats,
new BatteryUsageStatsQuery.Builder().accumulated().build());
+
assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
assertThat(stats.getStatsEndTimestamp()).isEqualTo(115 * MINUTE_IN_MS);
+ assertThat(stats.getBatteryTimeRemainingMs()).isEqualTo(111);
+ assertThat(stats.getChargeTimeRemainingMs()).isEqualTo(777);
+ assertThat(stats.getBatteryCapacity()).isEqualTo(4000); // from PowerProfile
+
// Total: 10 + 20 + 30 = 60
assertThat(stats.getAggregateBatteryConsumer(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
@@ -729,7 +744,8 @@
BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
mock(PowerAttributor.class), mStatsRule.getPowerProfile(),
- mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock);
+ mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock,
+ mMonotonicClock);
PowerStatsStore powerStatsStore = mock(PowerStatsStore.class);
doAnswer(invocation -> {
@@ -796,7 +812,8 @@
BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
mock(PowerAttributor.class), mStatsRule.getPowerProfile(),
- mStatsRule.getCpuScalingPolicies(), powerStatsStore, 0, mMockClock);
+ mStatsRule.getCpuScalingPolicies(), powerStatsStore, 0, mMockClock,
+ mMonotonicClock);
BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder()
.aggregateSnapshots(0, 3000)
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
index 1b6b8c4..9771da5 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
@@ -119,7 +119,7 @@
BatteryStatsImpl.Uid mockUid = mock(BatteryStatsImpl.Uid.class);
when(mockUid.getUid()).thenReturn(i);
builder.getOrCreateUidBatteryConsumerBuilder(mockUid)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, i * 100);
+ .addConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, i * 100);
}
BatteryUsageStats outBatteryUsageStats = builder.build();
@@ -355,13 +355,13 @@
if (includeUserBatteryConsumer) {
builder.getOrCreateUserBatteryConsumerBuilder(USER_ID)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_CPU, 10)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.POWER_COMPONENT_CPU, 30)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 40);
}
return builder;
@@ -422,15 +422,15 @@
.setTimeInProcessStateMs(PROCESS_STATE_BACKGROUND, timeInProcessStateBackground)
.setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE,
timeInProcessStateForegroundService)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_SCREEN, screenPower, screenPowerModel)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_CPU, cpuPower, cpuPowerModel)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentPower)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.POWER_COMPONENT_CPU, cpuDuration)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentDuration);
if (builder.isProcessStateDataNeeded()) {
final BatteryConsumer.Key cpuFgKey = builder.isScreenStateDataNeeded()
@@ -461,21 +461,21 @@
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
BatteryConsumer.PROCESS_STATE_BACKGROUND);
uidBuilder
- .setConsumedPower(cpuFgKey, cpuPowerForeground,
+ .addConsumedPower(cpuFgKey, cpuPowerForeground,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setUsageDurationMillis(cpuFgKey, cpuDurationForeground)
- .setConsumedPower(cpuBgKey, cpuPowerBackground,
+ .addUsageDurationMillis(cpuFgKey, cpuDurationForeground)
+ .addConsumedPower(cpuBgKey, cpuPowerBackground,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setUsageDurationMillis(cpuBgKey, cpuDurationBackground)
- .setConsumedPower(cpuFgsKey, cpuPowerFgs,
+ .addUsageDurationMillis(cpuBgKey, cpuDurationBackground)
+ .addConsumedPower(cpuFgsKey, cpuPowerFgs,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setUsageDurationMillis(cpuFgsKey, cpuDurationFgs)
- .setConsumedPower(cachedKey, cpuPowerCached,
+ .addUsageDurationMillis(cpuFgsKey, cpuDurationFgs)
+ .addConsumedPower(cachedKey, cpuPowerCached,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setUsageDurationMillis(cachedKey, cpuDurationCached)
- .setConsumedPower(customBgKey, customComponentPower,
+ .addUsageDurationMillis(cachedKey, cpuDurationCached)
+ .addConsumedPower(customBgKey, customComponentPower,
BatteryConsumer.POWER_MODEL_UNDEFINED)
- .setUsageDurationMillis(customBgKey, customComponentDuration);
+ .addUsageDurationMillis(customBgKey, customComponentDuration);
}
}
@@ -486,15 +486,15 @@
long cpuDurationChgScrOn, double cpuPowerChgScrOff, long cpuDurationChgScrOff) {
final AggregateBatteryConsumer.Builder aggBuilder =
builder.getAggregateBatteryConsumerBuilder(scope)
- .setConsumedPower(consumedPower)
- .setConsumedPower(
+ .addConsumedPower(consumedPower)
+ .addConsumedPower(
BatteryConsumer.POWER_COMPONENT_CPU, cpuPower)
- .setConsumedPower(
+ .addConsumedPower(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
customComponentPower)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.POWER_COMPONENT_CPU, cpuDuration)
- .setUsageDurationMillis(
+ .addUsageDurationMillis(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
customComponentDuration);
if (builder.isPowerStateDataNeeded() || builder.isScreenStateDataNeeded()) {
@@ -519,18 +519,18 @@
BatteryConsumer.SCREEN_STATE_OTHER,
BatteryConsumer.POWER_STATE_OTHER);
aggBuilder
- .setConsumedPower(cpuBatScrOn, cpuPowerBatScrOn,
+ .addConsumedPower(cpuBatScrOn, cpuPowerBatScrOn,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setUsageDurationMillis(cpuBatScrOn, cpuDurationBatScrOn)
- .setConsumedPower(cpuBatScrOff, cpuPowerBatScrOff,
+ .addUsageDurationMillis(cpuBatScrOn, cpuDurationBatScrOn)
+ .addConsumedPower(cpuBatScrOff, cpuPowerBatScrOff,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setUsageDurationMillis(cpuBatScrOff, cpuDurationBatScrOff)
- .setConsumedPower(cpuChgScrOn, cpuPowerChgScrOn,
+ .addUsageDurationMillis(cpuBatScrOff, cpuDurationBatScrOff)
+ .addConsumedPower(cpuChgScrOn, cpuPowerChgScrOn,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setUsageDurationMillis(cpuChgScrOn, cpuDurationChgScrOn)
- .setConsumedPower(cpuChgScrOff, cpuPowerChgScrOff,
+ .addUsageDurationMillis(cpuChgScrOn, cpuDurationChgScrOn)
+ .addConsumedPower(cpuChgScrOff, cpuPowerChgScrOff,
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
- .setUsageDurationMillis(cpuChgScrOff, cpuDurationChgScrOff);
+ .addUsageDurationMillis(cpuChgScrOff, cpuDurationChgScrOff);
}
}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 359755a..f165667 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -96,7 +96,10 @@
"CtsVirtualDeviceCommonLib",
"com_android_server_accessibility_flags_lib",
"locksettings_flags_lib",
- ],
+ ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), {
+ "true": ["service-crashrecovery.impl"],
+ default: [],
+ }),
libs: [
"android.hardware.power-V1-java",
@@ -157,21 +160,49 @@
resource_zips: [":FrameworksServicesTests_apks_as_resources"],
}
-android_ravenwood_test {
- name: "FrameworksServicesTestsRavenwood",
+java_defaults {
+ name: "FrameworksServicesTestsRavenwood-defaults",
libs: [
"android.test.mock.stubs.system",
],
static_libs: [
"androidx.annotation_annotation",
"androidx.test.rules",
- "services.core",
"flag-junit",
],
+ auto_gen_config: true,
+}
+
+// Unit tests for UriGrantManager, running on ravenwood.
+// Note UriGrantManager does not support Ravenwood (yet). We're just running the original
+// unit tests as is on Ravenwood. So here, we use the original "services.core", because
+// "services.core.ravenwood" doesn't have the target code.
+// (Compare to FrameworksServicesTestsRavenwood_Compat, which does support Ravenwood.)
+android_ravenwood_test {
+ name: "FrameworksServicesTestsRavenwood_Uri",
+ defaults: ["FrameworksServicesTestsRavenwood-defaults"],
+ team: "trendy_team_ravenwood",
+ static_libs: [
+ "services.core",
+ ],
srcs: [
"src/com/android/server/uri/**/*.java",
],
- auto_gen_config: true,
+}
+
+// Unit tests for compat-framework.
+// Compat-framework does support Ravenwood, and it uses the ravenwood anottations,
+// so we link "services.core.ravenwood".
+android_ravenwood_test {
+ name: "FrameworksServicesTestsRavenwood_Compat",
+ defaults: ["FrameworksServicesTestsRavenwood-defaults"],
+ team: "trendy_team_ravenwood",
+ static_libs: [
+ "services.core.ravenwood",
+ ],
+ srcs: [
+ "src/com/android/server/compat/**/*.java",
+ ],
}
java_library {
diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsRecentAccessPersistenceTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsRecentAccessPersistenceTest.java
index c4b3c149..5d7ffe9 100644
--- a/services/tests/servicestests/src/com/android/server/appop/AppOpsRecentAccessPersistenceTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsRecentAccessPersistenceTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
+import android.app.PropertyInvalidatedCache;
import android.companion.virtual.VirtualDeviceManager;
import android.content.Context;
import android.os.FileUtils;
@@ -69,6 +70,7 @@
@Before
public void setUp() {
+ PropertyInvalidatedCache.disableForTestMode();
when(mAppOpCheckingService.addAppOpsModeChangedListener(any())).thenReturn(true);
LocalServices.addService(AppOpsCheckingServiceInterface.class, mAppOpCheckingService);
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
index c9e9f00..c418151 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
@@ -16,6 +16,7 @@
package com.android.server.audio;
import static android.media.AudioDeviceInfo.TYPE_BUILTIN_MIC;
+import static android.media.AudioManager.GET_DEVICES_INPUTS;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -34,7 +35,9 @@
import android.os.Looper;
import android.os.PermissionEnforcer;
import android.os.UserHandle;
+import android.os.test.TestLooper;
import android.platform.test.annotations.EnableFlags;
+import android.util.IntArray;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -80,12 +83,15 @@
private static boolean sLooperPrepared = false;
+ private TestLooper mTestLooper;
+
@Before
public void setUp() throws Exception {
if (!sLooperPrepared) {
Looper.prepare();
sLooperPrepared = true;
}
+ mTestLooper = new TestLooper();
mContext = InstrumentationRegistry.getTargetContext();
mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
mSettingsAdapter = new NoOpSettingsAdapter();
@@ -93,8 +99,11 @@
when(mMockAppOpsManager.noteOp(anyInt(), anyInt(), anyString(), anyString(), anyString()))
.thenReturn(AppOpsManager.MODE_ALLOWED);
mAudioService = new AudioService(mContext, mSpyAudioSystem, mSpySystemServer,
- mSettingsAdapter, mAudioVolumeGroupHelper, mMockAudioPolicy, null,
- mMockAppOpsManager, mMockPermissionEnforcer, mMockPermissionProvider, r -> r.run());
+ mSettingsAdapter, mAudioVolumeGroupHelper, mMockAudioPolicy,
+ mTestLooper.getLooper(), mMockAppOpsManager, mMockPermissionEnforcer,
+ mMockPermissionProvider, r -> r.run());
+
+ mTestLooper.dispatchAll();
}
/**
@@ -216,7 +225,19 @@
public void testInputGainIndex() throws Exception {
Log.i(TAG, "running testInputGainIndex");
Assert.assertNotNull(mAudioService);
- Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS); // wait for full AudioService initialization
+
+ IntArray internalDeviceTypes = new IntArray();
+ int status = AudioSystem.getSupportedDeviceTypes(GET_DEVICES_INPUTS, internalDeviceTypes);
+ if (status != AudioSystem.SUCCESS) {
+ Log.e(TAG, "AudioSystem.getSupportedDeviceTypes(GET_DEVICES_INPUTS) failed. status:"
+ + status);
+ }
+
+ // Make sure TYPE_BUILTIN_MIC, aka DEVICE_IN_BUILTIN_MIC in terms of internal device type,
+ // is supported.
+ if (!internalDeviceTypes.contains(AudioSystem.DEVICE_IN_BUILTIN_MIC)) {
+ return;
+ }
AudioDeviceAttributes ada =
new AudioDeviceAttributes(
@@ -229,6 +250,8 @@
int inputGainIndex = 20;
mAudioService.setInputGainIndex(ada, inputGainIndex);
+ mTestLooper.dispatchAll();
+
Assert.assertEquals(
"input gain index reporting wrong value",
inputGainIndex,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClientTest.java
new file mode 100644
index 0000000..405fb44
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClientTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.biometrics.sensors.face.aidl;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.biometrics.IInvalidationCallback;
+import android.hardware.biometrics.face.V1_0.IBiometricsFace;
+import android.hardware.biometrics.face.V1_0.OptionalUint64;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.testing.TestableContext;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.log.BiometricLogger;
+import com.android.server.biometrics.sensors.ClientMonitorCallback;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.stubbing.Answer;
+
+import java.util.HashMap;
+
+@Presubmit
+@SmallTest
+public class FaceInvalidationClientTest {
+
+ private static final int SENSOR_ID = 4;
+ private static final int USER_ID = 0;
+
+
+ @Rule
+ public final TestableContext mContext = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+
+ @Mock
+ private IBiometricsFace mFace;
+ @Mock
+ private AidlResponseHandler mAidlResponseHandler;
+ @Mock
+ private BiometricLogger mBiometricLogger;
+ @Mock
+ private BiometricContext mBiometricContext;
+ @Mock
+ private IInvalidationCallback mInvalidationCallback;
+ @Mock
+ private ClientMonitorCallback mClientMonitorCallback;
+
+ @Test
+ public void testStartInvalidationClient_whenHalIsHidl() throws RemoteException {
+ final OptionalUint64 halId = new OptionalUint64();
+
+ when(mFace.setCallback(any())).thenReturn(halId);
+
+ final AidlSession aidlSession = new AidlSession(mContext, () -> mFace, USER_ID,
+ mAidlResponseHandler);
+ final FaceInvalidationClient faceInvalidationClient =
+ new FaceInvalidationClient(mContext, () -> aidlSession, USER_ID,
+ SENSOR_ID, mBiometricLogger, mBiometricContext, new HashMap<>(),
+ mInvalidationCallback);
+
+ doAnswer((Answer<Void>) invocationOnMock -> {
+ faceInvalidationClient.cancel();
+ return null;
+ }).when(mAidlResponseHandler).onUnsupportedClientScheduled();
+
+ faceInvalidationClient.start(mClientMonitorCallback);
+
+ verify(mInvalidationCallback).onCompleted();
+ }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClientTest.java
new file mode 100644
index 0000000..1ee2fd1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClientTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.biometrics.sensors.fingerprint.aidl;
+
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+
+import android.hardware.biometrics.IInvalidationCallback;
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.testing.TestableContext;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.log.BiometricLogger;
+import com.android.server.biometrics.sensors.ClientMonitorCallback;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.stubbing.Answer;
+
+import java.util.HashMap;
+
+@Presubmit
+@SmallTest
+public class FingerprintInvalidationClientTest {
+
+ private static final int SENSOR_ID = 4;
+ private static final int USER_ID = 0;
+
+
+ @Rule
+ public final TestableContext mContext = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+
+ @Mock
+ private IBiometricsFingerprint mFingerprint;
+ @Mock
+ private AidlResponseHandler mAidlResponseHandler;
+ @Mock
+ private BiometricLogger mBiometricLogger;
+ @Mock
+ private BiometricContext mBiometricContext;
+ @Mock
+ private IInvalidationCallback mInvalidationCallback;
+ @Mock
+ private ClientMonitorCallback mClientMonitorCallback;
+
+ @Test
+ public void testStartInvalidationClient_whenHalIsHidl() throws RemoteException {
+ final AidlSession aidlSession = new AidlSession(
+ () -> mFingerprint, USER_ID, mAidlResponseHandler);
+ final FingerprintInvalidationClient fingerprintInvalidationClient =
+ new FingerprintInvalidationClient(mContext, () -> aidlSession, USER_ID,
+ SENSOR_ID, mBiometricLogger, mBiometricContext, new HashMap<>(),
+ mInvalidationCallback);
+
+ doAnswer((Answer<Void>) invocationOnMock -> {
+ fingerprintInvalidationClient.cancel();
+ return null;
+ }).when(mAidlResponseHandler).onUnsupportedClientScheduled(
+ FingerprintInvalidationClient.class);
+
+ fingerprintInvalidationClient.start(mClientMonitorCallback);
+
+ verify(mInvalidationCallback).onCompleted();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
index 36b163e..3d695a6 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -18,12 +18,12 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
import android.app.compat.ChangeIdStateCache;
import android.app.compat.PackageOverride;
diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
index 1d07540..95d601f 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
@@ -26,9 +27,9 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.times;
-import static org.testng.Assert.assertThrows;
import android.compat.Compatibility.ChangeConfig;
+import android.content.AttributionSource;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -39,6 +40,8 @@
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.os.PermissionEnforcer;
+import android.permission.PermissionCheckerManager;
import androidx.test.runner.AndroidJUnit4;
@@ -90,6 +93,22 @@
.thenReturn(-1);
when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt()))
.thenThrow(new PackageManager.NameNotFoundException());
+
+ var allGrantingPermissionEnforcer = new PermissionEnforcer() {
+ @Override
+ protected int checkPermission(String permission, AttributionSource source) {
+ return PermissionCheckerManager.PERMISSION_GRANTED;
+ }
+
+ @Override
+ protected int checkPermission(String permission, int pid, int uid) {
+ return PermissionCheckerManager.PERMISSION_GRANTED;
+ }
+ };
+
+ when(mContext.getSystemService(eq(Context.PERMISSION_ENFORCER_SERVICE)))
+ .thenReturn(allGrantingPermissionEnforcer);
+
mCompatConfig = new CompatConfig(mBuildClassifier, mContext);
mPlatformCompat =
new PlatformCompat(mContext, mCompatConfig, mBuildClassifier, mChangeReporter);
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index cfe3d84..2ed71ce 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -22,10 +22,12 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
+import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
@@ -39,14 +41,18 @@
import android.hardware.thermal.TemperatureThreshold;
import android.hardware.thermal.ThrottlingSeverity;
import android.os.CoolingDevice;
+import android.os.Flags;
import android.os.IBinder;
import android.os.IPowerManager;
import android.os.IThermalEventListener;
+import android.os.IThermalHeadroomListener;
import android.os.IThermalService;
import android.os.IThermalStatusListener;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.Temperature;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -56,6 +62,8 @@
import com.android.server.power.ThermalManagerService.ThermalHalWrapper;
import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -78,6 +86,11 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ThermalManagerServiceTest {
+ @ClassRule
+ public static final SetFlagsRule.ClassRule mSetFlagsClassRule = new SetFlagsRule.ClassRule();
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = mSetFlagsClassRule.createSetFlagsRule();
+
private static final long CALLBACK_TIMEOUT_MILLI_SEC = 5000;
private ThermalManagerService mService;
private ThermalHalFake mFakeHal;
@@ -89,6 +102,8 @@
@Mock
private IThermalService mIThermalServiceMock;
@Mock
+ private IThermalHeadroomListener mHeadroomListener;
+ @Mock
private IThermalEventListener mEventListener1;
@Mock
private IThermalEventListener mEventListener2;
@@ -102,22 +117,23 @@
*/
private class ThermalHalFake extends ThermalHalWrapper {
private static final int INIT_STATUS = Temperature.THROTTLING_NONE;
- private ArrayList<Temperature> mTemperatureList = new ArrayList<>();
- private ArrayList<CoolingDevice> mCoolingDeviceList = new ArrayList<>();
- private ArrayList<TemperatureThreshold> mTemperatureThresholdList = initializeThresholds();
+ private List<Temperature> mTemperatureList = new ArrayList<>();
+ private List<Temperature> mOverrideTemperatures = null;
+ private List<CoolingDevice> mCoolingDeviceList = new ArrayList<>();
+ private List<TemperatureThreshold> mTemperatureThresholdList = initializeThresholds();
- private Temperature mSkin1 = new Temperature(0, Temperature.TYPE_SKIN, "skin1",
+ private Temperature mSkin1 = new Temperature(28, Temperature.TYPE_SKIN, "skin1",
INIT_STATUS);
- private Temperature mSkin2 = new Temperature(0, Temperature.TYPE_SKIN, "skin2",
+ private Temperature mSkin2 = new Temperature(31, Temperature.TYPE_SKIN, "skin2",
INIT_STATUS);
- private Temperature mBattery = new Temperature(0, Temperature.TYPE_BATTERY, "batt",
+ private Temperature mBattery = new Temperature(34, Temperature.TYPE_BATTERY, "batt",
INIT_STATUS);
- private Temperature mUsbPort = new Temperature(0, Temperature.TYPE_USB_PORT, "usbport",
+ private Temperature mUsbPort = new Temperature(37, Temperature.TYPE_USB_PORT, "usbport",
INIT_STATUS);
- private CoolingDevice mCpu = new CoolingDevice(0, CoolingDevice.TYPE_BATTERY, "cpu");
- private CoolingDevice mGpu = new CoolingDevice(0, CoolingDevice.TYPE_BATTERY, "gpu");
+ private CoolingDevice mCpu = new CoolingDevice(40, CoolingDevice.TYPE_BATTERY, "cpu");
+ private CoolingDevice mGpu = new CoolingDevice(43, CoolingDevice.TYPE_BATTERY, "gpu");
- private ArrayList<TemperatureThreshold> initializeThresholds() {
+ private List<TemperatureThreshold> initializeThresholds() {
ArrayList<TemperatureThreshold> thresholds = new ArrayList<>();
TemperatureThreshold skinThreshold = new TemperatureThreshold();
@@ -157,6 +173,14 @@
mCoolingDeviceList.add(mGpu);
}
+ void setOverrideTemperatures(List<Temperature> temperatures) {
+ mOverrideTemperatures = temperatures;
+ }
+
+ void resetOverrideTemperatures() {
+ mOverrideTemperatures = null;
+ }
+
@Override
protected List<Temperature> getCurrentTemperatures(boolean shouldFilter, int type) {
List<Temperature> ret = new ArrayList<>();
@@ -221,22 +245,36 @@
when(mContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
resetListenerMock();
mService = new ThermalManagerService(mContext, mFakeHal);
- // Register callbacks before AMS ready and no callback sent
+ mService.onBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
+ }
+
+ private void resetListenerMock() {
+ reset(mEventListener1);
+ reset(mStatusListener1);
+ reset(mEventListener2);
+ reset(mStatusListener2);
+ reset(mHeadroomListener);
+ doReturn(mock(IBinder.class)).when(mEventListener1).asBinder();
+ doReturn(mock(IBinder.class)).when(mStatusListener1).asBinder();
+ doReturn(mock(IBinder.class)).when(mEventListener2).asBinder();
+ doReturn(mock(IBinder.class)).when(mStatusListener2).asBinder();
+ doReturn(mock(IBinder.class)).when(mHeadroomListener).asBinder();
+ }
+
+ @Test
+ public void testRegister() throws Exception {
+ mService = new ThermalManagerService(mContext, mFakeHal);
+ // Register callbacks before AMS ready and verify they are called after AMS is ready
assertTrue(mService.mService.registerThermalEventListener(mEventListener1));
assertTrue(mService.mService.registerThermalStatusListener(mStatusListener1));
assertTrue(mService.mService.registerThermalEventListenerWithType(mEventListener2,
Temperature.TYPE_SKIN));
assertTrue(mService.mService.registerThermalStatusListener(mStatusListener2));
- verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(0)).notifyThrottling(any(Temperature.class));
- verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(1)).onStatusChange(Temperature.THROTTLING_NONE);
- verify(mEventListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(0)).notifyThrottling(any(Temperature.class));
- verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(1)).onStatusChange(Temperature.THROTTLING_NONE);
+ Thread.sleep(CALLBACK_TIMEOUT_MILLI_SEC);
resetListenerMock();
mService.onBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
+ assertTrue(mService.mService.registerThermalHeadroomListener(mHeadroomListener));
+
ArgumentCaptor<Temperature> captor = ArgumentCaptor.forClass(Temperature.class);
verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(4)).notifyThrottling(captor.capture());
@@ -251,31 +289,18 @@
captor.getAllValues());
verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(0)).onStatusChange(Temperature.THROTTLING_NONE);
- }
-
- private void resetListenerMock() {
- reset(mEventListener1);
- reset(mStatusListener1);
- reset(mEventListener2);
- reset(mStatusListener2);
- doReturn(mock(IBinder.class)).when(mEventListener1).asBinder();
- doReturn(mock(IBinder.class)).when(mStatusListener1).asBinder();
- doReturn(mock(IBinder.class)).when(mEventListener2).asBinder();
- doReturn(mock(IBinder.class)).when(mStatusListener2).asBinder();
- }
-
- @Test
- public void testRegister() throws RemoteException {
resetListenerMock();
- // Register callbacks and verify they are called
+
+ // Register callbacks after AMS ready and verify they are called
assertTrue(mService.mService.registerThermalEventListener(mEventListener1));
assertTrue(mService.mService.registerThermalStatusListener(mStatusListener1));
- ArgumentCaptor<Temperature> captor = ArgumentCaptor.forClass(Temperature.class);
+ captor = ArgumentCaptor.forClass(Temperature.class);
verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(4)).notifyThrottling(captor.capture());
assertListEqualsIgnoringOrder(mFakeHal.mTemperatureList, captor.getAllValues());
verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).onStatusChange(Temperature.THROTTLING_NONE);
+
// Register new callbacks and verify old ones are not called (remained same) while new
// ones are called
assertTrue(mService.mService.registerThermalEventListenerWithType(mEventListener2,
@@ -296,7 +321,15 @@
}
@Test
- public void testNotifyThrottling() throws RemoteException {
+ public void testNotifyThrottling() throws Exception {
+ assertTrue(mService.mService.registerThermalEventListener(mEventListener1));
+ assertTrue(mService.mService.registerThermalStatusListener(mStatusListener1));
+ assertTrue(mService.mService.registerThermalEventListenerWithType(mEventListener2,
+ Temperature.TYPE_SKIN));
+ assertTrue(mService.mService.registerThermalStatusListener(mStatusListener2));
+ Thread.sleep(CALLBACK_TIMEOUT_MILLI_SEC);
+ resetListenerMock();
+
int status = Temperature.THROTTLING_SEVERE;
// Should only notify event not status
Temperature newBattery = new Temperature(50, Temperature.TYPE_BATTERY, "batt", status);
@@ -349,6 +382,57 @@
}
@Test
+ @EnableFlags({Flags.FLAG_ALLOW_THERMAL_THRESHOLDS_CALLBACK})
+ public void testNotifyThrottling_headroomCallback() throws Exception {
+ assertTrue(mService.mService.registerThermalHeadroomListener(mHeadroomListener));
+ Thread.sleep(CALLBACK_TIMEOUT_MILLI_SEC);
+ resetListenerMock();
+ int status = Temperature.THROTTLING_SEVERE;
+ mFakeHal.setOverrideTemperatures(new ArrayList<>());
+
+ // Should not notify on non-skin type
+ Temperature newBattery = new Temperature(37, Temperature.TYPE_BATTERY, "batt", status);
+ mFakeHal.mCallback.onTemperatureChanged(newBattery);
+ verify(mHeadroomListener, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(0)).onHeadroomChange(anyFloat(), anyFloat(), anyInt(), any());
+ resetListenerMock();
+
+ // Notify headroom on skin temperature change
+ Temperature newSkin = new Temperature(37, Temperature.TYPE_SKIN, "skin1", status);
+ mFakeHal.mCallback.onTemperatureChanged(newSkin);
+ verify(mHeadroomListener, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onHeadroomChange(eq(0.9f), anyFloat(), anyInt(),
+ eq(new float[]{Float.NaN, 0.6666667f, 0.8333333f, 1.0f, 1.1666666f, 1.3333334f,
+ 1.5f}));
+ resetListenerMock();
+
+ // Same or similar temperature should not trigger in a short period
+ mFakeHal.mCallback.onTemperatureChanged(newSkin);
+ newSkin = new Temperature(36.9f, Temperature.TYPE_SKIN, "skin1", status);
+ mFakeHal.mCallback.onTemperatureChanged(newSkin);
+ newSkin = new Temperature(37.1f, Temperature.TYPE_SKIN, "skin1", status);
+ mFakeHal.mCallback.onTemperatureChanged(newSkin);
+ verify(mHeadroomListener, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(0)).onHeadroomChange(anyFloat(), anyFloat(), anyInt(), any());
+ resetListenerMock();
+
+ // Significant temperature should trigger in a short period
+ newSkin = new Temperature(34f, Temperature.TYPE_SKIN, "skin1", status);
+ mFakeHal.mCallback.onTemperatureChanged(newSkin);
+ verify(mHeadroomListener, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onHeadroomChange(eq(0.8f), anyFloat(), anyInt(),
+ eq(new float[]{Float.NaN, 0.6666667f, 0.8333333f, 1.0f, 1.1666666f, 1.3333334f,
+ 1.5f}));
+ resetListenerMock();
+ newSkin = new Temperature(40f, Temperature.TYPE_SKIN, "skin1", status);
+ mFakeHal.mCallback.onTemperatureChanged(newSkin);
+ verify(mHeadroomListener, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onHeadroomChange(eq(1.0f), anyFloat(), anyInt(),
+ eq(new float[]{Float.NaN, 0.6666667f, 0.8333333f, 1.0f, 1.1666666f, 1.3333334f,
+ 1.5f}));
+ }
+
+ @Test
public void testGetCurrentTemperatures() throws RemoteException {
assertListEqualsIgnoringOrder(mFakeHal.getCurrentTemperatures(false, 0),
Arrays.asList(mService.mService.getCurrentTemperatures()));
@@ -388,13 +472,28 @@
// Do no call onActivityManagerReady to skip connect HAL
assertTrue(mService.mService.registerThermalEventListener(mEventListener1));
assertTrue(mService.mService.registerThermalStatusListener(mStatusListener1));
- assertTrue(mService.mService.unregisterThermalEventListener(mEventListener1));
- assertTrue(mService.mService.unregisterThermalStatusListener(mStatusListener1));
+ assertTrue(mService.mService.registerThermalEventListenerWithType(mEventListener2,
+ Temperature.TYPE_SKIN));
+ assertFalse(mService.mService.registerThermalHeadroomListener(mHeadroomListener));
+ verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(0)).notifyThrottling(any(Temperature.class));
+ verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onStatusChange(Temperature.THROTTLING_NONE);
+ verify(mEventListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(0)).notifyThrottling(any(Temperature.class));
+ verify(mHeadroomListener, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(0)).onHeadroomChange(anyFloat(), anyFloat(), anyInt(), any());
+
assertEquals(0, Arrays.asList(mService.mService.getCurrentTemperatures()).size());
assertEquals(0, Arrays.asList(mService.mService.getCurrentTemperaturesWithType(
- Temperature.TYPE_SKIN)).size());
+ Temperature.TYPE_SKIN)).size());
assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentThermalStatus());
assertTrue(Float.isNaN(mService.mService.getThermalHeadroom(0)));
+
+ assertTrue(mService.mService.unregisterThermalEventListener(mEventListener1));
+ assertTrue(mService.mService.unregisterThermalEventListener(mEventListener2));
+ assertTrue(mService.mService.unregisterThermalStatusListener(mStatusListener1));
+ assertFalse(mService.mService.unregisterThermalHeadroomListener(mHeadroomListener));
}
@Test
@@ -419,35 +518,45 @@
}
@Test
- public void testTemperatureWatcherUpdateSevereThresholds() {
+ @EnableFlags({Flags.FLAG_ALLOW_THERMAL_THRESHOLDS_CALLBACK,
+ Flags.FLAG_ALLOW_THERMAL_HEADROOM_THRESHOLDS})
+ public void testTemperatureWatcherUpdateSevereThresholds() throws Exception {
+ assertTrue(mService.mService.registerThermalHeadroomListener(mHeadroomListener));
+ verify(mHeadroomListener, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onHeadroomChange(eq(0.6f), eq(0.6f), anyInt(),
+ aryEq(new float[]{Float.NaN, 0.6666667f, 0.8333333f, 1.0f, 1.1666666f, 1.3333334f,
+ 1.5f}));
+ resetListenerMock();
TemperatureWatcher watcher = mService.mTemperatureWatcher;
+ TemperatureThreshold newThreshold = new TemperatureThreshold();
+ newThreshold.name = "skin1";
+ newThreshold.type = Temperature.TYPE_SKIN;
+ // significant change in threshold (> 0.3C) should trigger a callback
+ newThreshold.hotThrottlingThresholds = new float[]{
+ Float.NaN, 43.0f, 46.0f, 49.0f, Float.NaN, Float.NaN, Float.NaN
+ };
+ mFakeHal.mCallback.onThresholdChanged(newThreshold);
synchronized (watcher.mSamples) {
- watcher.mSevereThresholds.erase();
- watcher.getAndUpdateThresholds();
- assertEquals(1, watcher.mSevereThresholds.size());
- assertEquals("skin1", watcher.mSevereThresholds.keyAt(0));
Float threshold = watcher.mSevereThresholds.get("skin1");
assertNotNull(threshold);
- assertEquals(40.0f, threshold, 0.0f);
+ assertEquals(49.0f, threshold, 0.0f);
assertArrayEquals("Got" + Arrays.toString(watcher.mHeadroomThresholds),
- new float[]{Float.NaN, 0.6667f, 0.8333f, 1.0f, 1.166f, 1.3333f,
- 1.5f},
- watcher.mHeadroomThresholds, 0.01f);
-
- TemperatureThreshold newThreshold = new TemperatureThreshold();
- newThreshold.name = "skin1";
- newThreshold.hotThrottlingThresholds = new float[] {
- Float.NaN, 44.0f, 47.0f, 50.0f, Float.NaN, Float.NaN, Float.NaN
- };
- mFakeHal.mCallback.onThresholdChanged(newThreshold);
- threshold = watcher.mSevereThresholds.get("skin1");
- assertNotNull(threshold);
- assertEquals(50.0f, threshold, 0.0f);
- assertArrayEquals("Got" + Arrays.toString(watcher.mHeadroomThresholds),
- new float[]{Float.NaN, 0.8f, 0.9f, 1.0f, Float.NaN, Float.NaN,
- Float.NaN},
+ new float[]{Float.NaN, 0.8f, 0.9f, 1.0f, Float.NaN, Float.NaN, Float.NaN},
watcher.mHeadroomThresholds, 0.01f);
}
+ verify(mHeadroomListener, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onHeadroomChange(eq(0.3f), eq(0.3f), anyInt(),
+ aryEq(new float[]{Float.NaN, 0.8f, 0.9f, 1.0f, Float.NaN, Float.NaN, Float.NaN}));
+ resetListenerMock();
+
+ // same or similar threshold callback data within a second should not trigger callback
+ mFakeHal.mCallback.onThresholdChanged(newThreshold);
+ newThreshold.hotThrottlingThresholds = new float[]{
+ Float.NaN, 43.1f, 45.9f, 49.0f, Float.NaN, Float.NaN, Float.NaN
+ };
+ mFakeHal.mCallback.onThresholdChanged(newThreshold);
+ verify(mHeadroomListener, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(0)).onHeadroomChange(anyFloat(), anyFloat(), anyInt(), any());
}
@Test
@@ -475,28 +584,34 @@
}
@Test
- public void testGetThermalHeadroomThresholdsOnlyReadOnce() throws Exception {
+ public void testGetThermalHeadroomThresholds() throws Exception {
float[] expected = new float[]{Float.NaN, 0.1f, 0.2f, 0.3f, 0.4f, Float.NaN, 0.6f};
when(mIThermalServiceMock.getThermalHeadroomThresholds()).thenReturn(expected);
Map<Integer, Float> thresholds1 = mPowerManager.getThermalHeadroomThresholds();
verify(mIThermalServiceMock, times(1)).getThermalHeadroomThresholds();
+ checkHeadroomThresholds(expected, thresholds1);
+
+ reset(mIThermalServiceMock);
+ expected = new float[]{Float.NaN, 0.2f, 0.3f, 0.4f, 0.4f, Float.NaN, 0.6f};
+ when(mIThermalServiceMock.getThermalHeadroomThresholds()).thenReturn(expected);
+ Map<Integer, Float> thresholds2 = mPowerManager.getThermalHeadroomThresholds();
+ verify(mIThermalServiceMock, times(1)).getThermalHeadroomThresholds();
+ checkHeadroomThresholds(expected, thresholds2);
+ }
+
+ private void checkHeadroomThresholds(float[] expected, Map<Integer, Float> thresholds) {
for (int status = PowerManager.THERMAL_STATUS_LIGHT;
status <= PowerManager.THERMAL_STATUS_SHUTDOWN; status++) {
if (Float.isNaN(expected[status])) {
- assertFalse(thresholds1.containsKey(status));
+ assertFalse(thresholds.containsKey(status));
} else {
- assertEquals(expected[status], thresholds1.get(status), 0.01f);
+ assertEquals(expected[status], thresholds.get(status), 0.01f);
}
}
- reset(mIThermalServiceMock);
- Map<Integer, Float> thresholds2 = mPowerManager.getThermalHeadroomThresholds();
- verify(mIThermalServiceMock, times(0)).getThermalHeadroomThresholds();
- assertNotSame(thresholds1, thresholds2);
- assertEquals(thresholds1, thresholds2);
}
@Test
- public void testGetThermalHeadroomThresholdsOnDefaultHalResult() throws Exception {
+ public void testGetThermalHeadroomThresholdsOnDefaultHalResult() throws Exception {
TemperatureWatcher watcher = mService.mTemperatureWatcher;
ArrayList<TemperatureThreshold> thresholds = new ArrayList<>();
mFakeHal.mTemperatureThresholdList = thresholds;
@@ -510,8 +625,8 @@
TemperatureThreshold nanThresholds = new TemperatureThreshold();
nanThresholds.name = "nan";
nanThresholds.type = Temperature.TYPE_SKIN;
- nanThresholds.hotThrottlingThresholds = new float[ThrottlingSeverity.SHUTDOWN + 1];
- nanThresholds.coldThrottlingThresholds = new float[ThrottlingSeverity.SHUTDOWN + 1];
+ nanThresholds.hotThrottlingThresholds = new float[ThrottlingSeverity.SHUTDOWN + 1];
+ nanThresholds.coldThrottlingThresholds = new float[ThrottlingSeverity.SHUTDOWN + 1];
Arrays.fill(nanThresholds.hotThrottlingThresholds, Float.NaN);
Arrays.fill(nanThresholds.coldThrottlingThresholds, Float.NaN);
thresholds.add(nanThresholds);
@@ -607,7 +722,13 @@
}
@Test
- public void testDump() {
+ public void testDump() throws Exception {
+ assertTrue(mService.mService.registerThermalEventListener(mEventListener1));
+ assertTrue(mService.mService.registerThermalStatusListener(mStatusListener1));
+ assertTrue(mService.mService.registerThermalEventListenerWithType(mEventListener2,
+ Temperature.TYPE_SKIN));
+ assertTrue(mService.mService.registerThermalStatusListener(mStatusListener2));
+
when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP))
.thenReturn(PackageManager.PERMISSION_GRANTED);
final StringWriter out = new StringWriter();
@@ -628,22 +749,22 @@
assertThat(dumpStr).contains("Thermal Status: 0");
assertThat(dumpStr).contains(
"Cached temperatures:\n"
- + "\tTemperature{mValue=0.0, mType=4, mName=usbport, mStatus=0}\n"
- + "\tTemperature{mValue=0.0, mType=2, mName=batt, mStatus=0}\n"
- + "\tTemperature{mValue=0.0, mType=3, mName=skin1, mStatus=0}\n"
- + "\tTemperature{mValue=0.0, mType=3, mName=skin2, mStatus=0}"
+ + "\tTemperature{mValue=37.0, mType=4, mName=usbport, mStatus=0}\n"
+ + "\tTemperature{mValue=34.0, mType=2, mName=batt, mStatus=0}\n"
+ + "\tTemperature{mValue=28.0, mType=3, mName=skin1, mStatus=0}\n"
+ + "\tTemperature{mValue=31.0, mType=3, mName=skin2, mStatus=0}"
);
assertThat(dumpStr).contains("HAL Ready: true\n"
+ "HAL connection:\n"
+ "\tThermalHAL AIDL 1 connected: yes");
assertThat(dumpStr).contains("Current temperatures from HAL:\n"
- + "\tTemperature{mValue=0.0, mType=3, mName=skin1, mStatus=0}\n"
- + "\tTemperature{mValue=0.0, mType=3, mName=skin2, mStatus=0}\n"
- + "\tTemperature{mValue=0.0, mType=2, mName=batt, mStatus=0}\n"
- + "\tTemperature{mValue=0.0, mType=4, mName=usbport, mStatus=0}\n");
+ + "\tTemperature{mValue=28.0, mType=3, mName=skin1, mStatus=0}\n"
+ + "\tTemperature{mValue=31.0, mType=3, mName=skin2, mStatus=0}\n"
+ + "\tTemperature{mValue=34.0, mType=2, mName=batt, mStatus=0}\n"
+ + "\tTemperature{mValue=37.0, mType=4, mName=usbport, mStatus=0}\n");
assertThat(dumpStr).contains("Current cooling devices from HAL:\n"
- + "\tCoolingDevice{mValue=0, mType=1, mName=cpu}\n"
- + "\tCoolingDevice{mValue=0, mType=1, mName=gpu}\n");
+ + "\tCoolingDevice{mValue=40, mType=1, mName=cpu}\n"
+ + "\tCoolingDevice{mValue=43, mType=1, mName=gpu}\n");
assertThat(dumpStr).contains("Temperature static thresholds from HAL:\n"
+ "\tTemperatureThreshold{mType=3, mName=skin1, mHotThrottlingThresholds=[25.0, "
+ "30.0, 35.0, 40.0, 45.0, 50.0, 55.0], mColdThrottlingThresholds=[0.0, 0.0, 0.0,"
diff --git a/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java
index 24abc18..f549453 100644
--- a/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java
@@ -61,7 +61,6 @@
import android.os.UserHandle;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
-import android.platform.test.ravenwood.RavenwoodRule;
import android.util.ArraySet;
import org.junit.Before;
@@ -77,9 +76,6 @@
@RunWith(Parameterized.class)
public class UriGrantsManagerServiceTest {
- @Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule();
-
/**
* Why this class needs to test all combinations of
* {@link android.security.Flags#FLAG_CONTENT_URI_PERMISSION_APIS}:
diff --git a/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java b/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java
index 611c514..fe66f73 100644
--- a/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java
+++ b/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java
@@ -37,18 +37,13 @@
import static org.junit.Assert.assertTrue;
import android.os.SystemClock;
-import android.platform.test.ravenwood.RavenwoodRule;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class UriPermissionTest {
- @Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule();
-
@Mock
private UriGrantsManagerInternal mService;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 22a4f85..0b89c11 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -34,10 +34,12 @@
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION;
import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION;
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static com.android.server.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUP_CONVERSATIONS;
+import static com.android.server.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS;
import static com.android.server.notification.GroupHelper.AGGREGATE_GROUP_KEY;
import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
import static com.android.server.notification.GroupHelper.BASE_FLAGS;
@@ -2217,6 +2219,7 @@
@Test
@EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ @DisableFlags(FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION)
public void testMoveAggregateGroups_updateChannel_multipleChannels() {
final String pkg = "package";
final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
@@ -2265,16 +2268,17 @@
mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel1,
notificationList);
- // Check that channel1's notifications are moved to the silent section group
- // But not enough to auto-group => remove override group key
- verify(mCallback, never()).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
- anyString(), anyInt(), any());
- verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+ // Check that the override group key was cleared
for (NotificationRecord record: notificationList) {
if (record.getChannel().getId().equals(channel1.getId())) {
assertThat(record.getSbn().getOverrideGroupKey()).isNull();
}
}
+ // Check that channel1's notifications are moved to the silent section group
+ // and a group summary is created + notifications are added to the group
+ verify(mCallback, never()).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+ anyInt(), any());
+ verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
// Check that the alerting section group is not removed, only updated
expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
@@ -2287,6 +2291,357 @@
}
@Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION})
+ public void testMoveAggregateGroups_updateChannel_multipleChannels_regroupOnClassifEnabled() {
+ final String pkg = "package";
+ final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ int numNotificationChannel1 = 0;
+ final NotificationChannel channel1 = new NotificationChannel("TEST_CHANNEL_ID1",
+ "TEST_CHANNEL_ID1", IMPORTANCE_DEFAULT);
+ final NotificationChannel channel2 = new NotificationChannel("TEST_CHANNEL_ID2",
+ "TEST_CHANNEL_ID2", IMPORTANCE_DEFAULT);
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ // Post notifications with different channels that autogroup within the same section
+ NotificationRecord r;
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+ if (i % 2 == 0) {
+ r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false, channel1);
+ numNotificationChannel1++;
+ } else {
+ r = getNotificationRecord(pkg, i, String.valueOf(i),
+ UserHandle.SYSTEM, "testGrp " + i, false, channel2);
+ }
+ notificationList.add(r);
+ mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+ }
+ NotificationAttributes expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+ mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ "TEST_CHANNEL_ID1");
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_alerting), anyInt(), eq(expectedSummaryAttr));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_alerting), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ Mockito.reset(mCallback);
+
+ // Update channel1's importance
+ final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+ channel1.setImportance(IMPORTANCE_LOW);
+ for (NotificationRecord record: notificationList) {
+ if (record.getChannel().getId().equals(channel1.getId())) {
+ record.updateNotificationChannel(channel1);
+ }
+ }
+ mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel1,
+ notificationList);
+
+ // Check that the override group key was cleared
+ for (NotificationRecord record: notificationList) {
+ if (record.getChannel().getId().equals(channel1.getId())) {
+ assertThat(record.getSbn().getOverrideGroupKey()).isNull();
+ }
+ }
+ // Check that channel1's notifications are moved to the silent section group
+ // and a group summary is created + notifications are added to the group
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_silent), anyInt(), any());
+ verify(mCallback, times(numNotificationChannel1)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_silent), anyBoolean());
+
+ // Check that the alerting section group is not removed, only updated
+ expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+ mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ "TEST_CHANNEL_ID2");
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey_alerting));
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey_alerting), eq(expectedSummaryAttr));
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION})
+ public void testMoveSections_notificationBundled() {
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final String pkg = "package";
+ final int summaryId = 0;
+ final int numChildNotif = 4;
+
+ // Create an app-provided group: summary + child notifications
+ final NotificationChannel channel1 = new NotificationChannel("TEST_CHANNEL_ID1",
+ "TEST_CHANNEL_ID1", IMPORTANCE_DEFAULT);
+ NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+ String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp " + summaryId,
+ true, channel1);
+ notificationList.add(summary);
+ final String originalAppGroupKey = summary.getGroupKey();
+ for (int i = 0; i < numChildNotif; i++) {
+ NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+ UserHandle.SYSTEM, "testGrp " + summaryId, false, channel1);
+ notificationList.add(child);
+ }
+
+ // Classify/bundle child notifications
+ final NotificationChannel socialChannel = new NotificationChannel(
+ NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+ IMPORTANCE_DEFAULT);
+ final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
+ final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
+ BASE_FLAGS, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ NotificationChannel.SOCIAL_MEDIA_ID);
+ final NotificationChannel newsChannel = new NotificationChannel(
+ NotificationChannel.NEWS_ID, NotificationChannel.NEWS_ID,
+ IMPORTANCE_DEFAULT);
+ final String expectedGroupKey_news = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "NewsSection", UserHandle.SYSTEM.getIdentifier());
+ final NotificationAttributes expectedSummaryAttr_news = new NotificationAttributes(
+ BASE_FLAGS, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ NotificationChannel.NEWS_ID);
+ for (NotificationRecord record: notificationList) {
+ if (record.getChannel().getId().equals(channel1.getId())
+ && record.getSbn().getId() % 2 == 0) {
+ record.updateNotificationChannel(socialChannel);
+ mGroupHelper.onChannelUpdated(record);
+ }
+ if (record.getChannel().getId().equals(channel1.getId())
+ && record.getSbn().getId() % 2 != 0) {
+ record.updateNotificationChannel(newsChannel);
+ mGroupHelper.onChannelUpdated(record);
+ }
+ }
+
+ // Check that 2 autogroup summaries were created for the news & social sections
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_social), anyInt(), eq(expectedSummaryAttr_social));
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_news), anyInt(), eq(expectedSummaryAttr_news));
+ // Check that half of the child notifications were grouped in each new section
+ verify(mCallback, times(numChildNotif / 2)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_news), eq(true));
+ verify(mCallback, times(numChildNotif / 2)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_social), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, times(numChildNotif / 2)).updateAutogroupSummary(anyInt(), anyString(),
+ anyString(), any());
+ verify(mCallback, times(numChildNotif)).removeAppProvidedSummaryOnClassification(
+ anyString(), eq(originalAppGroupKey));
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION})
+ public void testCacheAndCancelAppSummary_notificationBundled() {
+ // check that the original app summary is canceled & cached on classification regrouping
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final String pkg = "package";
+ final int summaryId = 0;
+ final int numChildNotif = 4;
+
+ // Create an app-provided group: summary + child notifications
+ final NotificationChannel channel1 = new NotificationChannel("TEST_CHANNEL_ID1",
+ "TEST_CHANNEL_ID1", IMPORTANCE_DEFAULT);
+ NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+ String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp " + summaryId,
+ true, channel1);
+ notificationList.add(summary);
+ final String originalAppGroupKey = summary.getGroupKey();
+ final String originalAppGroupName = summary.getNotification().getGroup();
+ for (int i = 0; i < numChildNotif; i++) {
+ NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+ UserHandle.SYSTEM, "testGrp " + summaryId, false, channel1);
+ notificationList.add(child);
+ }
+
+ // Last regrouped notification will trigger summary cancellation in NMS
+ when(mCallback.removeAppProvidedSummaryOnClassification(anyString(),
+ eq(originalAppGroupKey))).thenReturn(summary);
+
+ // Classify/bundle child notifications
+ final NotificationChannel socialChannel = new NotificationChannel(
+ NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+ IMPORTANCE_DEFAULT);
+ for (NotificationRecord record: notificationList) {
+ if (record.getChannel().getId().equals(channel1.getId())) {
+ record.updateNotificationChannel(socialChannel);
+ mGroupHelper.onChannelUpdated(record);
+ }
+ }
+
+ // Check that the original app summary was cached
+ CachedSummary cachedSummary = mGroupHelper.findCanceledSummary(pkg,
+ String.valueOf(summaryId), summaryId, UserHandle.SYSTEM.getIdentifier());
+ assertThat(cachedSummary.originalGroupKey()).isEqualTo(originalAppGroupName);
+ assertThat(cachedSummary.key()).isEqualTo(summary.getKey());
+
+ // App cancels the original summary
+ reset(mCallback);
+ mGroupHelper.maybeCancelGroupChildrenForCanceledSummary(pkg, String.valueOf(summaryId),
+ summaryId, UserHandle.SYSTEM.getIdentifier(), REASON_APP_CANCEL);
+ // Check that child notifications are removed and cache is cleared
+ verify(mCallback, times(1)).removeNotificationFromCanceledGroup(
+ eq(UserHandle.SYSTEM.getIdentifier()), eq(pkg), eq(originalAppGroupName),
+ eq(REASON_APP_CANCEL));
+ cachedSummary = mGroupHelper.findCanceledSummary(pkg, String.valueOf(summaryId), summaryId,
+ UserHandle.SYSTEM.getIdentifier());
+ assertThat(cachedSummary).isNull();
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION,
+ FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testSingletonGroupsRegrouped_notificationBundledBeforeDelayTimeout() {
+ // Check that singleton group notifications are regrouped if classification is done
+ // before onNotificationPostedWithDelay
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+
+ // Post singleton groups, above forced group limit
+ for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i,
+ String.valueOf(i), UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+ UserHandle.SYSTEM, "testGrp " + i, false);
+ notificationList.add(child);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ }
+
+ // Classify/bundle child notifications
+ final NotificationChannel socialChannel = new NotificationChannel(
+ NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+ IMPORTANCE_DEFAULT);
+ final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
+ final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
+ BASE_FLAGS, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ NotificationChannel.SOCIAL_MEDIA_ID);
+ for (NotificationRecord record: notificationList) {
+ if (record.getOriginalGroupKey().contains("testGrp")) {
+ record.updateNotificationChannel(socialChannel);
+ mGroupHelper.onChannelUpdated(record);
+ }
+ }
+
+ // Check that notifications are forced grouped and app-provided summaries are canceled
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_social), anyInt(), eq(expectedSummaryAttr_social));
+ verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_social), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ verify(mCallback, times(2)).removeAppProvidedSummaryOnClassification(
+ anyString(), anyString());
+
+ // Adjust group key and cancel summaries
+ for (NotificationRecord record: notificationList) {
+ if (record.getNotification().isGroupSummary()) {
+ record.isCanceled = true;
+ } else {
+ record.setOverrideGroupKey(expectedGroupKey_social);
+ }
+ }
+
+ // Check that after onNotificationPostedWithDelay there is no change in the grouping
+ reset(mCallback);
+ for (NotificationRecord record: notificationList) {
+ mGroupHelper.onNotificationPostedWithDelay(record, notificationList, summaryByGroup);
+ }
+
+ verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+ anyString(), anyInt(), any());
+ verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION,
+ FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testSingletonGroupsRegrouped_notificationBundledAfterDelayTimeout() {
+ // Check that singleton group notifications are regrouped if classification is done
+ // after onNotificationPostedWithDelay
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ String expectedTriggeringKey = null;
+ // Post singleton groups, above forced group limit
+ for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i,
+ String.valueOf(i), UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, i + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp " + i, false);
+ notificationList.add(child);
+ expectedTriggeringKey = child.getKey();
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+ summary.isCanceled = true; // simulate removing the app summary
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ }
+
+ // Check that notifications are forced grouped and app-provided summaries are canceled
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg),
+ eq(expectedTriggeringKey), eq(expectedGroupKey_alerting), anyInt(),
+ eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_alerting), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).removeAppProvidedSummary(
+ anyString());
+ assertThat(mGroupHelper.findCanceledSummary(pkg, String.valueOf(0), 0,
+ UserHandle.SYSTEM.getIdentifier())).isNotNull();
+ assertThat(mGroupHelper.findCanceledSummary(pkg, String.valueOf(1), 1,
+ UserHandle.SYSTEM.getIdentifier())).isNotNull();
+
+ // Classify/bundle child notifications
+ reset(mCallback);
+ final NotificationChannel socialChannel = new NotificationChannel(
+ NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+ IMPORTANCE_DEFAULT);
+ final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
+ final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
+ BASE_FLAGS, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+ NotificationChannel.SOCIAL_MEDIA_ID);
+ for (NotificationRecord record: notificationList) {
+ if (record.getOriginalGroupKey().contains("testGrp")) {
+ record.updateNotificationChannel(socialChannel);
+ mGroupHelper.onChannelUpdated(record);
+ }
+ }
+
+ // Check that all notifications are moved to the social section group
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey_social), anyInt(), eq(expectedSummaryAttr_social));
+ verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey_social), eq(true));
+ // Check that the alerting section group is removed
+ verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+ eq(expectedGroupKey_alerting));
+ verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).updateAutogroupSummary(anyInt(),
+ anyString(), anyString(), any());
+ }
+
+ @Test
@EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testMoveAggregateGroups_updateChannel_groupsUngrouped() {
final String pkg = "package";
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index b5724b5c..48bc9d7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -21,10 +21,8 @@
import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
import static android.os.UserManager.USER_TYPE_PROFILE_PRIVATE;
-import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static android.service.notification.NotificationListenerService.META_DATA_DEFAULT_AUTOBIND;
-import static com.android.server.notification.Flags.FLAG_NOTIFICATION_NLS_REBIND;
import static com.android.server.notification.ManagedServices.APPROVAL_BY_COMPONENT;
import static com.android.server.notification.ManagedServices.APPROVAL_BY_PACKAGE;
import static com.android.server.notification.NotificationManagerService.privateSpaceFlagsEnabled;
@@ -65,14 +63,11 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.platform.test.annotations.EnableFlags;
-import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
-import android.testing.TestableLooper;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -87,9 +82,7 @@
import com.google.android.collect.Lists;
-import org.junit.After;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
@@ -110,10 +103,7 @@
import java.util.Set;
import java.util.concurrent.CountDownLatch;
-
public class ManagedServicesTest extends UiServiceTestCase {
- @Rule
- public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
@Mock
private IPackageManager mIpm;
@@ -125,7 +115,6 @@
private ManagedServices.UserProfiles mUserProfiles;
@Mock private DevicePolicyManager mDpm;
Object mLock = new Object();
- private TestableLooper mTestableLooper;
UserInfo mZero = new UserInfo(0, "zero", 0);
UserInfo mTen = new UserInfo(10, "ten", 0);
@@ -153,7 +142,6 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mTestableLooper = new TestableLooper(Looper.getMainLooper());
mContext.setMockPackageManager(mPm);
mContext.addMockSystemService(Context.USER_SERVICE, mUm);
@@ -211,11 +199,6 @@
mIpm, APPROVAL_BY_COMPONENT);
}
- @After
- public void tearDown() throws Exception {
- mTestableLooper.destroy();
- }
-
@Test
public void testBackupAndRestore_migration() throws Exception {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
@@ -905,7 +888,7 @@
return true;
});
- mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>());
+ mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>());
service.addApprovedList("a", 0, true);
service.reregisterService(cn, 0);
@@ -936,7 +919,7 @@
return true;
});
- mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>());
+ mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>());
service.addApprovedList("a", 0, false);
service.reregisterService(cn, 0);
@@ -967,7 +950,7 @@
return true;
});
- mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>());
+ mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>());
service.addApprovedList("a/a", 0, true);
service.reregisterService(cn, 0);
@@ -998,7 +981,7 @@
return true;
});
- mockServiceInfoWithMetaData(List.of(cn), service, pm, new ArrayMap<>());
+ mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>());
service.addApprovedList("a/a", 0, false);
service.reregisterService(cn, 0);
@@ -1070,78 +1053,6 @@
}
@Test
- @EnableFlags(FLAG_NOTIFICATION_NLS_REBIND)
- public void registerService_bindingDied_rebindIsClearedOnUserSwitch() throws Exception {
- Context context = mock(Context.class);
- PackageManager pm = mock(PackageManager.class);
- ApplicationInfo ai = new ApplicationInfo();
- ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
-
- when(context.getPackageName()).thenReturn(mPkg);
- when(context.getUserId()).thenReturn(mUser.getIdentifier());
- when(context.getPackageManager()).thenReturn(pm);
- when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
-
- ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
- APPROVAL_BY_PACKAGE);
- service = spy(service);
- ComponentName cn = ComponentName.unflattenFromString("a/a");
-
- // Trigger onBindingDied for component when registering
- // => will schedule a rebind in 10 seconds
- when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
- Object[] args = invocation.getArguments();
- ServiceConnection sc = (ServiceConnection) args[1];
- sc.onBindingDied(cn);
- return true;
- });
- service.registerService(cn, 0);
- assertThat(service.isBound(cn, 0)).isFalse();
-
- // Switch to user 10
- service.onUserSwitched(10);
-
- // Check that the scheduled rebind for user 0 was cleared
- mTestableLooper.moveTimeForward(ManagedServices.ON_BINDING_DIED_REBIND_DELAY_MS);
- mTestableLooper.processAllMessages();
- verify(service, never()).reregisterService(any(), anyInt());
- }
-
- @Test
- public void registerService_bindingDied_rebindIsExecutedAfterTimeout() throws Exception {
- Context context = mock(Context.class);
- PackageManager pm = mock(PackageManager.class);
- ApplicationInfo ai = new ApplicationInfo();
- ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
-
- when(context.getPackageName()).thenReturn(mPkg);
- when(context.getUserId()).thenReturn(mUser.getIdentifier());
- when(context.getPackageManager()).thenReturn(pm);
- when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
-
- ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
- APPROVAL_BY_PACKAGE);
- service = spy(service);
- ComponentName cn = ComponentName.unflattenFromString("a/a");
-
- // Trigger onBindingDied for component when registering
- // => will schedule a rebind in 10 seconds
- when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
- Object[] args = invocation.getArguments();
- ServiceConnection sc = (ServiceConnection) args[1];
- sc.onBindingDied(cn);
- return true;
- });
- service.registerService(cn, 0);
- assertThat(service.isBound(cn, 0)).isFalse();
-
- // Check that the scheduled rebind is run
- mTestableLooper.moveTimeForward(ManagedServices.ON_BINDING_DIED_REBIND_DELAY_MS);
- mTestableLooper.processAllMessages();
- verify(service, times(1)).reregisterService(eq(cn), eq(0));
- }
-
- @Test
public void testPackageUninstall_packageNoLongerInApprovedList() throws Exception {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
@@ -1300,65 +1211,6 @@
}
@Test
- @EnableFlags(FLAG_NOTIFICATION_NLS_REBIND)
- public void testUpgradeAppNoIntentFilterNoRebind() throws Exception {
- Context context = spy(getContext());
- doReturn(true).when(context).bindServiceAsUser(any(), any(), anyInt(), any());
-
- ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles,
- mIpm, APPROVAL_BY_COMPONENT);
-
- List<String> packages = new ArrayList<>();
- packages.add("package");
- addExpectedServices(service, packages, 0);
-
- final ComponentName unapprovedComponent = ComponentName.unflattenFromString("package/C1");
- final ComponentName approvedComponent = ComponentName.unflattenFromString("package/C2");
-
- // Both components are approved initially
- mExpectedPrimaryComponentNames.clear();
- mExpectedPrimaryPackages.clear();
- mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2");
- mExpectedSecondaryComponentNames.clear();
- mExpectedSecondaryPackages.clear();
-
- loadXml(service);
-
- //Component package/C1 loses serviceInterface intent filter
- ManagedServices.Config config = service.getConfig();
- when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt()))
- .thenAnswer(new Answer<List<ResolveInfo>>() {
- @Override
- public List<ResolveInfo> answer(InvocationOnMock invocationOnMock)
- throws Throwable {
- Object[] args = invocationOnMock.getArguments();
- Intent invocationIntent = (Intent) args[0];
- if (invocationIntent != null) {
- if (invocationIntent.getAction().equals(config.serviceInterface)
- && packages.contains(invocationIntent.getPackage())) {
- List<ResolveInfo> dummyServices = new ArrayList<>();
- ResolveInfo resolveInfo = new ResolveInfo();
- ServiceInfo serviceInfo = new ServiceInfo();
- serviceInfo.packageName = invocationIntent.getPackage();
- serviceInfo.name = approvedComponent.getClassName();
- serviceInfo.permission = service.getConfig().bindPermission;
- resolveInfo.serviceInfo = serviceInfo;
- dummyServices.add(resolveInfo);
- return dummyServices;
- }
- }
- return new ArrayList<>();
- }
- });
-
- // Trigger package update
- service.onPackagesChanged(false, new String[]{"package"}, new int[]{0});
-
- assertFalse(service.isComponentEnabledForCurrentProfiles(unapprovedComponent));
- assertTrue(service.isComponentEnabledForCurrentProfiles(approvedComponent));
- }
-
- @Test
public void testSetPackageOrComponentEnabled() throws Exception {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
@@ -1371,21 +1223,6 @@
"user10package1/K", "user10.3/Component", "user10package2/L",
"user10.4/Component"}));
- // mock permissions for services
- PackageManager pm = mock(PackageManager.class);
- when(getContext().getPackageManager()).thenReturn(pm);
- List<ComponentName> enabledComponents = List.of(
- ComponentName.unflattenFromString("package/Comp"),
- ComponentName.unflattenFromString("package/C2"),
- ComponentName.unflattenFromString("again/M4"),
- ComponentName.unflattenFromString("user10package/B"),
- ComponentName.unflattenFromString("user10/Component"),
- ComponentName.unflattenFromString("user10package1/K"),
- ComponentName.unflattenFromString("user10.3/Component"),
- ComponentName.unflattenFromString("user10package2/L"),
- ComponentName.unflattenFromString("user10.4/Component"));
- mockServiceInfoWithMetaData(enabledComponents, service, pm, new ArrayMap<>());
-
for (int userId : expectedEnabled.keySet()) {
ArrayList<String> expectedForUser = expectedEnabled.get(userId);
for (int i = 0; i < expectedForUser.size(); i++) {
@@ -1447,90 +1284,6 @@
}
@Test
- @EnableFlags(FLAG_NOTIFICATION_NLS_REBIND)
- public void testSetPackageOrComponentEnabled_pkgInstalledAfterEnabling() throws Exception {
- ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
- mIpm, APPROVAL_BY_COMPONENT);
-
- final int userId = 0;
- final String validComponent = "again/M4";
- ArrayList<String> expectedEnabled = Lists.newArrayList("package/Comp", "package/C2",
- validComponent);
-
- PackageManager pm = mock(PackageManager.class);
- when(getContext().getPackageManager()).thenReturn(pm);
- service = spy(service);
-
- // Component again/M4 is a valid service and the package is available
- doReturn(true).when(service)
- .isValidService(ComponentName.unflattenFromString(validComponent), userId);
- when(pm.isPackageAvailable("again")).thenReturn(true);
-
- // "package" is not available and its services are not valid
- doReturn(false).when(service)
- .isValidService(ComponentName.unflattenFromString("package/Comp"), userId);
- doReturn(false).when(service)
- .isValidService(ComponentName.unflattenFromString("package/C2"), userId);
- when(pm.isPackageAvailable("package")).thenReturn(false);
-
- // Enable all components
- for (String component: expectedEnabled) {
- service.setPackageOrComponentEnabled(component, userId, true, true);
- }
-
- // Verify everything added is approved
- for (String component: expectedEnabled) {
- assertTrue("Not allowed: user: " + userId + " entry: " + component
- + " for approval level " + APPROVAL_BY_COMPONENT,
- service.isPackageOrComponentAllowed(component, userId));
- }
-
- // Add missing package "package"
- service.onPackagesChanged(false, new String[]{"package"}, new int[]{0});
-
- // Check that component of "package" are not enabled
- assertFalse(service.isComponentEnabledForCurrentProfiles(
- ComponentName.unflattenFromString("package/Comp")));
- assertFalse(service.isPackageOrComponentAllowed("package/Comp", userId));
-
- assertFalse(service.isComponentEnabledForCurrentProfiles(
- ComponentName.unflattenFromString("package/C2")));
- assertFalse(service.isPackageOrComponentAllowed("package/C2", userId));
-
- // Check that the valid components are still enabled
- assertTrue(service.isComponentEnabledForCurrentProfiles(
- ComponentName.unflattenFromString(validComponent)));
- assertTrue(service.isPackageOrComponentAllowed(validComponent, userId));
- }
-
- @Test
- @EnableFlags(FLAG_NOTIFICATION_NLS_REBIND)
- public void testSetPackageOrComponentEnabled_invalidComponent() throws Exception {
- ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
- mIpm, APPROVAL_BY_COMPONENT);
-
- final int userId = 0;
- final String invalidComponent = "package/Comp";
-
- PackageManager pm = mock(PackageManager.class);
- when(getContext().getPackageManager()).thenReturn(pm);
- service = spy(service);
-
- // Component is an invalid service and the package is available
- doReturn(false).when(service)
- .isValidService(ComponentName.unflattenFromString(invalidComponent), userId);
- when(pm.isPackageAvailable("package")).thenReturn(true);
- service.setPackageOrComponentEnabled(invalidComponent, userId, true, true);
-
- // Verify that the component was not enabled
- assertFalse("Not allowed: user: " + userId + " entry: " + invalidComponent
- + " for approval level " + APPROVAL_BY_COMPONENT,
- service.isPackageOrComponentAllowed(invalidComponent, userId));
- assertFalse(service.isComponentEnabledForCurrentProfiles(
- ComponentName.unflattenFromString(invalidComponent)));
- }
-
- @Test
public void testGetAllowedPackages_byUser() throws Exception {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
@@ -2191,7 +1944,7 @@
metaDataAutobindAllow.putBoolean(META_DATA_DEFAULT_AUTOBIND, true);
metaDatas.put(cn_allowed, metaDataAutobindAllow);
- mockServiceInfoWithMetaData(componentNames, service, pm, metaDatas);
+ mockServiceInfoWithMetaData(componentNames, service, metaDatas);
service.addApprovedList(cn_allowed.flattenToString(), 0, true);
service.addApprovedList(cn_disallowed.flattenToString(), 0, true);
@@ -2236,7 +1989,7 @@
metaDataAutobindDisallow.putBoolean(META_DATA_DEFAULT_AUTOBIND, false);
metaDatas.put(cn_disallowed, metaDataAutobindDisallow);
- mockServiceInfoWithMetaData(componentNames, service, pm, metaDatas);
+ mockServiceInfoWithMetaData(componentNames, service, metaDatas);
service.addApprovedList(cn_disallowed.flattenToString(), 0, true);
@@ -2275,7 +2028,7 @@
metaDataAutobindDisallow.putBoolean(META_DATA_DEFAULT_AUTOBIND, false);
metaDatas.put(cn_disallowed, metaDataAutobindDisallow);
- mockServiceInfoWithMetaData(componentNames, service, pm, metaDatas);
+ mockServiceInfoWithMetaData(componentNames, service, metaDatas);
service.addApprovedList(cn_disallowed.flattenToString(), 0, true);
@@ -2346,8 +2099,8 @@
}
private void mockServiceInfoWithMetaData(List<ComponentName> componentNames,
- ManagedServices service, PackageManager packageManager,
- ArrayMap<ComponentName, Bundle> metaDatas) throws RemoteException {
+ ManagedServices service, ArrayMap<ComponentName, Bundle> metaDatas)
+ throws RemoteException {
when(mIpm.getServiceInfo(any(), anyLong(), anyInt())).thenAnswer(
(Answer<ServiceInfo>) invocation -> {
ComponentName invocationCn = invocation.getArgument(0);
@@ -2362,39 +2115,6 @@
return null;
}
);
-
- // add components to queryIntentServicesAsUser response
- final List<String> packages = new ArrayList<>();
- for (ComponentName cn: componentNames) {
- packages.add(cn.getPackageName());
- }
- ManagedServices.Config config = service.getConfig();
- when(packageManager.queryIntentServicesAsUser(any(), anyInt(), anyInt())).
- thenAnswer(new Answer<List<ResolveInfo>>() {
- @Override
- public List<ResolveInfo> answer(InvocationOnMock invocationOnMock)
- throws Throwable {
- Object[] args = invocationOnMock.getArguments();
- Intent invocationIntent = (Intent) args[0];
- if (invocationIntent != null) {
- if (invocationIntent.getAction().equals(config.serviceInterface)
- && packages.contains(invocationIntent.getPackage())) {
- List<ResolveInfo> dummyServices = new ArrayList<>();
- for (ComponentName cn: componentNames) {
- ResolveInfo resolveInfo = new ResolveInfo();
- ServiceInfo serviceInfo = new ServiceInfo();
- serviceInfo.packageName = invocationIntent.getPackage();
- serviceInfo.name = cn.getClassName();
- serviceInfo.permission = service.getConfig().bindPermission;
- resolveInfo.serviceInfo = serviceInfo;
- dummyServices.add(resolveInfo);
- }
- return dummyServices;
- }
- }
- return new ArrayList<>();
- }
- });
}
private void resetComponentsAndPackages() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
index 2c645e0..6eb2f71 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -17,6 +17,9 @@
import static android.os.UserHandle.USER_ALL;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
+import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION;
+import static android.service.notification.Adjustment.TYPE_NEWS;
+import static android.service.notification.Adjustment.TYPE_PROMOTION;
import static com.android.server.notification.NotificationManagerService.DEFAULT_ALLOWED_ADJUSTMENTS;
@@ -28,7 +31,6 @@
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertNull;
-
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.any;
@@ -58,6 +60,8 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IntArray;
+import android.util.Log;
+import android.util.Slog;
import android.util.Xml;
import androidx.test.runner.AndroidJUnit4;
@@ -198,8 +202,6 @@
public void testWriteXml_userTurnedOffNAS() throws Exception {
int userId = ActivityManager.getCurrentUser();
- doReturn(true).when(mAssistants).isValidService(eq(mCn), eq(userId));
-
mAssistants.loadDefaultsFromConfig(true);
mAssistants.setPackageOrComponentEnabled(mCn.flattenToString(), userId, true,
@@ -435,10 +437,6 @@
public void testSetPackageOrComponentEnabled_onlyOnePackage() throws Exception {
ComponentName component1 = ComponentName.unflattenFromString("package/Component1");
ComponentName component2 = ComponentName.unflattenFromString("package/Component2");
-
- doReturn(true).when(mAssistants).isValidService(eq(component1), eq(mZero.id));
- doReturn(true).when(mAssistants).isValidService(eq(component2), eq(mZero.id));
-
mAssistants.setPackageOrComponentEnabled(component1.flattenToString(), mZero.id, true,
true, true);
verify(mNm, never()).setNotificationAssistantAccessGrantedForUserInternal(
@@ -584,7 +582,6 @@
public void testSetAdjustmentTypeSupportedState() throws Exception {
int userId = ActivityManager.getCurrentUser();
- doReturn(true).when(mAssistants).isValidService(eq(mCn), eq(userId));
mAssistants.loadDefaultsFromConfig(true);
mAssistants.setPackageOrComponentEnabled(mCn.flattenToString(), userId, true,
true, true);
@@ -608,7 +605,6 @@
public void testSetAdjustmentTypeSupportedState_readWriteXml_entries() throws Exception {
int userId = ActivityManager.getCurrentUser();
- doReturn(true).when(mAssistants).isValidService(eq(mCn), eq(userId));
mAssistants.loadDefaultsFromConfig(true);
mAssistants.setPackageOrComponentEnabled(mCn.flattenToString(), userId, true,
true, true);
@@ -632,7 +628,6 @@
public void testSetAdjustmentTypeSupportedState_readWriteXml_empty() throws Exception {
int userId = ActivityManager.getCurrentUser();
- doReturn(true).when(mAssistants).isValidService(eq(mCn), eq(userId));
mAssistants.loadDefaultsFromConfig(true);
mAssistants.setPackageOrComponentEnabled(mCn.flattenToString(), userId, true,
true, true);
@@ -690,4 +685,47 @@
assertThat(mAssistants.getAllowedAssistantAdjustments())
.containsExactlyElementsIn(DEFAULT_ALLOWED_ADJUSTMENTS);
}
+
+ @Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+ public void testSetAssistantAdjustmentKeyTypeState_allow() {
+ assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
+ .containsExactly(TYPE_PROMOTION);
+
+ mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true);
+
+ assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
+ .containsExactlyElementsIn(List.of(TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION));
+ }
+
+ @Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+ public void testSetAssistantAdjustmentKeyTypeState_disallow() {
+ mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false);
+ assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).isEmpty();
+ }
+
+ @Test
+ @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+ public void testDisallowAdjustmentKeyType_readWriteXml() throws Exception {
+ mAssistants.loadDefaultsFromConfig(true);
+ mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false);
+ mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, true);
+ mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true);
+
+ writeXmlAndReload(USER_ALL);
+
+ assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
+ .containsExactlyElementsIn(List.of(TYPE_NEWS, TYPE_CONTENT_RECOMMENDATION));
+ }
+
+ @Test
+ public void testDefaultAllowedKeyAdjustments_readWriteXml() throws Exception {
+ mAssistants.loadDefaultsFromConfig(true);
+
+ writeXmlAndReload(USER_ALL);
+
+ assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
+ .containsExactly(TYPE_PROMOTION);
+ }
}
\ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index cbfdc5f..eae587b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -43,8 +43,8 @@
import static android.app.Notification.FLAG_USER_INITIATED_JOB;
import static android.app.Notification.GROUP_ALERT_CHILDREN;
import static android.app.Notification.VISIBILITY_PRIVATE;
-import static android.app.NotificationChannel.NEWS_ID;
import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
+import static android.app.NotificationChannel.NEWS_ID;
import static android.app.NotificationChannel.PROMOTIONS_ID;
import static android.app.NotificationChannel.RECS_ID;
import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
@@ -78,7 +78,6 @@
import static android.app.StatusBarManager.ACTION_KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED;
import static android.app.StatusBarManager.EXTRA_KM_PRIVATE_NOTIFS_ALLOWED;
import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG;
-import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_RULES;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.PackageManager.FEATURE_TELECOM;
import static android.content.pm.PackageManager.FEATURE_WATCH;
@@ -114,6 +113,7 @@
import static android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION;
import static android.service.notification.Flags.FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT;
import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION;
import static android.service.notification.Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
@@ -336,12 +336,12 @@
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;
-import com.google.android.collect.Lists;
-import com.google.common.collect.ImmutableList;
-
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+import com.google.android.collect.Lists;
+import com.google.common.collect.ImmutableList;
+
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -366,7 +366,6 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
-import java.io.OutputStream;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
@@ -2685,6 +2684,41 @@
}
@Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION})
+ public void testAggregateGroups_RemoveAppSummary_onClassification() throws Exception {
+ final String originalGroupName = "originalGroup";
+ final int summaryId = 0;
+ final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel,
+ summaryId + 1, originalGroupName, false);
+ mService.addNotification(r1);
+ final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel,
+ summaryId + 2, originalGroupName, false);
+ mService.addNotification(r2);
+ final NotificationRecord summary = generateNotificationRecord(mTestNotificationChannel,
+ summaryId, originalGroupName, true);
+ mService.addNotification(summary);
+ final String originalGroupKey = summary.getGroupKey();
+ assertThat(mService.mSummaryByGroupKey).containsEntry(originalGroupKey, summary);
+
+ // Regroup first child notification
+ r1.setOverrideGroupKey("newGroup");
+ // Check that removeAppProvidedSummaryOnClassificationLocked is null
+ // => there is still one child left in the original group
+ assertThat(mService.removeAppProvidedSummaryOnClassificationLocked(r1.getKey(),
+ originalGroupKey)).isNull();
+
+ // Regroup last child notification
+ r2.setOverrideGroupKey("newGroup");
+ // Check that removeAppProvidedSummaryOnClassificationLocked returns the original summary
+ // and that the original app-provided summary is canceled
+ assertThat(mService.removeAppProvidedSummaryOnClassificationLocked(r2.getKey(),
+ originalGroupKey)).isEqualTo(summary);
+ waitForIdle();
+ verify(mWorkerHandler, times(1)).scheduleCancelNotification(any(), eq(summaryId));
+ assertThat(mService.mSummaryByGroupKey).doesNotContainKey(originalGroupKey);
+ }
+
+ @Test
@EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testUngroupingAggregateSummary() throws Exception {
final String originalGroupName = "originalGroup";
@@ -7480,6 +7514,64 @@
}
@Test
+ @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
+ public void testClassificationChannelAdjustmentsLogged() throws Exception {
+ NotificationManagerService.WorkerHandler handler = mock(
+ NotificationManagerService.WorkerHandler.class);
+ mService.setHandler(handler);
+ when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
+ when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
+ when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
+
+ // Set up notifications that will be adjusted
+ final NotificationRecord r1 = spy(generateNotificationRecord(
+ mTestNotificationChannel, 1, null, true));
+ when(r1.getLifespanMs(anyLong())).thenReturn(234);
+
+ r1.getSbn().setInstanceId(mNotificationInstanceIdSequence.newInstanceId());
+ // Enqueues the notification to be posted, so hasPosted will be false.
+ mService.addEnqueuedNotification(r1);
+
+ // Test an adjustment for an enqueued notification
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_TYPE, Adjustment.TYPE_NEWS);
+ Adjustment adjustment1 = new Adjustment(
+ r1.getSbn().getPackageName(), r1.getKey(), signals, "",
+ r1.getUser().getIdentifier());
+ mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment1);
+ assertTrue(mService.checkLastClassificationChannelLog(false /*hasPosted*/,
+ true /*isAlerting*/, 3 /*TYPE_NEWS*/, 234));
+
+ // Set up notifications that will be adjusted
+ // This notification starts on a low importance channel, so isAlerting is false.
+ NotificationChannel mLowImportanceNotificationChannel = new NotificationChannel(
+ TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_LOW);
+ final NotificationRecord r2 = spy(generateNotificationRecord(
+ mLowImportanceNotificationChannel, 1, null, true));
+ when(r2.getLifespanMs(anyLong())).thenReturn(345);
+
+ r2.getSbn().setInstanceId(mNotificationInstanceIdSequence.newInstanceId());
+ // Adds the notification as already posted, so hasPosted will be true.
+ mService.addNotification(r2);
+ // The signal is removed when used so it has to be readded.
+ signals.putInt(Adjustment.KEY_TYPE, Adjustment.TYPE_NEWS);
+ Adjustment adjustment2 = new Adjustment(
+ r2.getSbn().getPackageName(), r2.getKey(), signals, "",
+ r2.getUser().getIdentifier());
+ mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment2);
+ assertTrue(mService.checkLastClassificationChannelLog(true /*hasPosted*/,
+ false /*isAlerting*/, 3 /*TYPE_NEWS*/, 345)); // currently failing
+
+ signals.putInt(Adjustment.KEY_TYPE, Adjustment.TYPE_PROMOTION);
+ Adjustment adjustment3 = new Adjustment(
+ r2.getSbn().getPackageName(), r2.getKey(), signals, "",
+ r2.getUser().getIdentifier());
+ mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment3);
+ assertTrue(mService.checkLastClassificationChannelLog(true /*hasPosted*/,
+ false /*isAlerting*/, 1 /*TYPE_PROMOTION*/, 345));
+ }
+
+ @Test
public void testAdjustmentToImportanceNone_cancelsNotification() throws Exception {
NotificationManagerService.WorkerHandler handler = mock(
NotificationManagerService.WorkerHandler.class);
@@ -14365,9 +14457,10 @@
r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue();
}
- private NotificationRecord createBigPictureRecord(boolean isBigPictureStyle, boolean hasImage,
- boolean isImageBitmap, boolean isExpired) {
- Notification.Builder builder = new Notification.Builder(mContext);
+ private Notification createBigPictureNotification(boolean isBigPictureStyle, boolean hasImage,
+ boolean isImageBitmap) {
+ Notification.Builder builder = new Notification.Builder(mContext)
+ .setSmallIcon(android.R.drawable.sym_def_app_icon);
Notification.BigPictureStyle style = new Notification.BigPictureStyle();
if (isBigPictureStyle && hasImage) {
@@ -14383,12 +14476,18 @@
Notification notification = builder.setChannelId(TEST_CHANNEL_ID).build();
+ return notification;
+ }
+
+ private NotificationRecord createBigPictureRecord(boolean isBigPictureStyle, boolean hasImage,
+ boolean isImageBitmap, boolean isExpired) {
long timePostedMs = System.currentTimeMillis();
if (isExpired) {
timePostedMs -= BITMAP_DURATION.toMillis();
}
StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
- notification, UserHandle.getUserHandleForUid(mUid), null, timePostedMs);
+ createBigPictureNotification(isBigPictureStyle, hasImage, isImageBitmap),
+ UserHandle.getUserHandleForUid(mUid), null, timePostedMs);
return new NotificationRecord(mContext, sbn, mTestNotificationChannel);
}
@@ -14400,6 +14499,33 @@
}
@Test
+ public void testRemoveBitmaps_canRemoveRevokedDelegate() throws Exception {
+ Notification n = createBigPictureNotification(true, true, true);
+ long timePostedMs = System.currentTimeMillis();
+ timePostedMs -= BITMAP_DURATION.toMillis();
+
+ when(mPermissionHelper.hasPermission(UID_O)).thenReturn(true);
+ when(mPackageManagerInternal.isSameApp(PKG_O, UID_O, UserHandle.getUserId(UID_O)))
+ .thenReturn(true);
+ mService.mPreferencesHelper.createNotificationChannel(PKG_O, UID_O,
+ mTestNotificationChannel, true /* fromTargetApp */, false, UID_O,
+ false);
+ mBinderService.createNotificationChannels(PKG_O, new ParceledListSlice(
+ Arrays.asList(mTestNotificationChannel, mSilentChannel, mMinChannel)));
+
+ StatusBarNotification sbn = new StatusBarNotification(PKG_O, "old.delegate", 8, "tag",
+ UID_O, 0, n, UserHandle.getUserHandleForUid(UID_O), null, timePostedMs);
+
+ mService.addNotification(new NotificationRecord(mContext, sbn, mTestNotificationChannel));
+ mInternalService.removeBitmaps();
+
+ waitForIdle();
+
+ verify(mWorkerHandler, times(1))
+ .post(any(NotificationManagerService.EnqueueNotificationRunnable.class));
+ }
+
+ @Test
public void testRemoveBitmaps_notBigPicture_noRepost() {
addRecordAndRemoveBitmaps(
createBigPictureRecord(
@@ -17067,6 +17193,7 @@
NotificationManagerService.WorkerHandler handler = mock(
NotificationManagerService.WorkerHandler.class);
mService.setHandler(handler);
+ when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
Bundle signals = new Bundle();
signals.putInt(KEY_TYPE, TYPE_NEWS);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
index 07d25df..ba91ca2 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
@@ -52,6 +52,14 @@
}
public SensitiveLog lastSensitiveLog = null;
+ private static class ClassificationChannelLog {
+ public boolean hasPosted;
+ public boolean isAlerting;
+ public long classification;
+ public long lifetime;
+ }
+ public ClassificationChannelLog lastClassificationChannelLog = null;
+
TestableNotificationManagerService(Context context, NotificationRecordLogger logger,
InstanceIdSequence notificationInstanceIdSequence) {
super(context, logger, notificationInstanceIdSequence);
@@ -211,4 +219,29 @@
public interface ComponentPermissionChecker {
int check(String permission, int uid, int owningUid, boolean exported);
}
+
+ @Override
+ protected void logClassificationChannelAdjustmentReceived(boolean hasPosted, boolean isAlerting,
+ int classification, int lifetimeMs) {
+ lastClassificationChannelLog = new ClassificationChannelLog();
+ lastClassificationChannelLog.hasPosted = hasPosted;
+ lastClassificationChannelLog.isAlerting = isAlerting;
+ lastClassificationChannelLog.classification = classification;
+ lastClassificationChannelLog.lifetime = lifetimeMs;
+ }
+
+ /**
+ * Returns true if the last recorded classification channel log has all the values specified.
+ */
+ public boolean checkLastClassificationChannelLog(boolean hasPosted, boolean isAlerting,
+ int classification, int lifetime) {
+ if (lastClassificationChannelLog == null) {
+ return false;
+ }
+
+ return hasPosted == lastClassificationChannelLog.hasPosted
+ && isAlerting == lastClassificationChannelLog.isAlerting
+ && classification == lastClassificationChannelLog.classification
+ && lifetime == lastClassificationChannelLog.lifetime;
+ }
}
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 0019b3e..4b94e10 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -493,6 +493,22 @@
}
@Test
+ public void testZenOn_RepeatCallers_CallTypesBlocked() {
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
+ // Any call allowed but no repeat callers
+ mZenModeHelper.mConsolidatedPolicy = new Policy(PRIORITY_CATEGORY_CALLS,
+ PRIORITY_SENDERS_ANY, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
+
+ verifyApplyRestrictions(true, true,
+ AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
+ verifyApplyRestrictions(true, true,
+ AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
+ }
+
+
+ @Test
public void testZenOn_StarredCallers_CallTypesBlocked() {
mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
@@ -501,7 +517,7 @@
| PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
| PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
| PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
- | PRIORITY_CATEGORY_SYSTEM,
+ | PRIORITY_CATEGORY_SYSTEM | PRIORITY_CATEGORY_REPEAT_CALLERS,
PRIORITY_SENDERS_STARRED,
PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
mZenModeHelper.applyRestrictions();
diff --git a/services/tests/vibrator/AndroidManifest.xml b/services/tests/vibrator/AndroidManifest.xml
index c0f514f..850884f 100644
--- a/services/tests/vibrator/AndroidManifest.xml
+++ b/services/tests/vibrator/AndroidManifest.xml
@@ -32,6 +32,9 @@
<uses-permission android:name="android.permission.VIBRATE_ALWAYS_ON" />
<!-- Required to play system-only haptic feedback constants -->
<uses-permission android:name="android.permission.VIBRATE_SYSTEM_CONSTANTS" />
+ <!-- Required to play vendor effects and start vendor sessions -->
+ <uses-permission android:name="android.permission.VIBRATE_VENDOR_EFFECTS" />
+ <uses-permission android:name="android.permission.START_VIBRATION_SESSIONS" />
<application android:debuggable="true">
<uses-library android:name="android.test.mock" android:required="true" />
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index dfdd0cd..88ba9e3 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -35,6 +35,7 @@
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@@ -83,6 +84,8 @@
import android.os.VibratorInfo;
import android.os.test.FakeVibrator;
import android.os.test.TestLooper;
+import android.os.vibrator.IVibrationSession;
+import android.os.vibrator.IVibrationSessionCallback;
import android.os.vibrator.PrebakedSegment;
import android.os.vibrator.PrimitiveSegment;
import android.os.vibrator.StepSegment;
@@ -195,6 +198,7 @@
new SparseArray<>();
private final List<HalVibration> mPendingVibrations = new ArrayList<>();
+ private final List<VendorVibrationSession> mPendingSessions = new ArrayList<>();
private VibratorManagerService mService;
private Context mContextSpy;
@@ -264,6 +268,11 @@
grantPermission(android.Manifest.permission.VIBRATE);
// Cancel any pending vibration from tests, including external vibrations.
cancelVibrate(mService);
+ // End pending sessions.
+ for (VendorVibrationSession session : mPendingSessions) {
+ session.cancelSession();
+ }
+ mTestLooper.dispatchAll();
// Wait until pending vibrations end asynchronously.
for (HalVibration vibration : mPendingVibrations) {
vibration.waitForEnd();
@@ -1229,6 +1238,36 @@
.anyMatch(PrebakedSegment.class::isInstance));
}
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ @Test
+ public void vibrate_withOngoingHigherImportanceSession_ignoresEffect() throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1);
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1);
+ fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+ VibratorManagerService service = createSystemReadyService();
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1);
+ mTestLooper.dispatchAll();
+ assertThat(session.getStatus()).isEqualTo(Status.RUNNING);
+ verify(callback).onStarted(any(IVibrationSession.class));
+
+ HalVibration vibration = vibrateAndWaitUntilFinished(service,
+ VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
+ HAPTIC_FEEDBACK_ATTRS);
+ mTestLooper.dispatchAll();
+
+ assertThat(session.getStatus()).isEqualTo(Status.RUNNING);
+ assertThat(vibration.getStatus()).isEqualTo(Status.IGNORED_FOR_HIGHER_IMPORTANCE);
+ verify(callback, never()).onFinishing();
+ verify(callback, never()).onFinished(anyInt());
+ // The second vibration shouldn't have played any prebaked segment.
+ assertFalse(fakeVibrator.getAllEffectSegments().stream()
+ .anyMatch(PrebakedSegment.class::isInstance));
+ }
+
@Test
public void vibrate_withOngoingLowerImportanceVibration_cancelsOngoingEffect()
throws Exception {
@@ -1289,6 +1328,36 @@
.filter(PrebakedSegment.class::isInstance).count());
}
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ @Test
+ public void vibrate_withOngoingLowerImportanceSession_cancelsOngoingSession() throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1);
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1);
+ fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ VibratorManagerService service = createSystemReadyService();
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ VendorVibrationSession session = startSession(service, HAPTIC_FEEDBACK_ATTRS, callback, 1);
+ mTestLooper.dispatchAll();
+ assertThat(session.getStatus()).isEqualTo(Status.RUNNING);
+ verify(callback).onStarted(any(IVibrationSession.class));
+
+ HalVibration vibration = vibrateAndWaitUntilFinished(service,
+ VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
+ HAPTIC_FEEDBACK_ATTRS);
+ mTestLooper.dispatchAll();
+
+ assertThat(session.getStatus()).isEqualTo(Status.CANCELLED_SUPERSEDED);
+ assertThat(vibration.getStatus()).isEqualTo(Status.FINISHED);
+ verify(callback).onFinishing();
+ verify(callback).onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_CANCELED));
+ // One segment played is the prebaked CLICK from the new vibration.
+ assertEquals(1, mVibratorProviders.get(1).getAllEffectSegments().stream()
+ .filter(PrebakedSegment.class::isInstance).count());
+ }
+
@Test
public void vibrate_withOngoingSameImportancePipelinedVibration_continuesOngoingEffect()
throws Exception {
@@ -1416,16 +1485,16 @@
// The native callback will be dispatched manually in this test.
mTestLooper.stopAutoDispatchAndIgnoreExceptions();
- ArgumentCaptor<VibratorManagerService.OnSyncedVibrationCompleteListener> listenerCaptor =
+ ArgumentCaptor<VibratorManagerService.VibratorManagerNativeCallbacks> listenerCaptor =
ArgumentCaptor.forClass(
- VibratorManagerService.OnSyncedVibrationCompleteListener.class);
+ VibratorManagerService.VibratorManagerNativeCallbacks.class);
verify(mNativeWrapperMock).init(listenerCaptor.capture());
CountDownLatch triggerCountDown = new CountDownLatch(1);
// Mock trigger callback on registered listener right after the synced vibration starts.
when(mNativeWrapperMock.prepareSynced(eq(new int[]{1, 2}))).thenReturn(true);
when(mNativeWrapperMock.triggerSynced(anyLong())).then(answer -> {
- listenerCaptor.getValue().onComplete(answer.getArgument(0));
+ listenerCaptor.getValue().onSyncedVibrationComplete(answer.getArgument(0));
triggerCountDown.countDown();
return true;
});
@@ -2318,6 +2387,34 @@
assertEquals(Arrays.asList(false), mVibratorProviders.get(1).getExternalControlStates());
}
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ @Test
+ public void onExternalVibration_withOngoingHigherImportanceSession_ignoreNewVibration()
+ throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1);
+ mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
+ VibratorManagerService service = createSystemReadyService();
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1);
+ mTestLooper.dispatchAll();
+ verify(callback).onStarted(any(IVibrationSession.class));
+
+ ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME,
+ AUDIO_ALARM_ATTRS, mock(IExternalVibrationController.class));
+ ExternalVibrationScale scale =
+ mExternalVibratorService.onExternalVibrationStart(externalVibration);
+ // External vibration is ignored.
+ assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel);
+
+ // Session still running.
+ assertThat(session.getStatus()).isEqualTo(Status.RUNNING);
+ verify(callback, never()).onFinishing();
+ verify(callback, never()).onFinished(anyInt());
+ }
+
@Test
public void onExternalVibration_withNewSameImportanceButRepeating_cancelsOngoingVibration()
throws Exception {
@@ -2373,6 +2470,36 @@
assertEquals(Arrays.asList(false), mVibratorProviders.get(1).getExternalControlStates());
}
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ @Test
+ public void onExternalVibration_withOngoingLowerImportanceSession_cancelsOngoingSession()
+ throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1);
+ mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
+ VibratorManagerService service = createSystemReadyService();
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ VendorVibrationSession session = startSession(service, HAPTIC_FEEDBACK_ATTRS, callback, 1);
+ mTestLooper.dispatchAll();
+ verify(callback).onStarted(any(IVibrationSession.class));
+
+ ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME,
+ AUDIO_ALARM_ATTRS, mock(IExternalVibrationController.class));
+ ExternalVibrationScale scale =
+ mExternalVibratorService.onExternalVibrationStart(externalVibration);
+ assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel);
+ mTestLooper.dispatchAll();
+
+ // Session is cancelled.
+ assertThat(session.getStatus()).isEqualTo(Status.CANCELLED_SUPERSEDED);
+ verify(callback).onFinishing();
+ verify(callback).onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_CANCELED));
+ assertEquals(Arrays.asList(false, true),
+ mVibratorProviders.get(1).getExternalControlStates());
+ }
+
@Test
public void onExternalVibration_withRingtone_usesRingerModeSettings() {
mockVibrators(1);
@@ -2638,6 +2765,376 @@
}
@Test
+ @DisableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_withoutFeatureFlag_throwsException() throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ int vibratorId = 1;
+ mockVibrators(vibratorId);
+ VibratorManagerService service = createSystemReadyService();
+
+ IVibrationSessionCallback callback = mock(IVibrationSessionCallback.class);
+ assertThrows("Expected starting session without feature flag to fail!",
+ UnsupportedOperationException.class,
+ () -> startSession(service, RINGTONE_ATTRS, callback, vibratorId));
+ mTestLooper.dispatchAll();
+
+ verify(mNativeWrapperMock, never()).startSession(anyLong(), any(int[].class));
+ verify(callback, never()).onStarted(any(IVibrationSession.class));
+ verify(callback, never()).onFinishing();
+ verify(callback, never()).onFinished(anyInt());
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_withoutCapability_doesNotStart() throws Exception {
+ int vibratorId = 1;
+ mockVibrators(vibratorId);
+ VibratorManagerService service = createSystemReadyService();
+
+ IVibrationSessionCallback callback = mock(IVibrationSessionCallback.class);
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS,
+ callback, vibratorId);
+ mTestLooper.dispatchAll();
+
+ assertThat(session.getStatus()).isEqualTo(Status.IGNORED_UNSUPPORTED);
+ verify(mNativeWrapperMock, never()).startSession(anyLong(), any(int[].class));
+ verify(callback, never()).onFinishing();
+ verify(callback)
+ .onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_UNSUPPORTED));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_withoutCallback_doesNotStart() {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ int vibratorId = 1;
+ mockVibrators(vibratorId);
+ VibratorManagerService service = createSystemReadyService();
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS,
+ /* callback= */ null, vibratorId);
+ mTestLooper.dispatchAll();
+
+ assertThat(session).isNull();
+ verify(mNativeWrapperMock, never()).startSession(anyLong(), any(int[].class));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_withoutVibratorIds_doesNotStart() throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1);
+ VibratorManagerService service = createSystemReadyService();
+
+ int[] nullIds = null;
+ IVibrationSessionCallback callback = mock(IVibrationSessionCallback.class);
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, nullIds);
+ assertThat(session.getStatus()).isEqualTo(Status.IGNORED_UNSUPPORTED);
+
+ int[] emptyIds = {};
+ session = startSession(service, RINGTONE_ATTRS, callback, emptyIds);
+ assertThat(session.getStatus()).isEqualTo(Status.IGNORED_UNSUPPORTED);
+
+ mTestLooper.dispatchAll();
+
+ verify(mNativeWrapperMock, never()).startSession(anyLong(), any(int[].class));
+ verify(callback, never()).onFinishing();
+ verify(callback, times(2))
+ .onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_UNSUPPORTED));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_badVibratorId_failsToStart() throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1, 2);
+ when(mNativeWrapperMock.startSession(anyLong(), any(int[].class))).thenReturn(false);
+ doReturn(false).when(mNativeWrapperMock).startSession(anyLong(), eq(new int[] {1, 3}));
+ doReturn(true).when(mNativeWrapperMock).startSession(anyLong(), eq(new int[] {1, 2}));
+ VibratorManagerService service = createSystemReadyService();
+
+ IBinder token = mock(IBinder.class);
+ IVibrationSessionCallback callback = mock(IVibrationSessionCallback.class);
+ doReturn(token).when(callback).asBinder();
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1, 3);
+ mTestLooper.dispatchAll();
+
+ assertThat(session.getStatus()).isEqualTo(Status.IGNORED_UNSUPPORTED);
+ verify(mNativeWrapperMock).startSession(eq(session.getSessionId()), eq(new int[] {1, 3}));
+ verify(callback, never()).onStarted(any(IVibrationSession.class));
+ verify(callback, never()).onFinishing();
+ verify(callback)
+ .onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_UNSUPPORTED));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_thenFinish_returnsSuccessAfterCallback() throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1, 2);
+ VibratorManagerService service = createSystemReadyService();
+ int sessionFinishDelayMs = 200;
+ IVibrationSessionCallback callback = mockSessionCallbacks(sessionFinishDelayMs);
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1, 2);
+ mTestLooper.dispatchAll();
+
+ verify(mNativeWrapperMock).startSession(eq(session.getSessionId()), eq(new int[] {1, 2}));
+ ArgumentCaptor<IVibrationSession> captor = ArgumentCaptor.forClass(IVibrationSession.class);
+ verify(callback).onStarted(captor.capture());
+
+ captor.getValue().finishSession();
+
+ // Session not ended until HAL callback.
+ assertThat(session.getStatus()).isEqualTo(Status.RUNNING);
+
+ // Dispatch HAL callbacks.
+ mTestLooper.moveTimeForward(sessionFinishDelayMs);
+ mTestLooper.dispatchAll();
+
+ assertThat(session.getStatus()).isEqualTo(Status.FINISHED);
+ verify(callback).onFinishing();
+ verify(callback).onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_SUCCESS));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_thenSendCancelSignal_cancelsSession() throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1, 2);
+ VibratorManagerService service = createSystemReadyService();
+ int sessionFinishDelayMs = 200;
+ IVibrationSessionCallback callback = mockSessionCallbacks(sessionFinishDelayMs);
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1, 2);
+ mTestLooper.dispatchAll();
+
+ verify(mNativeWrapperMock).startSession(eq(session.getSessionId()), eq(new int[] {1, 2}));
+ ArgumentCaptor<IVibrationSession> captor = ArgumentCaptor.forClass(IVibrationSession.class);
+ verify(callback).onStarted(captor.capture());
+
+ session.getCancellationSignal().cancel();
+ mTestLooper.dispatchAll();
+
+ assertThat(session.getStatus()).isEqualTo(Status.CANCELLED_BY_USER);
+ verify(callback).onFinishing();
+ verify(callback).onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_CANCELED));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_thenCancel_returnsCancelStatus() throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1, 2);
+ VibratorManagerService service = createSystemReadyService();
+ // Delay not applied when session is aborted.
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1, 2);
+ mTestLooper.dispatchAll();
+
+ verify(mNativeWrapperMock).startSession(eq(session.getSessionId()), eq(new int[] {1, 2}));
+ ArgumentCaptor<IVibrationSession> captor = ArgumentCaptor.forClass(IVibrationSession.class);
+ verify(callback).onStarted(captor.capture());
+
+ captor.getValue().cancelSession();
+ mTestLooper.dispatchAll();
+
+ assertThat(session.getStatus()).isEqualTo(Status.CANCELLED_BY_USER);
+ verify(callback).onFinishing();
+ verify(callback).onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_CANCELED));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_finishThenCancel_returnsRightAwayWithFinishedStatus()
+ throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1, 2);
+ VibratorManagerService service = createSystemReadyService();
+ // Delay not applied when session is aborted.
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1, 2);
+ mTestLooper.dispatchAll();
+
+ verify(mNativeWrapperMock).startSession(eq(session.getSessionId()), eq(new int[] {1, 2}));
+ ArgumentCaptor<IVibrationSession> captor = ArgumentCaptor.forClass(IVibrationSession.class);
+ verify(callback).onStarted(captor.capture());
+
+ captor.getValue().finishSession();
+ mTestLooper.dispatchAll();
+ assertThat(session.getStatus()).isEqualTo(Status.RUNNING);
+
+ captor.getValue().cancelSession();
+ mTestLooper.dispatchAll();
+
+ assertThat(session.getStatus()).isEqualTo(Status.FINISHED);
+ verify(callback).onFinishing();
+ verify(callback).onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_SUCCESS));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_thenHalCancels_returnsCancelStatus()
+ throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1, 2);
+ VibratorManagerService service = createSystemReadyService();
+ ArgumentCaptor<VibratorManagerService.VibratorManagerNativeCallbacks> listenerCaptor =
+ ArgumentCaptor.forClass(
+ VibratorManagerService.VibratorManagerNativeCallbacks.class);
+ verify(mNativeWrapperMock).init(listenerCaptor.capture());
+ doReturn(true).when(mNativeWrapperMock).startSession(anyLong(), any(int[].class));
+
+ IBinder token = mock(IBinder.class);
+ IVibrationSessionCallback callback = mock(IVibrationSessionCallback.class);
+ doReturn(token).when(callback).asBinder();
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1, 2);
+ mTestLooper.dispatchAll();
+
+ verify(mNativeWrapperMock).startSession(eq(session.getSessionId()), eq(new int[] {1, 2}));
+ verify(callback).onStarted(any(IVibrationSession.class));
+
+ // Mock HAL ending session unexpectedly.
+ listenerCaptor.getValue().onVibrationSessionComplete(session.getSessionId());
+ mTestLooper.dispatchAll();
+
+ assertThat(session.getStatus()).isEqualTo(Status.CANCELLED_BY_UNKNOWN_REASON);
+ verify(callback).onFinishing();
+ verify(callback).onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_CANCELED));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_withPowerMode_usesPowerModeState() throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1);
+ VibratorManagerService service = createSystemReadyService();
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
+ VendorVibrationSession session1 = startSession(service, HAPTIC_FEEDBACK_ATTRS, callback, 1);
+ VendorVibrationSession session2 = startSession(service, RINGTONE_ATTRS, callback, 1);
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<IVibrationSession> captor = ArgumentCaptor.forClass(IVibrationSession.class);
+ verify(callback).onStarted(captor.capture());
+ captor.getValue().cancelSession();
+ mTestLooper.dispatchAll();
+
+ mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
+ VendorVibrationSession session3 = startSession(service, HAPTIC_FEEDBACK_ATTRS, callback, 1);
+ mTestLooper.dispatchAll();
+
+ verify(mNativeWrapperMock, never())
+ .startSession(eq(session1.getSessionId()), any(int[].class));
+ verify(mNativeWrapperMock).startSession(eq(session2.getSessionId()), eq(new int[] {1}));
+ verify(mNativeWrapperMock).startSession(eq(session3.getSessionId()), eq(new int[] {1}));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_withOngoingHigherImportanceVibration_ignoresSession()
+ throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1);
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1);
+ fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+ VibratorManagerService service = createSystemReadyService();
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ VibrationEffect effect = VibrationEffect.createWaveform(
+ new long[]{10, 10_000}, new int[]{128, 255}, -1);
+ vibrate(service, effect, ALARM_ATTRS);
+
+ // VibrationThread will start this vibration async.
+ // Wait until second step started to ensure the noteVibratorOn was triggered.
+ assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2,
+ service, TEST_TIMEOUT_MILLIS));
+
+ VendorVibrationSession session = startSession(service, HAPTIC_FEEDBACK_ATTRS, callback, 1);
+ mTestLooper.dispatchAll();
+
+ verify(mNativeWrapperMock, never())
+ .startSession(eq(session.getSessionId()), any(int[].class));
+ assertThat(session.getStatus()).isEqualTo(Status.IGNORED_FOR_HIGHER_IMPORTANCE);
+ verify(callback, never()).onFinishing();
+ verify(callback).onFinished(eq(android.os.vibrator.VendorVibrationSession.STATUS_IGNORED));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_withOngoingLowerImportanceVibration_cancelsOngoing()
+ throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1);
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1);
+ fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+ fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ VibratorManagerService service = createSystemReadyService();
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ VibrationEffect effect = VibrationEffect.createWaveform(
+ new long[]{10, 10_000}, new int[]{128, 255}, -1);
+ HalVibration vibration = vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS);
+
+ // VibrationThread will start this vibration async.
+ // Wait until second step started to ensure the noteVibratorOn was triggered.
+ assertTrue(waitUntil(s -> fakeVibrator.getAmplitudes().size() == 2, service,
+ TEST_TIMEOUT_MILLIS));
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1);
+ vibration.waitForEnd();
+ assertTrue(waitUntil(s -> session.isStarted(), service, TEST_TIMEOUT_MILLIS));
+ mTestLooper.dispatchAll();
+
+ assertThat(vibration.getStatus()).isEqualTo(Status.CANCELLED_SUPERSEDED);
+ assertThat(session.getStatus()).isEqualTo(Status.RUNNING);
+ verify(mNativeWrapperMock).startSession(eq(session.getSessionId()), eq(new int[] { 1 }));
+ verify(callback).onStarted(any(IVibrationSession.class));
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
+ public void startVibrationSession_withOngoingLowerImportanceExternalVibration_cancelsOngoing()
+ throws Exception {
+ mockCapabilities(IVibratorManager.CAP_START_SESSIONS);
+ mockVibrators(1);
+ mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
+ mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ VibratorManagerService service = createSystemReadyService();
+ IVibrationSessionCallback callback =
+ mockSessionCallbacks(/* delayToEndSessionMillis= */ TEST_TIMEOUT_MILLIS);
+
+ IBinder firstToken = mock(IBinder.class);
+ IExternalVibrationController controller = mock(IExternalVibrationController.class);
+ ExternalVibration externalVibration = new ExternalVibration(UID, PACKAGE_NAME,
+ AUDIO_ALARM_ATTRS,
+ controller, firstToken);
+ ExternalVibrationScale scale =
+ mExternalVibratorService.onExternalVibrationStart(externalVibration);
+
+ VendorVibrationSession session = startSession(service, RINGTONE_ATTRS, callback, 1);
+ mTestLooper.dispatchAll();
+
+ assertNotEquals(ExternalVibrationScale.ScaleLevel.SCALE_MUTE, scale.scaleLevel);
+ // The external vibration should have been cancelled
+ verify(controller).mute();
+ assertEquals(Arrays.asList(false, true, false),
+ mVibratorProviders.get(1).getExternalControlStates());
+ verify(mNativeWrapperMock).startSession(eq(session.getSessionId()), eq(new int[] { 1 }));
+ verify(callback).onStarted(any(IVibrationSession.class));
+ }
+
+ @Test
public void frameworkStats_externalVibration_reportsAllMetrics() throws Exception {
mockVibrators(1);
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
@@ -3050,6 +3547,30 @@
when(mNativeWrapperMock.getVibratorIds()).thenReturn(vibratorIds);
}
+ private IVibrationSessionCallback mockSessionCallbacks(long delayToEndSessionMillis) {
+ Handler handler = new Handler(mTestLooper.getLooper());
+ ArgumentCaptor<VibratorManagerService.VibratorManagerNativeCallbacks> listenerCaptor =
+ ArgumentCaptor.forClass(
+ VibratorManagerService.VibratorManagerNativeCallbacks.class);
+ verify(mNativeWrapperMock).init(listenerCaptor.capture());
+ doReturn(true).when(mNativeWrapperMock).startSession(anyLong(), any(int[].class));
+ doAnswer(args -> {
+ handler.postDelayed(
+ () -> listenerCaptor.getValue().onVibrationSessionComplete(args.getArgument(0)),
+ delayToEndSessionMillis);
+ return null;
+ }).when(mNativeWrapperMock).endSession(anyLong(), eq(false));
+ doAnswer(args -> {
+ listenerCaptor.getValue().onVibrationSessionComplete(args.getArgument(0));
+ return null;
+ }).when(mNativeWrapperMock).endSession(anyLong(), eq(true));
+
+ IBinder token = mock(IBinder.class);
+ IVibrationSessionCallback callback = mock(IVibrationSessionCallback.class);
+ doReturn(token).when(callback).asBinder();
+ return callback;
+ }
+
private void cancelVibrate(VibratorManagerService service) {
service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service);
}
@@ -3157,6 +3678,16 @@
return vib;
}
+ private VendorVibrationSession startSession(VibratorManagerService service,
+ VibrationAttributes attrs, IVibrationSessionCallback callback, int... vibratorIds) {
+ VendorVibrationSession session = service.startVendorVibrationSessionInternal(UID,
+ Context.DEVICE_ID_DEFAULT, PACKAGE_NAME, vibratorIds, attrs, "reason", callback);
+ if (session != null) {
+ mPendingSessions.add(session);
+ }
+ return session;
+ }
+
private boolean waitUntil(Predicate<VibratorManagerService> predicate,
VibratorManagerService service, long timeout) throws InterruptedException {
long timeoutTimestamp = SystemClock.uptimeMillis() + timeout;
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
index 25a8db6..1e9038e 100644
--- a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
@@ -397,7 +397,7 @@
}
@Test
- @EnableFlags(Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL)
+ @EnableFlags(Flags.FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES)
@DisableFlags(com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
public void testToggleTalkbackPress() {
testShortcutInternal("Meta + Alt + T -> Toggle talkback",
@@ -745,7 +745,7 @@
}
@Test
- @EnableFlags(com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL)
+ @EnableFlags(com.android.hardware.input.Flags.FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES)
public void testKeyGestureToggleTalkback() {
Assert.assertTrue(
sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK));
diff --git a/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java
index 30cc002..bfce3d2 100644
--- a/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java
+++ b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java
@@ -168,32 +168,28 @@
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
- .setConsumedPower(123)
- .setConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU, 10100)
- .setConsumedPower(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200)
- .setUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU, 10300)
- .setUsageDurationMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10400);
+ .addConsumedPower(123)
+ .addConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 10100)
+ .addConsumedPower(BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200)
+ .addUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CPU, 10300)
+ .addUsageDurationMillis(BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10400);
for (int i = 0; i < 1000; i++) {
final UidBatteryConsumer.Builder consumerBuilder =
builder.getOrCreateUidBatteryConsumerBuilder(i)
.setPackageWithHighestDrain("example.packagename" + i)
- .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, i * 2000)
- .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, i * 1000);
+ .setTimeInProcessStateMs(UidBatteryConsumer.STATE_FOREGROUND, i * 2000)
+ .setTimeInProcessStateMs(UidBatteryConsumer.STATE_BACKGROUND, i * 1000);
for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
componentId++) {
- consumerBuilder.setConsumedPower(componentId, componentId * 123.0,
+ consumerBuilder.addConsumedPower(componentId, componentId * 123.0,
BatteryConsumer.POWER_MODEL_POWER_PROFILE);
- consumerBuilder.setUsageDurationMillis(componentId, componentId * 1000);
+ consumerBuilder.addUsageDurationMillis(componentId, componentId * 1000);
}
consumerBuilder
- .setConsumedPower(BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 1234)
- .setUsageDurationMillis(BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 4321);
+ .addConsumedPower(BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 1234)
+ .addUsageDurationMillis(BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 4321);
}
return builder.build();
}
diff --git a/tests/Input/src/com/android/server/input/InputGestureManagerTests.kt b/tests/Input/src/com/android/server/input/InputGestureManagerTests.kt
index 862886c..e281a3f 100644
--- a/tests/Input/src/com/android/server/input/InputGestureManagerTests.kt
+++ b/tests/Input/src/com/android/server/input/InputGestureManagerTests.kt
@@ -61,13 +61,13 @@
assertEquals(InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS, result)
assertEquals(
listOf(customGesture),
- inputGestureManager.getCustomInputGestures(USER_ID)
+ inputGestureManager.getCustomInputGestures(USER_ID, /* filter = */null)
)
inputGestureManager.removeCustomInputGesture(USER_ID, customGesture)
assertEquals(
listOf<InputGestureData>(),
- inputGestureManager.getCustomInputGestures(USER_ID)
+ inputGestureManager.getCustomInputGestures(USER_ID, /* filter = */null)
)
}
@@ -86,7 +86,7 @@
assertEquals(InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_DOES_NOT_EXIST, result)
assertEquals(
listOf<InputGestureData>(),
- inputGestureManager.getCustomInputGestures(USER_ID)
+ inputGestureManager.getCustomInputGestures(USER_ID, /* filter = */null)
)
}
@@ -115,7 +115,7 @@
assertEquals(InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_ALREADY_EXISTS, result)
assertEquals(
listOf(customGesture),
- inputGestureManager.getCustomInputGestures(USER_ID)
+ inputGestureManager.getCustomInputGestures(USER_ID, /* filter = */null)
)
}
@@ -144,13 +144,67 @@
assertEquals(
listOf(customGesture, customGesture2),
- inputGestureManager.getCustomInputGestures(USER_ID)
+ inputGestureManager.getCustomInputGestures(USER_ID, /* filter = */null)
)
- inputGestureManager.removeAllCustomInputGestures(USER_ID)
+ inputGestureManager.removeAllCustomInputGestures(USER_ID, /* filter = */null)
assertEquals(
listOf<InputGestureData>(),
- inputGestureManager.getCustomInputGestures(USER_ID)
+ inputGestureManager.getCustomInputGestures(USER_ID, /* filter = */null)
+ )
+ }
+
+ @Test
+ fun filteringBasedOnTouchpadOrKeyGestures() {
+ val customKeyGesture = InputGestureData.Builder()
+ .setTrigger(
+ InputGestureData.createKeyTrigger(
+ KeyEvent.KEYCODE_H,
+ KeyEvent.META_META_ON
+ )
+ )
+ .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_HOME)
+ .build()
+ inputGestureManager.addCustomInputGesture(USER_ID, customKeyGesture)
+ val customTouchpadGesture = InputGestureData.Builder()
+ .setTrigger(
+ InputGestureData.createTouchpadTrigger(
+ InputGestureData.TOUCHPAD_GESTURE_TYPE_THREE_FINGER_TAP
+ )
+ )
+ .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_BACK)
+ .build()
+ inputGestureManager.addCustomInputGesture(USER_ID, customTouchpadGesture)
+
+ assertEquals(
+ listOf(customTouchpadGesture, customKeyGesture),
+ inputGestureManager.getCustomInputGestures(USER_ID, /* filter = */null)
+ )
+ assertEquals(
+ listOf(customKeyGesture),
+ inputGestureManager.getCustomInputGestures(USER_ID, InputGestureData.Filter.KEY)
+ )
+ assertEquals(
+ listOf(customTouchpadGesture),
+ inputGestureManager.getCustomInputGestures(
+ USER_ID,
+ InputGestureData.Filter.TOUCHPAD
+ )
+ )
+
+ inputGestureManager.removeAllCustomInputGestures(USER_ID, InputGestureData.Filter.KEY)
+ assertEquals(
+ listOf(customTouchpadGesture),
+ inputGestureManager.getCustomInputGestures(USER_ID, /* filter = */null)
+ )
+
+ inputGestureManager.removeAllCustomInputGestures(
+ USER_ID,
+ InputGestureData.Filter.TOUCHPAD
+ )
+ assertEquals(
+ listOf<InputGestureData>(),
+ inputGestureManager.getCustomInputGestures(USER_ID, /* filter = */null)
)
}
}
\ No newline at end of file
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index 6c9f764..1574d1b 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -1260,24 +1260,102 @@
testKeyGestureInternal(test)
}
- private fun testKeyGestureInternal(test: TestData) {
- var handleEvents = mutableListOf<KeyGestureEvent>()
+ class TouchpadTestData(
+ val name: String,
+ val touchpadGestureType: Int,
+ val expectedKeyGestureType: Int,
+ val expectedAction: Int,
+ val expectedAppLaunchData: AppLaunchData? = null,
+ ) {
+ override fun toString(): String = name
+ }
+
+ @Keep
+ private fun customTouchpadGesturesTestArguments(): Array<TouchpadTestData> {
+ return arrayOf(
+ TouchpadTestData(
+ "3 Finger Tap -> Go Home",
+ InputGestureData.TOUCHPAD_GESTURE_TYPE_THREE_FINGER_TAP,
+ KeyGestureEvent.KEY_GESTURE_TYPE_HOME,
+ KeyGestureEvent.ACTION_GESTURE_COMPLETE
+ ),
+ TouchpadTestData(
+ "3 Finger Tap -> Launch app",
+ InputGestureData.TOUCHPAD_GESTURE_TYPE_THREE_FINGER_TAP,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ KeyGestureEvent.ACTION_GESTURE_COMPLETE,
+ AppLaunchData.createLaunchDataForComponent("com.test", "com.test.BookmarkTest")
+ ),
+ )
+ }
+
+ @Test
+ @Parameters(method = "customTouchpadGesturesTestArguments")
+ fun testCustomTouchpadGesture(test: TouchpadTestData) {
+ setupKeyGestureController()
+ val builder = InputGestureData.Builder()
+ .setKeyGestureType(test.expectedKeyGestureType)
+ .setTrigger(InputGestureData.createTouchpadTrigger(test.touchpadGestureType))
+ if (test.expectedAppLaunchData != null) {
+ builder.setAppLaunchData(test.expectedAppLaunchData)
+ }
+ val inputGestureData = builder.build()
+
+ keyGestureController.addCustomInputGesture(0, inputGestureData.aidlData)
+
+ val handledEvents = mutableListOf<KeyGestureEvent>()
val handler = KeyGestureHandler { event, _ ->
- handleEvents.add(KeyGestureEvent(event))
+ handledEvents.add(KeyGestureEvent(event))
true
}
keyGestureController.registerKeyGestureHandler(handler, 0)
- handleEvents.clear()
+ handledEvents.clear()
+
+ keyGestureController.handleTouchpadGesture(test.touchpadGestureType)
+
+ assertEquals(
+ "Test: $test doesn't produce correct number of key gesture events",
+ 1,
+ handledEvents.size
+ )
+ val event = handledEvents[0]
+ assertEquals(
+ "Test: $test doesn't produce correct key gesture type",
+ test.expectedKeyGestureType,
+ event.keyGestureType
+ )
+ assertEquals(
+ "Test: $test doesn't produce correct key gesture action",
+ test.expectedAction,
+ event.action
+ )
+ assertEquals(
+ "Test: $test doesn't produce correct app launch data",
+ test.expectedAppLaunchData,
+ event.appLaunchData
+ )
+
+ keyGestureController.unregisterKeyGestureHandler(handler, 0)
+ }
+
+ private fun testKeyGestureInternal(test: TestData) {
+ val handledEvents = mutableListOf<KeyGestureEvent>()
+ val handler = KeyGestureHandler { event, _ ->
+ handledEvents.add(KeyGestureEvent(event))
+ true
+ }
+ keyGestureController.registerKeyGestureHandler(handler, 0)
+ handledEvents.clear()
sendKeys(test.keys)
assertEquals(
"Test: $test doesn't produce correct number of key gesture events",
test.expectedActions.size,
- handleEvents.size
+ handledEvents.size
)
- for (i in handleEvents.indices) {
- val event = handleEvents[i]
+ for (i in handledEvents.indices) {
+ val event = handledEvents[i]
assertArrayEquals(
"Test: $test doesn't produce correct key gesture keycodes",
test.expectedKeys,
@@ -1309,16 +1387,16 @@
}
private fun testKeyGestureNotProduced(testName: String, testKeys: IntArray) {
- var handleEvents = mutableListOf<KeyGestureEvent>()
+ var handledEvents = mutableListOf<KeyGestureEvent>()
val handler = KeyGestureHandler { event, _ ->
- handleEvents.add(KeyGestureEvent(event))
+ handledEvents.add(KeyGestureEvent(event))
true
}
keyGestureController.registerKeyGestureHandler(handler, 0)
- handleEvents.clear()
+ handledEvents.clear()
sendKeys(testKeys)
- assertEquals("Test: $testName should not produce Key gesture", 0, handleEvents.size)
+ assertEquals("Test: $testName should not produce Key gesture", 0, handledEvents.size)
}
private fun sendKeys(testKeys: IntArray, assertNotSentToApps: Boolean = false) {
diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp
index 096555e..91483eb 100644
--- a/tests/PackageWatchdog/Android.bp
+++ b/tests/PackageWatchdog/Android.bp
@@ -35,7 +35,13 @@
"services.core",
"services.net",
"truth",
- ],
+ ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), {
+ "true": [
+ "service-crashrecovery.impl",
+ "framework-crashrecovery.impl",
+ ],
+ default: [],
+ }),
libs: ["android.test.runner.stubs.system"],
jni_libs: [
// mockito-target-extended dependencies
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index 8d143b6..05a0f8f 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -224,39 +224,39 @@
PackageWatchdog watchdog = createWatchdog();
RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(1);
for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
watchdog.noteBoot();
}
- verify(rescuePartyObserver).executeBootLoopMitigation(1);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(2);
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(2);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(3);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(2);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(3);
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(3);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(4);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(3);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(4);
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(4);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(5);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(4);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(5);
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(5);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(6);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(5);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(6);
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(6);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(7);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(6);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(7);
}
@Test
@@ -265,14 +265,14 @@
RollbackPackageHealthObserver rollbackObserver =
setUpRollbackPackageHealthObserver(watchdog);
- verify(rollbackObserver, never()).executeBootLoopMitigation(1);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(1);
for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
watchdog.noteBoot();
}
- verify(rollbackObserver).executeBootLoopMitigation(1);
- verify(rollbackObserver, never()).executeBootLoopMitigation(2);
+ verify(rollbackObserver).onExecuteBootLoopMitigation(1);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
// Update the list of available rollbacks after executing bootloop mitigation once
when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH,
@@ -280,15 +280,15 @@
watchdog.noteBoot();
- verify(rollbackObserver).executeBootLoopMitigation(2);
- verify(rollbackObserver, never()).executeBootLoopMitigation(3);
+ verify(rollbackObserver).onExecuteBootLoopMitigation(2);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(3);
// Update the list of available rollbacks after executing bootloop mitigation once
when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL));
watchdog.noteBoot();
- verify(rollbackObserver, never()).executeBootLoopMitigation(3);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(3);
}
@Test
@@ -299,61 +299,61 @@
RollbackPackageHealthObserver rollbackObserver =
setUpRollbackPackageHealthObserver(watchdog);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(1);
- verify(rollbackObserver, never()).executeBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(1);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(1);
for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
watchdog.noteBoot();
}
- verify(rescuePartyObserver).executeBootLoopMitigation(1);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
- verify(rollbackObserver, never()).executeBootLoopMitigation(1);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(2);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(1);
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(2);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(3);
- verify(rollbackObserver, never()).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(2);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(3);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
watchdog.noteBoot();
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(3);
- verify(rollbackObserver).executeBootLoopMitigation(1);
- verify(rollbackObserver, never()).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(3);
+ verify(rollbackObserver).onExecuteBootLoopMitigation(1);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
// Update the list of available rollbacks after executing bootloop mitigation once
when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH,
ROLLBACK_INFO_MANUAL));
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(3);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(4);
- verify(rollbackObserver, never()).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(3);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(4);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(4);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(5);
- verify(rollbackObserver, never()).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(4);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(5);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(5);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(6);
- verify(rollbackObserver, never()).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(5);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(6);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
watchdog.noteBoot();
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(6);
- verify(rollbackObserver).executeBootLoopMitigation(2);
- verify(rollbackObserver, never()).executeBootLoopMitigation(3);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(6);
+ verify(rollbackObserver).onExecuteBootLoopMitigation(2);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(3);
// Update the list of available rollbacks after executing bootloop mitigation
when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL));
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(6);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(7);
- verify(rollbackObserver, never()).executeBootLoopMitigation(3);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(6);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(7);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(3);
moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1);
Mockito.reset(rescuePartyObserver);
@@ -361,8 +361,8 @@
for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
watchdog.noteBoot();
}
- verify(rescuePartyObserver).executeBootLoopMitigation(1);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(2);
}
@Test
@@ -373,37 +373,37 @@
RollbackPackageHealthObserver rollbackObserver =
setUpRollbackPackageHealthObserver(watchdog);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(1);
- verify(rollbackObserver, never()).executeBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(1);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(1);
for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
watchdog.noteBoot();
}
- verify(rescuePartyObserver).executeBootLoopMitigation(1);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
- verify(rollbackObserver, never()).executeBootLoopMitigation(1);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(2);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(1);
watchdog.noteBoot();
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
- verify(rollbackObserver).executeBootLoopMitigation(1);
- verify(rollbackObserver, never()).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(2);
+ verify(rollbackObserver).onExecuteBootLoopMitigation(1);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(2);
// Update the list of available rollbacks after executing bootloop mitigation once
when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH,
ROLLBACK_INFO_MANUAL));
watchdog.noteBoot();
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
- verify(rollbackObserver).executeBootLoopMitigation(2);
- verify(rollbackObserver, never()).executeBootLoopMitigation(3);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(2);
+ verify(rollbackObserver).onExecuteBootLoopMitigation(2);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(3);
// Update the list of available rollbacks after executing bootloop mitigation
when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL));
watchdog.noteBoot();
- verify(rescuePartyObserver).executeBootLoopMitigation(2);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(3);
- verify(rollbackObserver, never()).executeBootLoopMitigation(3);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(2);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(3);
+ verify(rollbackObserver, never()).onExecuteBootLoopMitigation(3);
moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1);
Mockito.reset(rescuePartyObserver);
@@ -411,8 +411,8 @@
for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
watchdog.noteBoot();
}
- verify(rescuePartyObserver).executeBootLoopMitigation(1);
- verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
+ verify(rescuePartyObserver).onExecuteBootLoopMitigation(1);
+ verify(rescuePartyObserver, never()).onExecuteBootLoopMitigation(2);
}
@Test
@@ -435,46 +435,46 @@
Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: SCOPED_DEVICE_CONFIG_RESET
- verify(rescuePartyObserver).execute(versionedPackageA,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rollbackObserver, never()).execute(versionedPackageA,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: ALL_DEVICE_CONFIG_RESET
- verify(rescuePartyObserver).execute(versionedPackageA,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
- verify(rollbackObserver, never()).execute(versionedPackageA,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: WARM_REBOOT
- verify(rescuePartyObserver).execute(versionedPackageA,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
- verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rollbackObserver, never()).execute(versionedPackageA,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: Low impact rollback
- verify(rollbackObserver).execute(versionedPackageA,
+ verify(rollbackObserver).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
// update available rollbacks to mock rollbacks being applied after the call to
- // rollbackObserver.execute
+ // rollbackObserver.onExecuteHealthCheckMitigation
when(mRollbackManager.getAvailableRollbacks()).thenReturn(
List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
@@ -482,9 +482,9 @@
Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD reached. No more mitigations applied
- verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rollbackObserver, never()).execute(versionedPackageA,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
}
@@ -510,24 +510,24 @@
Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: WARM_REBOOT
- verify(rescuePartyObserver).execute(versionedPackageA,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rollbackObserver, never()).execute(versionedPackageA,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: Low impact rollback
- verify(rollbackObserver).execute(versionedPackageA,
+ verify(rollbackObserver).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
// update available rollbacks to mock rollbacks being applied after the call to
- // rollbackObserver.execute
+ // rollbackObserver.onExecuteHealthCheckMitigation
when(mRollbackManager.getAvailableRollbacks()).thenReturn(
List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
@@ -535,9 +535,9 @@
Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD reached. No more mitigations applied
- verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rollbackObserver, never()).execute(versionedPackageA,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageA,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
}
@@ -567,48 +567,48 @@
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: SCOPED_DEVICE_CONFIG_RESET
- verify(rescuePartyObserver).execute(versionedPackageUi,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: ALL_DEVICE_CONFIG_RESET
- verify(rescuePartyObserver).execute(versionedPackageUi,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: WARM_REBOOT
- verify(rescuePartyObserver).execute(versionedPackageUi,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: Low impact rollback
- verify(rollbackObserver).execute(versionedPackageUi,
+ verify(rollbackObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
// update available rollbacks to mock rollbacks being applied after the call to
- // rollbackObserver.execute
+ // rollbackObserver.onExecuteHealthCheckMitigation
when(mRollbackManager.getAvailableRollbacks()).thenReturn(
List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
@@ -616,44 +616,44 @@
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: RESET_SETTINGS_UNTRUSTED_DEFAULTS
- verify(rescuePartyObserver).execute(versionedPackageUi,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 5);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: RESET_SETTINGS_UNTRUSTED_CHANGES
- verify(rescuePartyObserver).execute(versionedPackageUi,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 5);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 6);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: RESET_SETTINGS_TRUSTED_DEFAULTS
- verify(rescuePartyObserver).execute(versionedPackageUi,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 6);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 7);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: Factory reset. High impact rollbacks are performed only for boot loops.
- verify(rescuePartyObserver).execute(versionedPackageUi,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 7);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 8);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
}
@@ -685,26 +685,26 @@
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: WARM_REBOOT
- verify(rescuePartyObserver).execute(versionedPackageUi,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
raiseFatalFailureAndDispatch(watchdog,
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: Low impact rollback
- verify(rollbackObserver).execute(versionedPackageUi,
+ verify(rollbackObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
// update available rollbacks to mock rollbacks being applied after the call to
- // rollbackObserver.execute
+ // rollbackObserver.onExecuteHealthCheckMitigation
when(mRollbackManager.getAvailableRollbacks()).thenReturn(
List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
@@ -712,17 +712,17 @@
Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
// Mitigation: Factory reset. High impact rollbacks are performed only for boot loops.
- verify(rescuePartyObserver).execute(versionedPackageUi,
+ verify(rescuePartyObserver).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
- verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ verify(rescuePartyObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
- verify(rollbackObserver, never()).execute(versionedPackageUi,
+ verify(rollbackObserver, never()).onExecuteHealthCheckMitigation(versionedPackageUi,
PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
}
RollbackPackageHealthObserver setUpRollbackPackageHealthObserver(PackageWatchdog watchdog) {
RollbackPackageHealthObserver rollbackObserver =
- spy(new RollbackPackageHealthObserver(mSpyContext, mApexManager));
+ spy(new RollbackPackageHealthObserver(mSpyContext));
when(mSpyContext.getSystemService(RollbackManager.class)).thenReturn(mRollbackManager);
when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_LOW,
ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
@@ -785,7 +785,7 @@
Handler handler = new Handler(mTestLooper.getLooper());
PackageWatchdog watchdog =
new PackageWatchdog(mSpyContext, policyFile, handler, handler, controller,
- mConnectivityModuleConnector, mTestClock);
+ mTestClock);
mockCrashRecoveryProperties(watchdog);
// Verify controller is not automatically started
diff --git a/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java b/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java
index 2fbfeba..cd2ab86 100644
--- a/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java
@@ -35,6 +35,8 @@
private ExplicitHealthCheckService mExplicitHealthCheckService;
private static final String PACKAGE_NAME = "com.test.package";
+ private static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE =
+ "android.service.watchdog.extra.health_check_passed_package";
@Before
public void setup() throws Exception {
@@ -50,7 +52,7 @@
IBinder binder = mExplicitHealthCheckService.onBind(new Intent());
CountDownLatch countDownLatch = new CountDownLatch(1);
RemoteCallback callback = new RemoteCallback(result -> {
- assertThat(result.get(ExplicitHealthCheckService.EXTRA_HEALTH_CHECK_PASSED_PACKAGE))
+ assertThat(result.get(EXTRA_HEALTH_CHECK_PASSED_PACKAGE))
.isEqualTo(PACKAGE_NAME);
countDownLatch.countDown();
});
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 0364781a..a540a8d 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -1754,7 +1754,7 @@
Handler handler = new Handler(mTestLooper.getLooper());
PackageWatchdog watchdog =
new PackageWatchdog(mSpyContext, policyFile, handler, handler, controller,
- mConnectivityModuleConnector, mTestClock);
+ mTestClock);
mockCrashRecoveryProperties(watchdog);
// Verify controller is not automatically started
@@ -1869,8 +1869,8 @@
return mImpact;
}
- public boolean execute(VersionedPackage versionedPackage, int failureReason,
- int mitigationCount) {
+ public boolean onExecuteHealthCheckMitigation(VersionedPackage versionedPackage,
+ int failureReason, int mitigationCount) {
mMitigatedPackages.add(versionedPackage.getPackageName());
mMitigationCounts.add(mitigationCount);
mLastFailureReason = failureReason;
@@ -1893,7 +1893,7 @@
return mImpact;
}
- public boolean executeBootLoopMitigation(int level) {
+ public boolean onExecuteBootLoopMitigation(int level) {
mMitigatedBootLoop = true;
mBootMitigationCounts.add(level);
return true;
diff --git a/tests/permission/src/com/android/framework/permission/tests/VibratorManagerServicePermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/VibratorManagerServicePermissionTest.java
index 07b7338..0da4521 100644
--- a/tests/permission/src/com/android/framework/permission/tests/VibratorManagerServicePermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/VibratorManagerServicePermissionTest.java
@@ -143,6 +143,38 @@
}
@Test
+ public void testStartVendorVibrationSessionWithoutVibratePermissionFails() throws Exception {
+ getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
+ Manifest.permission.VIBRATE_VENDOR_EFFECTS,
+ Manifest.permission.START_VIBRATION_SESSIONS);
+ expectSecurityException("VIBRATE");
+ mVibratorService.startVendorVibrationSession(Process.myUid(), DEVICE_ID, PACKAGE_NAME,
+ new int[] { 1 }, ATTRS, "testVibrate", null);
+ }
+
+ @Test
+ public void testStartVendorVibrationSessionWithoutVibrateVendorEffectsPermissionFails()
+ throws Exception {
+ getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
+ Manifest.permission.VIBRATE,
+ Manifest.permission.START_VIBRATION_SESSIONS);
+ expectSecurityException("VIBRATE");
+ mVibratorService.startVendorVibrationSession(Process.myUid(), DEVICE_ID, PACKAGE_NAME,
+ new int[] { 1 }, ATTRS, "testVibrate", null);
+ }
+
+ @Test
+ public void testStartVendorVibrationSessionWithoutStartSessionPermissionFails()
+ throws Exception {
+ getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
+ Manifest.permission.VIBRATE,
+ Manifest.permission.VIBRATE_VENDOR_EFFECTS);
+ expectSecurityException("VIBRATE");
+ mVibratorService.startVendorVibrationSession(Process.myUid(), DEVICE_ID, PACKAGE_NAME,
+ new int[] { 1 }, ATTRS, "testVibrate", null);
+ }
+
+ @Test
public void testCancelVibrateFails() throws RemoteException {
expectSecurityException("VIBRATE");
mVibratorService.cancelVibrate(/* usageFilter= */ -1, new Binder());
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index be5c84c..ac96ef2 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -53,6 +53,7 @@
private static final Field MESSAGE_QUEUE_MESSAGES_FIELD;
private static final Field MESSAGE_NEXT_FIELD;
private static final Field MESSAGE_WHEN_FIELD;
+ private static Field MESSAGE_QUEUE_USE_CONCURRENT_FIELD = null;
private Looper mLooper;
private MessageQueue mQueue;
@@ -63,6 +64,14 @@
static {
try {
+ MESSAGE_QUEUE_USE_CONCURRENT_FIELD =
+ MessageQueue.class.getDeclaredField("mUseConcurrent");
+ MESSAGE_QUEUE_USE_CONCURRENT_FIELD.setAccessible(true);
+ } catch (NoSuchFieldException ignored) {
+ // Ignore - maybe this is not CombinedMessageQueue?
+ }
+
+ try {
MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages");
MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true);
MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
@@ -146,6 +155,15 @@
mLooper = l;
mQueue = mLooper.getQueue();
mHandler = new Handler(mLooper);
+
+ // If we are using CombinedMessageQueue, we need to disable concurrent mode for testing.
+ if (MESSAGE_QUEUE_USE_CONCURRENT_FIELD != null) {
+ try {
+ MESSAGE_QUEUE_USE_CONCURRENT_FIELD.set(mQueue, false);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
/**
diff --git a/tests/utils/testutils/java/android/os/test/TestLooper.java b/tests/utils/testutils/java/android/os/test/TestLooper.java
index e6eabd8..1bcfaf6 100644
--- a/tests/utils/testutils/java/android/os/test/TestLooper.java
+++ b/tests/utils/testutils/java/android/os/test/TestLooper.java
@@ -90,20 +90,6 @@
* and call {@link #dispatchAll()}.
*/
public TestLooper(Clock clock) {
- Field messageQueueUseConcurrentField = null;
- boolean previousUseConcurrentValue = false;
- try {
- messageQueueUseConcurrentField = MessageQueue.class.getDeclaredField("sUseConcurrent");
- messageQueueUseConcurrentField.setAccessible(true);
- previousUseConcurrentValue = messageQueueUseConcurrentField.getBoolean(null);
- // If we are using CombinedMessageQueue, we need to disable concurrent mode for testing.
- messageQueueUseConcurrentField.set(null, false);
- } catch (NoSuchFieldException e) {
- // Ignore - maybe this is not CombinedMessageQueue?
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Reflection error constructing or accessing looper", e);
- }
-
try {
mLooper = LOOPER_CONSTRUCTOR.newInstance(false);
@@ -114,15 +100,19 @@
throw new RuntimeException("Reflection error constructing or accessing looper", e);
}
- mClock = clock;
-
- if (messageQueueUseConcurrentField != null) {
- try {
- messageQueueUseConcurrentField.set(null, previousUseConcurrentValue);
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Reflection error constructing or accessing looper", e);
- }
+ // If we are using CombinedMessageQueue, we need to disable concurrent mode for testing.
+ try {
+ Field messageQueueUseConcurrentField =
+ MessageQueue.class.getDeclaredField("mUseConcurrent");
+ messageQueueUseConcurrentField.setAccessible(true);
+ messageQueueUseConcurrentField.set(mLooper.getQueue(), false);
+ } catch (NoSuchFieldException e) {
+ // Ignore - maybe this is not CombinedMessageQueue?
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Reflection error constructing or accessing looper", e);
}
+
+ mClock = clock;
}
public Looper getLooper() {
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index 49665f7..613b926 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -360,12 +360,10 @@
private void verifyGetSafeModeTimeoutMs(
boolean isInTestMode,
- boolean isConfigTimeoutSupported,
PersistableBundleWrapper carrierConfig,
long expectedTimeoutMs)
throws Exception {
doReturn(isInTestMode).when(mVcnContext).isInTestMode();
- doReturn(isConfigTimeoutSupported).when(mVcnContext).isFlagSafeModeTimeoutConfigEnabled();
final TelephonySubscriptionSnapshot snapshot = mock(TelephonySubscriptionSnapshot.class);
doReturn(carrierConfig).when(snapshot).getCarrierConfigForSubGrp(TEST_SUB_GRP);
@@ -377,16 +375,7 @@
}
@Test
- public void testGetSafeModeTimeoutMs_configTimeoutUnsupported() throws Exception {
- verifyGetSafeModeTimeoutMs(
- false /* isInTestMode */,
- false /* isConfigTimeoutSupported */,
- null /* carrierConfig */,
- TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS));
- }
-
- @Test
- public void testGetSafeModeTimeoutMs_configTimeoutSupported() throws Exception {
+ public void testGetSafeModeTimeoutMs() throws Exception {
final int carrierConfigTimeoutSeconds = 20;
final PersistableBundleWrapper carrierConfig = mock(PersistableBundleWrapper.class);
doReturn(carrierConfigTimeoutSeconds)
@@ -395,17 +384,14 @@
verifyGetSafeModeTimeoutMs(
false /* isInTestMode */,
- true /* isConfigTimeoutSupported */,
carrierConfig,
TimeUnit.SECONDS.toMillis(carrierConfigTimeoutSeconds));
}
@Test
- public void testGetSafeModeTimeoutMs_configTimeoutSupported_carrierConfigNull()
- throws Exception {
+ public void testGetSafeModeTimeoutMs_carrierConfigNull() throws Exception {
verifyGetSafeModeTimeoutMs(
false /* isInTestMode */,
- true /* isConfigTimeoutSupported */,
null /* carrierConfig */,
TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS));
}
@@ -420,7 +406,6 @@
verifyGetSafeModeTimeoutMs(
true /* isInTestMode */,
- true /* isConfigTimeoutSupported */,
carrierConfig,
TimeUnit.SECONDS.toMillis(carrierConfigTimeoutSeconds));
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
index 4c7b25a..8374fd9 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
@@ -222,7 +222,6 @@
doReturn(mTestLooper.getLooper()).when(mVcnContext).getLooper();
doReturn(mVcnNetworkProvider).when(mVcnContext).getVcnNetworkProvider();
doReturn(mFeatureFlags).when(mVcnContext).getFeatureFlags();
- doReturn(true).when(mVcnContext).isFlagSafeModeTimeoutConfigEnabled();
doReturn(mUnderlyingNetworkController)
.when(mDeps)