Merge "Extract camera open/close logic in a separate class." into main
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java
index be4b720..d52c4ce 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java
@@ -36,10 +36,9 @@
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateControllerProto;
+import java.util.Comparator;
import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
+import java.util.PriorityQueue;
import java.util.function.Predicate;
/**
@@ -64,8 +63,17 @@
private volatile long mLastFiredDelayExpiredElapsedMillis;
private AlarmManager mAlarmService = null;
- /** List of tracked jobs, sorted asc. by deadline */
- private final List<JobStatus> mTrackedJobs = new LinkedList<>();
+
+ /** List of tracked jobs, ordered by deadline (lowest i.e. earliest first) */
+ private final PriorityQueue<JobStatus> mTrackedJobs =
+ new PriorityQueue<>(
+ new Comparator<JobStatus>() {
+ public int compare(JobStatus left, JobStatus right) {
+ return Long.compare(
+ left.getLatestRunTimeElapsed(),
+ right.getLatestRunTimeElapsed());
+ }
+ });
public TimeController(JobSchedulerService service) {
super(service);
@@ -102,20 +110,7 @@
}
}
- boolean isInsert = false;
- ListIterator<JobStatus> it = mTrackedJobs.listIterator(mTrackedJobs.size());
- while (it.hasPrevious()) {
- JobStatus ts = it.previous();
- if (ts.getLatestRunTimeElapsed() < job.getLatestRunTimeElapsed()) {
- // Insert
- isInsert = true;
- break;
- }
- }
- if (isInsert) {
- it.next();
- }
- it.add(job);
+ mTrackedJobs.add(job);
job.setTrackingController(JobStatus.TRACKING_TIME);
WorkSource ws =
@@ -226,7 +221,7 @@
String nextExpiryPackageName = null;
final long nowElapsedMillis = sElapsedRealtimeClock.millis();
- ListIterator<JobStatus> it = mTrackedJobs.listIterator();
+ Iterator<JobStatus> it = mTrackedJobs.iterator();
while (it.hasNext()) {
JobStatus job = it.next();
if (!job.hasDeadlineConstraint()) {
diff --git a/config/Android.bp b/config/Android.bp
index dd681ca..adce203 100644
--- a/config/Android.bp
+++ b/config/Android.bp
@@ -29,6 +29,13 @@
],
}
+prebuilt_etc {
+ name: "preloaded-classes",
+ src: "preloaded-classes",
+ filename: "preloaded-classes",
+ installable: false,
+}
+
filegroup {
name: "preloaded-classes-denylist",
srcs: ["preloaded-classes-denylist"],
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index dd6bc55..b9906bf 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -84,6 +84,7 @@
import android.content.res.ApkAssets;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -118,9 +119,11 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.AttributeSet;
import android.util.LauncherIcons;
import android.util.Log;
import android.util.Slog;
+import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.Immutable;
@@ -132,6 +135,9 @@
import libcore.util.EmptyArray;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -4090,4 +4096,38 @@
}
}
}
+
+ @Override
+ public TypedArray extractPackageItemInfoAttributes(PackageItemInfo info, String name,
+ String rootTag, int[] attributes) {
+ if (info == null || info.metaData == null) {
+ return null;
+ }
+
+ try (XmlResourceParser parser = info.loadXmlMetaData(this, name)) {
+ if (parser == null) {
+ Log.w(TAG, "No " + name + " metadata");
+ return null;
+ }
+
+ final AttributeSet attrs = Xml.asAttributeSet(parser);
+ while (true) {
+ final int type = parser.next();
+ if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) {
+ break;
+ }
+ }
+
+ if (!TextUtils.equals(parser.getName(), rootTag)) {
+ Log.w(TAG, "Metadata does not start with " + name + " tag");
+ return null;
+ }
+
+ return getResourcesForApplication(info.getApplicationInfo())
+ .obtainAttributes(attrs, attributes);
+ } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
+ Log.e(TAG, "Error parsing: " + info.packageName, e);
+ return null;
+ }
+ }
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b19dc8f..4d7e29b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4538,12 +4538,6 @@
*/
@NonNull
public Builder setWhen(long when) {
- if (updateRankingTime()) {
- // don't show a timestamp that's decades old
- if (mN.extras.getBoolean(EXTRA_SHOW_WHEN, true) && when == 0) {
- return this;
- }
- }
mN.when = when;
return this;
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 103af4b..8171723 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1814,6 +1814,11 @@
return null;
}
break;
+ case Context.APPWIDGET_SERVICE:
+ if (!hasSystemFeatureOpportunistic(ctx, PackageManager.FEATURE_APP_WIDGETS)) {
+ return null;
+ }
+ break;
}
Slog.wtf(TAG, "Manager wrapper not available: " + name);
return null;
diff --git a/core/java/android/app/admin/EnterprisePlatform_OWNERS b/core/java/android/app/admin/EnterprisePlatform_OWNERS
index 4d1ed590..9da526f 100644
--- a/core/java/android/app/admin/EnterprisePlatform_OWNERS
+++ b/core/java/android/app/admin/EnterprisePlatform_OWNERS
@@ -1,2 +1,3 @@
sandness@google.com #{LAST_RESORT_SUGGESTION}
-scottjonathan@google.com #{LAST_RESORT_SUGGESTION}
\ No newline at end of file
+scottjonathan@google.com #{LAST_RESORT_SUGGESTION}
+rubinxu@google.com #{LAST_RESORT_SUGGESTION}
\ No newline at end of file
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index cae4fab..495ae60 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -2700,7 +2700,7 @@
/**
* @hide
*/
- @Override protected ApplicationInfo getApplicationInfo() {
+ @Override public ApplicationInfo getApplicationInfo() {
return this;
}
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index ff48ffa..4d9ecc4 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -284,7 +284,7 @@
/**
* @hide
*/
- @Override protected ApplicationInfo getApplicationInfo() {
+ @Override public ApplicationInfo getApplicationInfo() {
return applicationInfo;
}
}
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 1f821b9..51285de 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -511,7 +511,7 @@
*
* @hide
*/
- protected ApplicationInfo getApplicationInfo() {
+ public ApplicationInfo getApplicationInfo() {
return null;
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index f5bff9d..83285e0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -62,6 +62,7 @@
import android.content.pm.verify.domain.DomainVerificationManager;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
@@ -11743,4 +11744,17 @@
throw new UnsupportedOperationException(
"parseAndroidManifest not implemented in subclass");
}
+
+ /**
+ * @param info The {@link ServiceInfo} to pull the attributes from.
+ * @param name The name of the Xml metadata where the attributes are stored.
+ * @param rootTag The root tag of the attributes.
+ * @return A {@link TypedArray} of attributes if successful, {@code null} otherwise.
+ * @hide
+ */
+ public TypedArray extractPackageItemInfoAttributes(PackageItemInfo info, String name,
+ String rootTag, int[] attributes) {
+ throw new UnsupportedOperationException(
+ "parseServiceMetadata not implemented in subclass");
+ }
}
diff --git a/core/java/android/database/sqlite/package.html b/core/java/android/database/sqlite/package.html
index f2df536..06f8974 100644
--- a/core/java/android/database/sqlite/package.html
+++ b/core/java/android/database/sqlite/package.html
@@ -17,10 +17,14 @@
<code>platform-tools/</code> folder of your SDK. On the emulator, run the tool
with adb shell, for example, <code>adb shell sqlite3</code>.
-<p>The version of SQLite depends on the version of Android. See the following table:
+<p>The version of SQLite depends on the version of Android. In the past,
+ SQLite upgrades have been delivered as part of a new API level, but more
+ recently SQLite may be upgraded within an API level. See the following
+ table:
<table style="width:auto;">
<tr><th>Android API</th><th>SQLite Version</th></tr>
- <tr><td>LATEST</td><td>3.42.0</td></tr>
+ <tr><td>API 35</td><td>3.44.3</td></tr>
+ <tr><td>API 34</td><td>3.42.0</td></tr>
<tr><td>API 34</td><td>3.39</td></tr>
<tr><td>API 33</td><td>3.32</td></tr>
<tr><td>API 32</td><td>3.32</td></tr>
diff --git a/core/java/android/hardware/biometrics/BiometricFaceConstants.java b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
index 2ba1d89..ac47c8d 100644
--- a/core/java/android/hardware/biometrics/BiometricFaceConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
@@ -34,7 +34,7 @@
*
* @hide
*/
-public interface BiometricFaceConstants {
+public class BiometricFaceConstants {
//
// Accessibility constants
//
@@ -43,12 +43,12 @@
* authentication. Note this is to accommodate people who have limited
* vision.
*/
- int FEATURE_REQUIRE_ATTENTION = 1;
+ public static final int FEATURE_REQUIRE_ATTENTION = 1;
/**
* Require a diverse set of poses during enrollment. Note this is to
* accommodate people with limited mobility.
*/
- int FEATURE_REQUIRE_REQUIRE_DIVERSITY = 2;
+ public static final int FEATURE_REQUIRE_REQUIRE_DIVERSITY = 2;
//
// Error messages from face authentication hardware during initialization, enrollment,
@@ -75,49 +75,49 @@
BIOMETRIC_ERROR_POWER_PRESSED,
})
@Retention(RetentionPolicy.SOURCE)
- @interface FaceError {}
+ public @interface FaceError {}
/**
* The hardware is unavailable. Try again later.
*/
- int FACE_ERROR_HW_UNAVAILABLE = 1;
+ public static final int FACE_ERROR_HW_UNAVAILABLE = 1;
/**
* Error state returned when the sensor was unable to process the current image.
*/
- int FACE_ERROR_UNABLE_TO_PROCESS = 2;
+ public static final int FACE_ERROR_UNABLE_TO_PROCESS = 2;
/**
* Error state returned when the current request has been running too long. This is intended to
* prevent programs from waiting for the face authentication sensor indefinitely. The timeout is
* platform and sensor-specific, but is generally on the order of 30 seconds.
*/
- int FACE_ERROR_TIMEOUT = 3;
+ public static final int FACE_ERROR_TIMEOUT = 3;
/**
* Error state returned for operations like enrollment; the operation cannot be completed
* because there's not enough storage remaining to complete the operation.
*/
- int FACE_ERROR_NO_SPACE = 4;
+ public static final int FACE_ERROR_NO_SPACE = 4;
/**
* The operation was canceled because the face authentication sensor is unavailable. For
* example, this may happen when the user is switched, the device is locked or another pending
* operation prevents or disables it.
*/
- int FACE_ERROR_CANCELED = 5;
+ public static final int FACE_ERROR_CANCELED = 5;
/**
* The {@link FaceManager#remove} call failed. Typically this will happen when the
* provided face id was incorrect.
*/
- int FACE_ERROR_UNABLE_TO_REMOVE = 6;
+ public static final int FACE_ERROR_UNABLE_TO_REMOVE = 6;
/**
* The operation was canceled because the API is locked out due to too many attempts.
* This occurs after 5 failed attempts, and lasts for 30 seconds.
*/
- int FACE_ERROR_LOCKOUT = 7;
+ public static final int FACE_ERROR_LOCKOUT = 7;
/**
* Hardware vendors may extend this list if there are conditions that do not fall under one of
@@ -127,46 +127,46 @@
* expected to show the error message string if they happen, but are advised not to rely on the
* message id since they will be device and vendor-specific
*/
- int FACE_ERROR_VENDOR = 8;
+ public static final int FACE_ERROR_VENDOR = 8;
/**
* The operation was canceled because FACE_ERROR_LOCKOUT occurred too many times.
* Face authentication is disabled until the user unlocks with strong authentication
* (PIN/Pattern/Password)
*/
- int FACE_ERROR_LOCKOUT_PERMANENT = 9;
+ public static final int FACE_ERROR_LOCKOUT_PERMANENT = 9;
/**
* The user canceled the operation. Upon receiving this, applications should use alternate
* authentication (e.g. a password). The application should also provide the means to return
* to face authentication, such as a "use face authentication" button.
*/
- int FACE_ERROR_USER_CANCELED = 10;
+ public static final int FACE_ERROR_USER_CANCELED = 10;
/**
* The user does not have a face enrolled.
*/
- int FACE_ERROR_NOT_ENROLLED = 11;
+ public static final int FACE_ERROR_NOT_ENROLLED = 11;
/**
* The device does not have a face sensor. This message will propagate if the calling app
* ignores the result from PackageManager.hasFeature(FEATURE_FACE) and calls
* this API anyway. Apps should always check for the feature before calling this API.
*/
- int FACE_ERROR_HW_NOT_PRESENT = 12;
+ public static final int FACE_ERROR_HW_NOT_PRESENT = 12;
/**
* The user pressed the negative button. This is a placeholder that is currently only used
* by the support library.
*/
- int FACE_ERROR_NEGATIVE_BUTTON = 13;
+ public static final int FACE_ERROR_NEGATIVE_BUTTON = 13;
/**
* The device does not have pin, pattern, or password set up. See
* {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)} and
* {@link KeyguardManager#isDeviceSecure()}
*/
- int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;
+ public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;
/**
* A security vulnerability has been discovered and the sensor is unavailable until a
@@ -174,30 +174,30 @@
* authentication was requested with {@link Authenticators#BIOMETRIC_STRONG}, but the
* sensor's strength can currently only meet {@link Authenticators#BIOMETRIC_WEAK}.
*/
- int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15;
+ public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15;
/**
* Authentication cannot proceed because re-enrollment is required.
*/
- int BIOMETRIC_ERROR_RE_ENROLL = 16;
+ public static final int BIOMETRIC_ERROR_RE_ENROLL = 16;
/**
* Unknown error received from the HAL.
*/
- int FACE_ERROR_UNKNOWN = 17;
+ public static final int FACE_ERROR_UNKNOWN = 17;
/**
* A power press stopped this biometric operation.
* @hide
*/
- int BIOMETRIC_ERROR_POWER_PRESSED = 19;
+ public static final int BIOMETRIC_ERROR_POWER_PRESSED = 19;
/**
* Vendor codes received from the HAL start at 0. Codes that the framework exposes to keyguard
* append this value for some reason. We should probably remove this and just send the actual
* vendor code.
*/
- int FACE_ERROR_VENDOR_BASE = 1000;
+ public static final int FACE_ERROR_VENDOR_BASE = 1000;
//
// Image acquisition messages. These will not be sent to the user, since they conflict with
@@ -232,18 +232,18 @@
FACE_ACQUIRED_DARK_GLASSES_DETECTED,
FACE_ACQUIRED_MOUTH_COVERING_DETECTED})
@Retention(RetentionPolicy.SOURCE)
- @interface FaceAcquired {}
+ public @interface FaceAcquired {}
/**
* The image acquired was good.
*/
- int FACE_ACQUIRED_GOOD = 0;
+ public static final int FACE_ACQUIRED_GOOD = 0;
/**
* The face image was not good enough to process due to a detected condition.
* (See {@link #FACE_ACQUIRED_TOO_BRIGHT or @link #FACE_ACQUIRED_TOO_DARK}).
*/
- int FACE_ACQUIRED_INSUFFICIENT = 1;
+ public static final int FACE_ACQUIRED_INSUFFICIENT = 1;
/**
* The face image was too bright due to too much ambient light.
@@ -252,7 +252,7 @@
* The user is expected to take action to retry in better lighting conditions
* when this is returned.
*/
- int FACE_ACQUIRED_TOO_BRIGHT = 2;
+ public static final int FACE_ACQUIRED_TOO_BRIGHT = 2;
/**
* The face image was too dark due to illumination light obscured.
@@ -261,65 +261,65 @@
* The user is expected to take action to retry in better lighting conditions
* when this is returned.
*/
- int FACE_ACQUIRED_TOO_DARK = 3;
+ public static final int FACE_ACQUIRED_TOO_DARK = 3;
/**
* The detected face is too close to the sensor, and the image can't be processed.
* The user should be informed to move farther from the sensor when this is returned.
*/
- int FACE_ACQUIRED_TOO_CLOSE = 4;
+ public static final int FACE_ACQUIRED_TOO_CLOSE = 4;
/**
* The detected face is too small, as the user might be too far from the sensor.
* The user should be informed to move closer to the sensor when this is returned.
*/
- int FACE_ACQUIRED_TOO_FAR = 5;
+ public static final int FACE_ACQUIRED_TOO_FAR = 5;
/**
* Only the upper part of the face was detected. The sensor field of view is too high.
* The user should be informed to move up with respect to the sensor when this is returned.
*/
- int FACE_ACQUIRED_TOO_HIGH = 6;
+ public static final int FACE_ACQUIRED_TOO_HIGH = 6;
/**
* Only the lower part of the face was detected. The sensor field of view is too low.
* The user should be informed to move down with respect to the sensor when this is returned.
*/
- int FACE_ACQUIRED_TOO_LOW = 7;
+ public static final int FACE_ACQUIRED_TOO_LOW = 7;
/**
* Only the right part of the face was detected. The sensor field of view is too far right.
* The user should be informed to move to the right with respect to the sensor
* when this is returned.
*/
- int FACE_ACQUIRED_TOO_RIGHT = 8;
+ public static final int FACE_ACQUIRED_TOO_RIGHT = 8;
/**
* Only the left part of the face was detected. The sensor field of view is too far left.
* The user should be informed to move to the left with respect to the sensor
* when this is returned.
*/
- int FACE_ACQUIRED_TOO_LEFT = 9;
+ public static final int FACE_ACQUIRED_TOO_LEFT = 9;
/**
* The user's eyes have strayed away from the sensor. If this message is sent, the user should
* be informed to look at the device. If the user can't be found in the frame, one of the other
* acquisition messages should be sent, e.g. FACE_ACQUIRED_NOT_DETECTED.
*/
- int FACE_ACQUIRED_POOR_GAZE = 10;
+ public static final int FACE_ACQUIRED_POOR_GAZE = 10;
/**
* No face was detected in front of the sensor.
* The user should be informed to point the sensor to a face when this is returned.
*/
- int FACE_ACQUIRED_NOT_DETECTED = 11;
+ public static final int FACE_ACQUIRED_NOT_DETECTED = 11;
/**
* Too much motion was detected.
* The user should be informed to keep their face steady relative to the
* sensor.
*/
- int FACE_ACQUIRED_TOO_MUCH_MOTION = 12;
+ public static final int FACE_ACQUIRED_TOO_MUCH_MOTION = 12;
/**
* The sensor needs to be re-calibrated. This is an unexpected condition, and should only be
@@ -327,20 +327,20 @@
* requires user intervention, e.g. re-enrolling. The expected response to this message is to
* direct the user to re-enroll.
*/
- int FACE_ACQUIRED_RECALIBRATE = 13;
+ public static final int FACE_ACQUIRED_RECALIBRATE = 13;
/**
* The face is too different from a previous acquisition. This condition
* only applies to enrollment. This can happen if the user passes the
* device to someone else in the middle of enrollment.
*/
- int FACE_ACQUIRED_TOO_DIFFERENT = 14;
+ public static final int FACE_ACQUIRED_TOO_DIFFERENT = 14;
/**
* The face is too similar to a previous acquisition. This condition only
* applies to enrollment. The user should change their pose.
*/
- int FACE_ACQUIRED_TOO_SIMILAR = 15;
+ public static final int FACE_ACQUIRED_TOO_SIMILAR = 15;
/**
* The magnitude of the pan angle of the user’s face with respect to the sensor’s
@@ -352,7 +352,7 @@
*
* The user should be informed to look more directly at the camera.
*/
- int FACE_ACQUIRED_PAN_TOO_EXTREME = 16;
+ public static final int FACE_ACQUIRED_PAN_TOO_EXTREME = 16;
/**
* The magnitude of the tilt angle of the user’s face with respect to the sensor’s
@@ -363,7 +363,7 @@
*
* The user should be informed to look more directly at the camera.
*/
- int FACE_ACQUIRED_TILT_TOO_EXTREME = 17;
+ public static final int FACE_ACQUIRED_TILT_TOO_EXTREME = 17;
/**
* The magnitude of the roll angle of the user’s face with respect to the sensor’s
@@ -375,7 +375,7 @@
*
* The user should be informed to look more directly at the camera.
*/
- int FACE_ACQUIRED_ROLL_TOO_EXTREME = 18;
+ public static final int FACE_ACQUIRED_ROLL_TOO_EXTREME = 18;
/**
* The user’s face has been obscured by some object.
@@ -383,7 +383,7 @@
* The user should be informed to remove any objects from the line of sight from
* the sensor to the user’s face.
*/
- int FACE_ACQUIRED_FACE_OBSCURED = 19;
+ public static final int FACE_ACQUIRED_FACE_OBSCURED = 19;
/**
* This message represents the earliest message sent at the beginning of the authentication
@@ -393,47 +393,47 @@
* The framework will measure latency based on the time between the last START message and the
* onAuthenticated callback.
*/
- int FACE_ACQUIRED_START = 20;
+ public static final int FACE_ACQUIRED_START = 20;
/**
* The sensor is dirty. The user should be informed to clean the sensor.
*/
- int FACE_ACQUIRED_SENSOR_DIRTY = 21;
+ public static final int FACE_ACQUIRED_SENSOR_DIRTY = 21;
/**
* Hardware vendors may extend this list if there are conditions that do not fall under one of
* the above categories. Vendors are responsible for providing error strings for these errors.
*/
- int FACE_ACQUIRED_VENDOR = 22;
+ public static final int FACE_ACQUIRED_VENDOR = 22;
/**
* Unknown acquired code received from the HAL.
*/
- int FACE_ACQUIRED_UNKNOWN = 23;
+ public static final int FACE_ACQUIRED_UNKNOWN = 23;
/**
* The first frame from the camera has been received.
*/
- int FACE_ACQUIRED_FIRST_FRAME_RECEIVED = 24;
+ public static final int FACE_ACQUIRED_FIRST_FRAME_RECEIVED = 24;
/**
* Dark glasses detected. This can be useful for providing relevant feedback to the user and
* enabling an alternative authentication logic if the implementation supports it.
*/
- int FACE_ACQUIRED_DARK_GLASSES_DETECTED = 25;
+ public static final int FACE_ACQUIRED_DARK_GLASSES_DETECTED = 25;
/**
* A face mask or face covering detected. This can be useful for providing relevant feedback to
* the user and enabling an alternative authentication logic if the implementation supports it.
*/
- int FACE_ACQUIRED_MOUTH_COVERING_DETECTED = 26;
+ public static final int FACE_ACQUIRED_MOUTH_COVERING_DETECTED = 26;
/**
* Vendor codes received from the HAL start at 0. Codes that the framework exposes to keyguard
* append this value for some reason. We should probably remove this and just send the actual
* vendor code.
*/
- int FACE_ACQUIRED_VENDOR_BASE = 1000;
+ public static final int FACE_ACQUIRED_VENDOR_BASE = 1000;
/**
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 2592630..d340f3f 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -20,6 +20,44 @@
import static android.Manifest.permission.MANAGE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
+import static android.hardware.biometrics.BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL;
+import static android.hardware.biometrics.BiometricFaceConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_GOOD;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_INSUFFICIENT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_PAN_TOO_EXTREME;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_POOR_GAZE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_RECALIBRATE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_ROLL_TOO_EXTREME;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_SENSOR_DIRTY;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_START;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TILT_TOO_EXTREME;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DIFFERENT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_FAR;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_MUCH_MOTION;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_SIMILAR;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_VENDOR;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_CANCELED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_NOT_PRESENT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_NOT_ENROLLED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_NO_SPACE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_USER_CANCELED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_VENDOR;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -29,7 +67,6 @@
import android.content.pm.PackageManager;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.CryptoObject;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
@@ -58,7 +95,7 @@
* @hide
*/
@SystemService(Context.FACE_SERVICE)
-public class FaceManager implements BiometricAuthenticator, BiometricFaceConstants {
+public class FaceManager implements BiometricAuthenticator {
private static final String TAG = "FaceManager";
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 02e787b..51758aa 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -43,6 +43,13 @@
}
flag {
+ name: "unlocked_storage_api"
+ namespace: "hardware_backed_security"
+ description: "Feature flag for unlocked-only storage API"
+ bug: "325129836"
+}
+
+flag {
name: "deprecate_fsv_sig"
namespace: "hardware_backed_security"
description: "Feature flag for deprecating .fsv_sig"
diff --git a/core/java/android/service/dreams/DreamActivity.java b/core/java/android/service/dreams/DreamActivity.java
index a389223..7487d90 100644
--- a/core/java/android/service/dreams/DreamActivity.java
+++ b/core/java/android/service/dreams/DreamActivity.java
@@ -18,9 +18,12 @@
import android.annotation.Nullable;
import android.app.Activity;
+import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
+import com.android.internal.annotations.VisibleForTesting;
+
/**
* The Activity used by the {@link DreamService} to draw screensaver content
* on the screen. This activity runs in dream application's process, but is started by a
@@ -41,6 +44,7 @@
*
* @hide
*/
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public class DreamActivity extends Activity {
static final String EXTRA_CALLBACK = "binder";
static final String EXTRA_DREAM_TITLE = "title";
@@ -53,19 +57,55 @@
public void onCreate(@Nullable Bundle bundle) {
super.onCreate(bundle);
- final String title = getIntent().getStringExtra(EXTRA_DREAM_TITLE);
+ final String title = getTitle(getIntent());
if (!TextUtils.isEmpty(title)) {
setTitle(title);
}
- final Object callback = getIntent().getExtras().getBinder(EXTRA_CALLBACK);
- if (callback instanceof DreamService.DreamActivityCallbacks) {
- mCallback = (DreamService.DreamActivityCallbacks) callback;
- mCallback.onActivityCreated(this);
- } else {
- mCallback = null;
+ mCallback = getCallback(getIntent());
+
+ if (mCallback == null) {
finishAndRemoveTask();
+ return;
}
+
+ mCallback.onActivityCreated(this);
+ }
+
+ /**
+ * Sets the title of the dream in the intent for starting the {@link DreamActivity}.
+ */
+ public static void setTitle(Intent intent, CharSequence title) {
+ if (TextUtils.isEmpty(title)) {
+ return;
+ }
+
+ intent.putExtra(DreamActivity.EXTRA_DREAM_TITLE, title);
+ }
+
+ /**
+ * Gets the title of the dream from the intent used to start the {@link DreamActivity}.
+ */
+ public static String getTitle(Intent intent) {
+ return intent.getStringExtra(EXTRA_DREAM_TITLE);
+ }
+
+ /**
+ * Sets the dream callback in the intent for starting the {@link DreamActivity}.
+ */
+ public static void setCallback(Intent intent, DreamService.DreamActivityCallbacks callback) {
+ intent.putExtra(DreamActivity.EXTRA_CALLBACK, callback);
+ }
+
+ /**
+ * Retrieves the dream callback from the intent used to start the {@link DreamActivity}.
+ */
+ public static DreamService.DreamActivityCallbacks getCallback(Intent intent) {
+ final Object binder = intent.getExtras().getBinder(EXTRA_CALLBACK);
+
+ return (binder instanceof DreamService.DreamActivityCallbacks)
+ ? (DreamService.DreamActivityCallbacks) binder
+ : null;
}
@Override
diff --git a/core/java/android/service/dreams/DreamOverlayConnectionHandler.java b/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
index cafe02a..85a13c7 100644
--- a/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
+++ b/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
@@ -39,7 +39,7 @@
*
* @hide
*/
-@VisibleForTesting
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public final class DreamOverlayConnectionHandler {
private static final String TAG = "DreamOverlayConnection";
diff --git a/core/java/android/service/dreams/DreamOverlayService.java b/core/java/android/service/dreams/DreamOverlayService.java
index 5da0cb4..17d2790 100644
--- a/core/java/android/service/dreams/DreamOverlayService.java
+++ b/core/java/android/service/dreams/DreamOverlayService.java
@@ -16,6 +16,7 @@
package android.service.dreams;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
@@ -84,7 +85,14 @@
mService.comeToFront(this);
}
- private void onExitRequested() {
+ @Override
+ public void onWakeRequested() {
+ if (Flags.dreamWakeRedirect()) {
+ mService.onWakeRequested();
+ }
+ }
+
+ private void requestExit() {
try {
mDreamOverlayCallback.onExitRequested();
} catch (RemoteException e) {
@@ -92,6 +100,14 @@
}
}
+ private void redirectWake(boolean redirect) {
+ try {
+ mDreamOverlayCallback.onRedirectWake(redirect);
+ } catch (RemoteException e) {
+ Log.e(TAG, "could not request redirect wake", e);
+ }
+ }
+
private boolean shouldShowComplications() {
return mShowComplications;
}
@@ -229,7 +245,35 @@
throw new IllegalStateException("requested exit with no dream present");
}
- mCurrentClient.onExitRequested();
+ mCurrentClient.requestExit();
+ }
+
+ /**
+ * Called to inform the dream to redirect waking to this overlay rather than exiting.
+ * @param redirect {@code true} if waking up should be redirected. {@code false} otherwise.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_DREAM_WAKE_REDIRECT)
+ public final void redirectWake(boolean redirect) {
+ if (!Flags.dreamWakeRedirect()) {
+ return;
+ }
+
+ if (mCurrentClient == null) {
+ throw new IllegalStateException("redirected wake with no dream present");
+ }
+
+ mCurrentClient.redirectWake(redirect);
+ }
+
+ /**
+ * Invoked when the dream has requested to exit. This is only called if the dream overlay
+ * has explicitly requested exits to be redirected via {@link #redirectWake(boolean)}.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_DREAM_WAKE_REDIRECT)
+ public void onWakeRequested() {
}
/**
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index c26d83c..997c9581 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -41,7 +41,6 @@
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
import android.os.Binder;
import android.os.Build;
@@ -54,11 +53,9 @@
import android.os.ServiceManager;
import android.service.controls.flags.Flags;
import android.service.dreams.utils.DreamAccessibility;
-import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
-import android.util.Xml;
import android.view.ActionMode;
import android.view.Display;
import android.view.KeyEvent;
@@ -75,13 +72,10 @@
import android.view.accessibility.AccessibilityEvent;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
import java.io.FileDescriptor;
-import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -200,13 +194,6 @@
"android.service.dreams.DreamService";
/**
- * The name of the extra where the dream overlay component is stored.
- * @hide
- */
- public static final String EXTRA_DREAM_OVERLAY_COMPONENT =
- "android.service.dream.DreamService.dream_overlay_component";
-
- /**
* Name under which a Dream publishes information about itself.
* This meta-data must reference an XML resource containing
* a <code><{@link android.R.styleable#Dream dream}></code>
@@ -230,6 +217,7 @@
* The default value for dream category
* @hide
*/
+ @VisibleForTesting
public static final int DREAM_CATEGORY_DEFAULT = 0;
/**
@@ -253,8 +241,14 @@
@Retention(RetentionPolicy.SOURCE)
@interface DreamCategory {}
+ /**
+ * The name of the extra where the dream overlay component is stored.
+ */
+ static final String EXTRA_DREAM_OVERLAY_COMPONENT =
+ "android.service.dream.DreamService.dream_overlay_component";
+
private final IDreamManager mDreamManager;
- private final Handler mHandler = new Handler(Looper.getMainLooper());
+ private final Handler mHandler;
private IBinder mDreamToken;
private Window mWindow;
private Activity mActivity;
@@ -287,9 +281,128 @@
private Integer mTrackingConfirmKey = null;
+ private boolean mRedirectWake;
+
+ private final Injector mInjector;
+
+ /**
+ * A helper object to inject dependencies into {@link DreamService}.
+ * @hide
+ */
+ @VisibleForTesting
+ public interface Injector {
+ /** Initializes the Injector */
+ void init(Context context);
+
+ /** Creates and returns the dream overlay connection */
+ DreamOverlayConnectionHandler createOverlayConnection(ComponentName overlayComponent);
+
+ /** Returns the {@link DreamActivity} component */
+ ComponentName getDreamActivityComponent();
+
+ /** Returns the dream component */
+ ComponentName getDreamComponent();
+
+ /** Returns the dream package name */
+ String getDreamPackageName();
+
+ /** Returns the {@link DreamManager} */
+ IDreamManager getDreamManager();
+
+ /** Returns the associated service info */
+ ServiceInfo getServiceInfo();
+
+ /** Returns the handler to be used for any posted operation */
+ Handler getHandler();
+
+ /** Returns the package manager */
+ PackageManager getPackageManager();
+
+ /** Returns the resources */
+ Resources getResources();
+ }
+
+ private static final class DefaultInjector implements Injector {
+ private Context mContext;
+ private Class<?> mClassName;
+
+ public void init(Context context) {
+ mContext = context;
+ mClassName = context.getClass();
+ }
+
+ @Override
+ public DreamOverlayConnectionHandler createOverlayConnection(
+ ComponentName overlayComponent) {
+ final Resources resources = mContext.getResources();
+
+ return new DreamOverlayConnectionHandler(
+ /* context= */ mContext,
+ Looper.getMainLooper(),
+ new Intent().setComponent(overlayComponent),
+ resources.getInteger(R.integer.config_minDreamOverlayDurationMs),
+ resources.getInteger(R.integer.config_dreamOverlayMaxReconnectAttempts),
+ resources.getInteger(R.integer.config_dreamOverlayReconnectTimeoutMs));
+ }
+
+ @Override
+ public ComponentName getDreamActivityComponent() {
+ return new ComponentName(mContext, DreamActivity.class);
+ }
+
+ @Override
+ public ComponentName getDreamComponent() {
+ return new ComponentName(mContext, mClassName);
+ }
+
+ @Override
+ public String getDreamPackageName() {
+ return mContext.getApplicationContext().getPackageName();
+ }
+
+ @Override
+ public IDreamManager getDreamManager() {
+ return IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
+ }
+
+ @Override
+ public ServiceInfo getServiceInfo() {
+ return fetchServiceInfo(mContext, getDreamComponent());
+ }
+
+ @Override
+ public Handler getHandler() {
+ return new Handler(Looper.getMainLooper());
+ }
+
+ @Override
+ public PackageManager getPackageManager() {
+ return mContext.getPackageManager();
+ }
+
+ @Override
+ public Resources getResources() {
+ return mContext.getResources();
+ }
+
+ }
public DreamService() {
- mDreamManager = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
+ this(new DefaultInjector());
+ }
+
+ /**
+ * Constructor for test purposes.
+ *
+ * @param injector used for providing dependencies
+ * @hide
+ */
+ @VisibleForTesting
+ public DreamService(Injector injector) {
+ mInjector = injector;
+ mInjector.init(this);
+ mDreamManager = mInjector.getDreamManager();
+ mHandler = mInjector.getHandler();
}
/**
@@ -997,15 +1110,20 @@
public void onCreate() {
if (mDebug) Slog.v(mTag, "onCreate()");
- mDreamComponent = new ComponentName(this, getClass());
- mShouldShowComplications = fetchShouldShowComplications(this /*context*/,
- fetchServiceInfo(this /*context*/, mDreamComponent));
+ mDreamComponent = mInjector.getDreamComponent();
+ mShouldShowComplications = fetchShouldShowComplications(mInjector.getPackageManager(),
+ mInjector.getServiceInfo());
mOverlayCallback = new IDreamOverlayCallback.Stub() {
@Override
public void onExitRequested() {
// Simply finish dream when exit is requested.
mHandler.post(() -> finish());
}
+
+ @Override
+ public void onRedirectWake(boolean redirect) {
+ mRedirectWake = redirect;
+ }
};
super.onCreate();
@@ -1066,16 +1184,7 @@
// Connect to the overlay service if present.
if (!mWindowless && overlayComponent != null) {
- final Resources resources = getResources();
- final Intent overlayIntent = new Intent().setComponent(overlayComponent);
-
- mOverlayConnection = new DreamOverlayConnectionHandler(
- /* context= */ this,
- Looper.getMainLooper(),
- overlayIntent,
- resources.getInteger(R.integer.config_minDreamOverlayDurationMs),
- resources.getInteger(R.integer.config_dreamOverlayMaxReconnectAttempts),
- resources.getInteger(R.integer.config_dreamOverlayReconnectTimeoutMs));
+ mOverlayConnection = mInjector.createOverlayConnection(overlayComponent);
if (!mOverlayConnection.bind()) {
// Binding failed.
@@ -1181,6 +1290,18 @@
+ ", mFinished=" + mFinished);
}
+ if (!fromSystem && mOverlayConnection != null && mRedirectWake) {
+ mOverlayConnection.addConsumer(overlay -> {
+ try {
+ overlay.onWakeRequested();
+ } catch (RemoteException e) {
+ Log.e(mTag, "could not inform overlay of dream wakeup:" + e);
+ }
+ });
+
+ return;
+ }
+
if (!mWaking && !mFinished) {
mWaking = true;
@@ -1242,11 +1363,25 @@
@TestApi
public static DreamMetadata getDreamMetadata(@NonNull Context context,
@Nullable ServiceInfo serviceInfo) {
+ return getDreamMetadata(context.getPackageManager(), serviceInfo);
+ }
+
+ /**
+ * Parses and returns metadata of the dream service indicated by the service info. Returns null
+ * if metadata cannot be found.
+ *
+ * Note that {@link ServiceInfo} must be fetched with {@link PackageManager#GET_META_DATA} flag.
+ *
+ * @hide
+ */
+ @Nullable
+ public static DreamMetadata getDreamMetadata(@NonNull PackageManager packageManager,
+ @Nullable ServiceInfo serviceInfo) {
if (serviceInfo == null) return null;
- final PackageManager pm = context.getPackageManager();
-
- try (TypedArray rawMetadata = readMetadata(pm, serviceInfo)) {
+ try (TypedArray rawMetadata = packageManager.extractPackageItemInfoAttributes(serviceInfo,
+ DreamService.DREAM_META_DATA, DREAM_META_DATA_ROOT_TAG,
+ com.android.internal.R.styleable.Dream)) {
if (rawMetadata == null) return null;
return new DreamMetadata(
convertToComponentName(
@@ -1261,47 +1396,6 @@
}
}
- /**
- * Returns the raw XML metadata fetched from the {@link ServiceInfo}.
- *
- * Returns <code>null</code> if the {@link ServiceInfo} doesn't contain valid dream metadata.
- */
- @Nullable
- private static TypedArray readMetadata(PackageManager pm, ServiceInfo serviceInfo) {
- if (serviceInfo == null || serviceInfo.metaData == null) {
- return null;
- }
-
- try (XmlResourceParser parser =
- serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA)) {
- if (parser == null) {
- if (DEBUG) Log.w(TAG, "No " + DreamService.DREAM_META_DATA + " metadata");
- return null;
- }
-
- final AttributeSet attrs = Xml.asAttributeSet(parser);
- while (true) {
- final int type = parser.next();
- if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) {
- break;
- }
- }
-
- if (!parser.getName().equals(DREAM_META_DATA_ROOT_TAG)) {
- if (DEBUG) {
- Log.w(TAG, "Metadata does not start with " + DREAM_META_DATA_ROOT_TAG + " tag");
- }
- return null;
- }
-
- return pm.getResourcesForApplication(serviceInfo.applicationInfo).obtainAttributes(
- attrs, com.android.internal.R.styleable.Dream);
- } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
- if (DEBUG) Log.e(TAG, "Error parsing: " + serviceInfo.packageName, e);
- return null;
- }
- }
-
@Nullable
private static ComponentName convertToComponentName(@Nullable String flattenedString,
ServiceInfo serviceInfo) {
@@ -1406,14 +1500,16 @@
// for the DreamActivity to report onActivityCreated via
// DreamServiceWrapper.onActivityCreated.
if (!mWindowless) {
- Intent i = new Intent(this, DreamActivity.class);
- i.setPackage(getApplicationContext().getPackageName());
+ Intent i = new Intent();
+ i.setComponent(mInjector.getDreamActivityComponent());
+ i.setPackage(mInjector.getDreamPackageName());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
- i.putExtra(DreamActivity.EXTRA_CALLBACK, new DreamActivityCallbacks(mDreamToken));
- final ServiceInfo serviceInfo = fetchServiceInfo(this,
- new ComponentName(this, getClass()));
- i.putExtra(DreamActivity.EXTRA_DREAM_TITLE,
- fetchDreamLabel(this, serviceInfo, isPreviewMode));
+ DreamActivity.setCallback(i, new DreamActivityCallbacks(mDreamToken));
+ final ServiceInfo serviceInfo = mInjector.getServiceInfo();
+ final CharSequence title = fetchDreamLabel(mInjector.getPackageManager(),
+ mInjector.getResources(), serviceInfo, isPreviewMode);
+
+ DreamActivity.setTitle(i, title);
try {
mDreamManager.startDreamActivity(i);
@@ -1539,9 +1635,9 @@
* the dream should show complications on the overlay. If not defined, returns
* {@link DreamService#DEFAULT_SHOW_COMPLICATIONS}.
*/
- private static boolean fetchShouldShowComplications(Context context,
+ private static boolean fetchShouldShowComplications(@NonNull PackageManager packageManager,
@Nullable ServiceInfo serviceInfo) {
- final DreamMetadata metadata = getDreamMetadata(context, serviceInfo);
+ final DreamMetadata metadata = getDreamMetadata(packageManager, serviceInfo);
if (metadata != null) {
return metadata.showComplications;
}
@@ -1549,19 +1645,20 @@
}
@Nullable
- private static CharSequence fetchDreamLabel(Context context,
+ private static CharSequence fetchDreamLabel(
+ PackageManager pm,
+ Resources resources,
@Nullable ServiceInfo serviceInfo,
boolean isPreviewMode) {
if (serviceInfo == null) {
return null;
}
- final PackageManager pm = context.getPackageManager();
final CharSequence dreamLabel = serviceInfo.loadLabel(pm);
if (!isPreviewMode || dreamLabel == null) {
return dreamLabel;
}
// When in preview mode, return a special label indicating the dream is in preview.
- return context.getResources().getString(R.string.dream_preview_title, dreamLabel);
+ return resources.getString(R.string.dream_preview_title, dreamLabel);
}
@Nullable
@@ -1643,14 +1740,16 @@
}
/** @hide */
- final class DreamActivityCallbacks extends Binder {
+ @VisibleForTesting
+ public final class DreamActivityCallbacks extends Binder {
private final IBinder mActivityDreamToken;
DreamActivityCallbacks(IBinder token) {
mActivityDreamToken = token;
}
- void onActivityCreated(DreamActivity activity) {
+ /** Callback when the {@link DreamActivity} has been created */
+ public void onActivityCreated(DreamActivity activity) {
if (mActivityDreamToken != mDreamToken || mFinished) {
Slog.d(TAG, "DreamActivity was created after the dream was finished or "
+ "a new dream started, finishing DreamActivity");
@@ -1672,8 +1771,8 @@
onWindowCreated(activity.getWindow());
}
- // If DreamActivity is destroyed, wake up from Dream.
- void onActivityDestroyed() {
+ /** Callback when the {@link DreamActivity} has been destroyed */
+ public void onActivityDestroyed() {
mActivity = null;
mWindow = null;
detach();
@@ -1685,6 +1784,7 @@
*
* @hide
*/
+ @VisibleForTesting
@TestApi
public static final class DreamMetadata {
@Nullable
@@ -1700,7 +1800,11 @@
@FlaggedApi(Flags.FLAG_HOME_PANEL_DREAM)
public final int dreamCategory;
- DreamMetadata(
+ /**
+ * @hide
+ */
+ @VisibleForTesting
+ public DreamMetadata(
ComponentName settingsActivity,
Drawable previewImage,
boolean showComplications,
@@ -1715,4 +1819,14 @@
}
}
}
+
+ /**
+ * Sets the dream overlay component to be used by the dream.
+ *
+ * @hide
+ */
+ @VisibleForTesting
+ public static void setDreamOverlayComponent(Intent intent, ComponentName component) {
+ intent.putExtra(DreamService.EXTRA_DREAM_OVERLAY_COMPONENT, component);
+ }
}
diff --git a/core/java/android/service/dreams/IDreamOverlayCallback.aidl b/core/java/android/service/dreams/IDreamOverlayCallback.aidl
index ec76a33..fae4780 100644
--- a/core/java/android/service/dreams/IDreamOverlayCallback.aidl
+++ b/core/java/android/service/dreams/IDreamOverlayCallback.aidl
@@ -23,9 +23,14 @@
*
* @hide
*/
-interface IDreamOverlayCallback {
+oneway interface IDreamOverlayCallback {
/**
* Invoked to request the dream exit.
*/
void onExitRequested();
+
+ /**
+ * Invoked to redirect wake requests to overlay instead.
+ */
+ void onRedirectWake(boolean redirect);
}
\ No newline at end of file
diff --git a/core/java/android/service/dreams/IDreamOverlayClient.aidl b/core/java/android/service/dreams/IDreamOverlayClient.aidl
index 5054d4d..0eb15a0 100644
--- a/core/java/android/service/dreams/IDreamOverlayClient.aidl
+++ b/core/java/android/service/dreams/IDreamOverlayClient.aidl
@@ -43,6 +43,9 @@
/** Called when the dream has ended. */
void endDream();
+ /** Called when wake up has been redirected to the overlay. */
+ void onWakeRequested();
+
/** Called when the dream is coming to the front. */
void comeToFront();
}
diff --git a/core/java/android/service/dreams/flags.aconfig b/core/java/android/service/dreams/flags.aconfig
index 0a458bc..f87cb85 100644
--- a/core/java/android/service/dreams/flags.aconfig
+++ b/core/java/android/service/dreams/flags.aconfig
@@ -21,6 +21,14 @@
}
flag {
+ name: "dream_wake_redirect"
+ namespace: "systemui"
+ description: "This flag enables using a host to handle displaying a dream's overlay rather than "
+ "relying on the dream's window"
+ bug: "334083490"
+}
+
+flag {
name: "dream_tracks_focus"
namespace: "communal"
description: "This flag enables the ability for dreams to track whether or not they have focus"
diff --git a/core/java/android/tracing/flags.aconfig b/core/java/android/tracing/flags.aconfig
index c50c384..74428aa 100644
--- a/core/java/android/tracing/flags.aconfig
+++ b/core/java/android/tracing/flags.aconfig
@@ -22,3 +22,11 @@
description: "Migrate IME tracing to Perfetto"
bug: "276433199"
}
+
+flag {
+ name: "perfetto_ime"
+ namespace: "windowing_tools"
+ description: "Migrate IME tracing to Perfetto"
+ is_fixed_read_only: true
+ bug: "276433199"
+}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 510a4a3..ddead88 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2430,12 +2430,6 @@
public static final int FRAME_RATE_CATEGORY_REASON_VELOCITY = 0x0600_0000;
/**
- * This indicates that the frame rate category was chosen because it is idle.
- * @hide
- */
- public static final int FRAME_RATE_CATEGORY_REASON_IDLE = 0x0700_0000;
-
- /**
* This indicates that the frame rate category was chosen because it is currently boosting.
* @hide
*/
@@ -4745,6 +4739,11 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
protected int mLeft;
/**
+ * The mLeft from the previous frame. Used for detecting movement for purposes of variable
+ * refresh rate.
+ */
+ private int mLastFrameLeft;
+ /**
* The distance in pixels from the left edge of this view's parent
* to the right edge of this view.
* {@hide}
@@ -4761,6 +4760,11 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
protected int mTop;
/**
+ * The mTop from the previous frame. Used for detecting movement for purposes of variable
+ * refresh rate.
+ */
+ private int mLastFrameTop;
+ /**
* The distance in pixels from the top edge of this view's parent
* to the bottom edge of this view.
* {@hide}
@@ -19535,7 +19539,6 @@
*/
public final void setTop(int top) {
if (top != mTop) {
- mPrivateFlags4 |= PFLAG4_HAS_MOVED;
final boolean matrixIsIdentity = hasIdentityMatrix();
if (matrixIsIdentity) {
if (mAttachInfo != null) {
@@ -20427,7 +20430,6 @@
*/
public void offsetTopAndBottom(int offset) {
if (offset != 0) {
- mPrivateFlags4 |= PFLAG4_HAS_MOVED;
final boolean matrixIsIdentity = hasIdentityMatrix();
if (matrixIsIdentity) {
if (isHardwareAccelerated()) {
@@ -20479,7 +20481,6 @@
*/
public void offsetLeftAndRight(int offset) {
if (offset != 0) {
- mPrivateFlags4 |= PFLAG4_HAS_MOVED;
final boolean matrixIsIdentity = hasIdentityMatrix();
if (matrixIsIdentity) {
if (isHardwareAccelerated()) {
@@ -25523,7 +25524,6 @@
}
if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
- mPrivateFlags4 |= PFLAG4_HAS_MOVED;
changed = true;
// Remember our drawn bit
@@ -33976,28 +33976,32 @@
// The most common case is when nothing is set, so this special case is called
// often.
if (mAttachInfo.mViewVelocityApi
- && (mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
- PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)
+ && ((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
+ PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
+ || mLastFrameTop != mTop)
&& viewRootImpl.shouldCheckFrameRate(false)
&& parent instanceof View
&& ((View) parent).mFrameContentVelocity <= 0) {
viewRootImpl.votePreferredFrameRate(MAX_FRAME_RATE, FRAME_RATE_COMPATIBILITY_GTE);
}
- if (!willNotDraw() && viewRootImpl.shouldCheckFrameRateCategory()) {
+ if (viewRootImpl.shouldCheckFrameRateCategory()) {
int frameRateCategory = calculateFrameRateCategory();
int category = frameRateCategory & ~FRAME_RATE_CATEGORY_REASON_MASK;
int reason = frameRateCategory & FRAME_RATE_CATEGORY_REASON_MASK;
viewRootImpl.votePreferredFrameRateCategory(category, reason, this);
mLastFrameRateCategory = frameRateCategory;
}
+ mLastFrameLeft = mLeft;
+ mLastFrameTop = mTop;
return;
}
if (viewRootImpl.shouldCheckFrameRate(frameRate > 0f)) {
float velocityFrameRate = 0f;
if (mAttachInfo.mViewVelocityApi) {
if (velocity < 0f
- && (mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
- PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)
+ && ((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
+ PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
+ || mLastFrameTop != mTop)
&& mParent instanceof View
&& ((View) mParent).mFrameContentVelocity <= 0
) {
@@ -34022,7 +34026,7 @@
}
}
- if (!willNotDraw() && viewRootImpl.shouldCheckFrameRateCategory()) {
+ if (viewRootImpl.shouldCheckFrameRateCategory()) {
if (sToolkitMetricsForFrameRateDecisionFlagValue) {
int width = mRight - mLeft;
int height = mBottom - mTop;
@@ -34030,7 +34034,7 @@
viewRootImpl.recordViewPercentage(sizePercentage);
}
- int frameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE;
+ int frameRateCategory;
if (Float.isNaN(frameRate)) {
frameRateCategory = calculateFrameRateCategory();
} else if (frameRate < 0) {
@@ -34055,6 +34059,10 @@
| FRAME_RATE_CATEGORY_REASON_INVALID;
}
}
+ } else {
+ // Category doesn't control it. It is directly controlled by frame rate
+ frameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE
+ | FRAME_RATE_CATEGORY_REASON_REQUESTED;
}
int category = frameRateCategory & ~FRAME_RATE_CATEGORY_REASON_MASK;
@@ -34062,6 +34070,8 @@
viewRootImpl.votePreferredFrameRateCategory(category, reason, this);
mLastFrameRateCategory = frameRateCategory;
}
+ mLastFrameLeft = mLeft;
+ mLastFrameTop = mTop;
}
private float convertVelocityToFrameRate(float velocityPps) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 701b2d3..2cb862c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -37,7 +37,6 @@
import static android.view.Surface.FRAME_RATE_COMPATIBILITY_GTE;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_BOOST;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_CONFLICTED;
-import static android.view.View.FRAME_RATE_CATEGORY_REASON_IDLE;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_INVALID;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_LARGE;
@@ -1088,16 +1087,10 @@
// The last preferred frame rate of the view that is mainly used to
// track the difference between the current preferred frame rate and the previous value.
private float mLastPreferredFrameRate = 0;
- // Used to check if there were any view invalidations in
- // the previous time frame (FRAME_RATE_IDLENESS_REEVALUATE_TIME).
- private boolean mHasInvalidation = false;
// Used to check if it is in the frame rate boosting period.
private boolean mIsFrameRateBoosting = false;
// Used to check if it is in touch boosting period.
private boolean mIsTouchBoosting = false;
- // Used to check if there is a message in the message queue
- // for idleness handling.
- private boolean mHasIdledMessage = false;
private boolean mDrawnThisFrame = false;
// Used to check if there is a conflict between different frame rate voting.
// Take 24 and 30 as an example, 24 is not a divisor of 30.
@@ -1108,10 +1101,6 @@
FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
// time for touch boost period.
private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000;
- // time for checking idle status periodically.
- private static final int FRAME_RATE_IDLENESS_CHECK_TIME_MILLIS = 500;
- // time for revaluating the idle status before lowering the frame rate.
- private static final int FRAME_RATE_IDLENESS_REEVALUATE_TIME = 1000;
// time for evaluating the interval between current time and
// the time when frame rate was set previously.
private static final int FRAME_RATE_SETTING_REEVALUATE_TIME = 100;
@@ -4263,7 +4252,6 @@
mHandler.sendEmptyMessageDelayed(MSG_FRAME_RATE_SETTING,
FRAME_RATE_SETTING_REEVALUATE_TIME);
}
- checkIdleness();
mFrameRateCategoryHighCount = mFrameRateCategoryHighCount > 0
? mFrameRateCategoryHighCount - 1 : mFrameRateCategoryHighCount;
mFrameRateCategoryNormalCount = mFrameRateCategoryNormalCount > 0
@@ -6445,8 +6433,6 @@
return "MSG_REFRESH_POINTER_ICON";
case MSG_TOUCH_BOOST_TIMEOUT:
return "MSG_TOUCH_BOOST_TIMEOUT";
- case MSG_CHECK_INVALIDATION_IDLE:
- return "MSG_CHECK_INVALIDATION_IDLE";
case MSG_FRAME_RATE_SETTING:
return "MSG_FRAME_RATE_SETTING";
}
@@ -6714,27 +6700,6 @@
mIsFrameRateBoosting = false;
mIsTouchBoosting = false;
break;
- case MSG_CHECK_INVALIDATION_IDLE:
- if (!mHasInvalidation && !mIsFrameRateBoosting && !mIsTouchBoosting) {
- mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE;
- mFrameRateCategoryChangeReason = FRAME_RATE_CATEGORY_REASON_IDLE;
- mFrameRateCategoryView = null;
- setPreferredFrameRateCategory(mPreferredFrameRateCategory);
- mHasIdledMessage = false;
- } else {
- /**
- * If there is no invalidation within a certain period,
- * we consider the display is idled.
- * We then set the frame rate catetogry to NO_PREFERENCE.
- * Note that SurfaceFlinger also has a mechanism to lower the refresh rate
- * if there is no updates of the buffer.
- */
- mHasInvalidation = false;
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_INVALIDATION_IDLE,
- FRAME_RATE_IDLENESS_REEVALUATE_TIME);
- mHasIdledMessage = true;
- }
- break;
case MSG_REFRESH_POINTER_ICON:
if (mPointerIconEvent == null) {
break;
@@ -6744,7 +6709,6 @@
case MSG_FRAME_RATE_SETTING:
mPreferredFrameRate = 0;
mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
- setPreferredFrameRate(mPreferredFrameRate);
break;
}
}
@@ -12649,7 +12613,6 @@
case FRAME_RATE_CATEGORY_REASON_REQUESTED -> str = "requested";
case FRAME_RATE_CATEGORY_REASON_INVALID -> str = "invalid frame rate";
case FRAME_RATE_CATEGORY_REASON_VELOCITY -> str = "velocity";
- case FRAME_RATE_CATEGORY_REASON_IDLE -> str = "idle";
case FRAME_RATE_CATEGORY_REASON_UNKNOWN -> str = "unknown";
case FRAME_RATE_CATEGORY_REASON_BOOST -> str = "boost";
case FRAME_RATE_CATEGORY_REASON_TOUCH -> str = "touch";
@@ -12718,7 +12681,6 @@
mFrameRateCategoryChangeReason = reason;
// mFrameRateCategoryView = view == null ? "-" : view.getClass().getSimpleName();
}
- mHasInvalidation = true;
mDrawnThisFrame = true;
}
@@ -12792,7 +12754,6 @@
mFrameRateCategoryHighCount = FRAME_RATE_CATEGORY_COUNT;
mFrameRateCategoryChangeReason = FRAME_RATE_CATEGORY_REASON_VELOCITY;
mFrameRateCategoryView = null;
- mHasInvalidation = true;
mDrawnThisFrame = true;
return;
}
@@ -12824,7 +12785,6 @@
mPreferredFrameRate = nextFrameRate;
mFrameRateCompatibility = nextFrameRateCompatibility;
- mHasInvalidation = true;
mDrawnThisFrame = true;
}
@@ -12944,19 +12904,8 @@
return false;
}
- private void checkIdleness() {
- if (!mHasIdledMessage) {
- // Check where the display is idled periodically.
- // If so, set the frame rate category to NO_PREFERENCE
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_INVALIDATION_IDLE,
- FRAME_RATE_IDLENESS_CHECK_TIME_MILLIS);
- mHasIdledMessage = true;
- }
- }
-
private void removeVrrMessages() {
mHandler.removeMessages(MSG_TOUCH_BOOST_TIMEOUT);
- mHandler.removeMessages(MSG_CHECK_INVALIDATION_IDLE);
mHandler.removeMessages(MSG_FRAME_RATE_SETTING);
}
@@ -12976,7 +12925,8 @@
mMinusOneFrameIntervalMillis = timeIntervalMillis;
mLastUpdateTimeMillis = currentTimeMillis;
- if (timeIntervalMillis >= INFREQUENT_UPDATE_INTERVAL_MILLIS) {
+ if (timeIntervalMillis + mMinusTwoFrameIntervalMillis
+ >= INFREQUENT_UPDATE_INTERVAL_MILLIS) {
int infrequentUpdateCount = mInfrequentUpdateCount;
mInfrequentUpdateCount = infrequentUpdateCount == INFREQUENT_UPDATE_COUNTS
? infrequentUpdateCount : infrequentUpdateCount + 1;
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 4f55441..d72207d 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -272,6 +272,7 @@
getOpenInWorkMessage(launchIntent, target.loadLabel(packageManagerForTargetUser)),
packageManagerForTargetUser);
+ ((Button) findViewById(R.id.button_open)).setText(getOpenInWorkButtonString(launchIntent));
View telephonyInfo = findViewById(R.id.miniresolver_info_section);
@@ -310,7 +311,15 @@
packageManagerForTargetUser);
View telephonyInfo = findViewById(R.id.miniresolver_info_section);
- telephonyInfo.setVisibility(View.GONE);
+ telephonyInfo.setVisibility(View.VISIBLE);
+
+ if (isTextMessageIntent(launchIntent)) {
+ ((TextView) findViewById(R.id.miniresolver_info_section_text)).setText(
+ R.string.miniresolver_private_space_messages_information);
+ } else {
+ ((TextView) findViewById(R.id.miniresolver_info_section_text)).setText(
+ R.string.miniresolver_private_space_phone_information);
+ }
}
private void buildMiniResolver(ResolveInfo target, Intent launchIntent, int targetUserId,
@@ -334,7 +343,6 @@
((Button) findViewById(R.id.use_same_profile_browser)).setText(R.string.cancel);
findViewById(R.id.use_same_profile_browser).setOnClickListener(v -> finish());
- ((Button) findViewById(R.id.button_open)).setText(getOpenInWorkButtonString(launchIntent));
findViewById(R.id.button_open).setOnClickListener(v -> {
startActivityAsCaller(
launchIntent,
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 5705b7e..7ac553c 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -48,8 +48,6 @@
public abstract class PackageMonitor extends android.content.BroadcastReceiver {
static final String TAG = "PackageMonitor";
- final IntentFilter mPackageFilt;
-
Context mRegisteredContext;
Handler mRegisteredHandler;
String[] mDisappearingPackages;
@@ -66,17 +64,32 @@
private Executor mExecutor;
+ final boolean mSupportsPackageRestartQuery;
+
@UnsupportedAppUsage
public PackageMonitor() {
+ this(true);
+ }
+
+ /**
+ * The constructor of PackageMonitor whose parameters clearly indicate whether support
+ * querying package restart event.
+ */
+ public PackageMonitor(boolean supportsPackageRestartQuery) {
+ mSupportsPackageRestartQuery = supportsPackageRestartQuery;
+ }
+
+ private IntentFilter getPackageFilter() {
final boolean isCore = UserHandle.isCore(android.os.Process.myUid());
- mPackageFilt = new IntentFilter();
+ IntentFilter filter = new IntentFilter();
// Settings app sends the broadcast
- mPackageFilt.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
- mPackageFilt.addDataScheme("package");
+ filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
+ filter.addDataScheme("package");
if (isCore) {
- mPackageFilt.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+ filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
}
+ return filter;
}
@UnsupportedAppUsage
@@ -91,7 +104,6 @@
(thread == null) ? BackgroundThread.getHandler() : new Handler(thread));
}
-
/**
* Register for notifications of package changes such as install, removal and other events.
*/
@@ -101,10 +113,13 @@
}
mRegisteredContext = context;
mRegisteredHandler = Objects.requireNonNull(handler);
- if (user != null) {
- context.registerReceiverAsUser(this, user, mPackageFilt, null, mRegisteredHandler);
- } else {
- context.registerReceiver(this, mPackageFilt, null, mRegisteredHandler);
+ if (mSupportsPackageRestartQuery) {
+ final IntentFilter filter = getPackageFilter();
+ if (user != null) {
+ context.registerReceiverAsUser(this, user, filter, null, mRegisteredHandler);
+ } else {
+ context.registerReceiver(this, filter, null, mRegisteredHandler);
+ }
}
if (mPackageMonitorCallback == null) {
PackageManager pm = mRegisteredContext.getPackageManager();
@@ -126,7 +141,9 @@
if (mRegisteredContext == null) {
throw new IllegalStateException("Not registered");
}
- mRegisteredContext.unregisterReceiver(this);
+ if (mSupportsPackageRestartQuery) {
+ mRegisteredContext.unregisterReceiver(this);
+ }
PackageManager pm = mRegisteredContext.getPackageManager();
if (pm != null && mPackageMonitorCallback != null) {
@@ -378,7 +395,7 @@
* @param intent the intent that contains package related event information
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
- public void doHandlePackageEvent(Intent intent) {
+ public final void doHandlePackageEvent(Intent intent) {
mChangeUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
UserHandle.USER_NULL);
if (mChangeUserId == UserHandle.USER_NULL) {
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index 9dec102..2f09a55 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -1340,35 +1340,39 @@
final int pixelStride = plane.getPixelStride();
final int rowStride = plane.getRowStride();
final int sampling = 10;
- final int[] borderLumas = new int[(width + height) * 2 / sampling];
+ final int[] histogram = new int[256];
// Grab the top and bottom borders.
int i = 0;
for (int x = 0, size = width - sampling; x < size; x += sampling) {
- borderLumas[i++] = getPixelLuminance(buffer, x, 0, pixelStride, rowStride);
- borderLumas[i++] = getPixelLuminance(buffer, x, height - 1, pixelStride, rowStride);
+ final int topLm = getPixelLuminance(buffer, x, 0, pixelStride, rowStride);
+ final int bottomLm = getPixelLuminance(buffer, x, height - 1, pixelStride, rowStride);
+ histogram[topLm]++;
+ histogram[bottomLm]++;
}
// Grab the left and right borders.
for (int y = 0, size = height - sampling; y < size; y += sampling) {
- borderLumas[i++] = getPixelLuminance(buffer, 0, y, pixelStride, rowStride);
- borderLumas[i++] = getPixelLuminance(buffer, width - 1, y, pixelStride, rowStride);
+ final int leftLm = getPixelLuminance(buffer, 0, y, pixelStride, rowStride);
+ final int rightLm = getPixelLuminance(buffer, width - 1, y, pixelStride, rowStride);
+ histogram[leftLm]++;
+ histogram[rightLm]++;
}
ir.close();
- // Get "mode" by histogram.
- final int[] histogram = new int[256];
- int maxCount = 0;
- int mostLuma = 0;
- for (int luma : borderLumas) {
- final int count = ++histogram[luma];
- if (count > maxCount) {
- maxCount = count;
- mostLuma = luma;
+ // Find the median from histogram.
+ final int halfNum = (width + height) / sampling;
+ int sum = 0;
+ int medianLuminance = 0;
+ for (i = 0; i < histogram.length; i++) {
+ sum += histogram[i];
+ if (sum >= halfNum) {
+ medianLuminance = i;
+ break;
}
}
- return mostLuma / 255f;
+ return medianLuminance / 255f;
}
/** Returns the luminance of the pixel in 0~255. */
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index b3e1df1..874cc49 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -131,7 +131,8 @@
Runnable cacheUpdater
) {
Producer.init(InitArguments.DEFAULTS);
- mDataSource.register(DataSourceParams.DEFAULTS);
+ mDataSource.register(new DataSourceParams(
+ DataSourceParams.PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_STALL_AND_ABORT));
this.mViewerConfigInputStreamProvider = viewerConfigInputStreamProvider;
this.mViewerConfigReader = viewerConfigReader;
this.mLogGroups = logGroups;
@@ -191,8 +192,6 @@
Log.e(LOG_TAG, "Failed to read ProtoLog viewer config to dump on tracing end", e);
}
});
-
- mDataSource.flush();
}
private static void writeViewerConfigGroup(
diff --git a/core/java/com/android/internal/widget/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java
index 18d5f6d..54b9a22 100644
--- a/core/java/com/android/internal/widget/LockscreenCredential.java
+++ b/core/java/com/android/internal/widget/LockscreenCredential.java
@@ -386,6 +386,11 @@
}
@Override
+ public void finalize() {
+ zeroize();
+ }
+
+ @Override
public int hashCode() {
// Effective Java — Always override hashCode when you override equals
return Objects.hash(mType, Arrays.hashCode(mCredential), mHasInvalidChars);
diff --git a/core/java/com/android/internal/widget/NotificationRowIconView.java b/core/java/com/android/internal/widget/NotificationRowIconView.java
new file mode 100644
index 0000000..4031b2f
--- /dev/null
+++ b/core/java/com/android/internal/widget/NotificationRowIconView.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import android.app.Flags;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RemoteViews;
+
+import androidx.annotation.Nullable;
+
+/**
+ * An image view that holds the icon displayed on the left side of a notification row.
+ */
+@RemoteViews.RemoteView
+public class NotificationRowIconView extends CachingIconView {
+ public NotificationRowIconView(Context context) {
+ super(context);
+ }
+
+ public NotificationRowIconView(Context context,
+ @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public NotificationRowIconView(Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public NotificationRowIconView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ 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();
+ }
+}
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index d31baf3..e3a438d 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -1059,6 +1059,7 @@
optional int32 uid = 1;
repeated .android.app.ApplicationStartInfoProto app_start_info = 2;
+ optional bool monitoring_enabled = 3;
}
repeated User users = 2;
}
diff --git a/core/proto/android/server/vibrator/vibratormanagerservice.proto b/core/proto/android/server/vibrator/vibratormanagerservice.proto
index 9151958..1d9b0db 100644
--- a/core/proto/android/server/vibrator/vibratormanagerservice.proto
+++ b/core/proto/android/server/vibrator/vibratormanagerservice.proto
@@ -116,7 +116,7 @@
reserved 6; // prev int32 status
// Also used by VibrationReported from frameworks/proto_logging/stats/atoms.proto.
- // Next Tag: 26
+ // Next Tag: 29
enum Status {
UNKNOWN = 0;
RUNNING = 1;
@@ -135,7 +135,6 @@
IGNORED_ERROR_TOKEN= 14;
IGNORED_APP_OPS = 15;
IGNORED_BACKGROUND = 16;
- IGNORED_UNKNOWN_VIBRATION = 17;
IGNORED_UNSUPPORTED = 18;
IGNORED_FOR_EXTERNAL = 19;
IGNORED_FOR_HIGHER_IMPORTANCE = 20;
@@ -146,6 +145,8 @@
IGNORED_SUPERSEDED = 25;
IGNORED_FROM_VIRTUAL_DEVICE = 26;
IGNORED_ON_WIRELESS_CHARGER = 27;
+ IGNORED_MISSING_PERMISSION = 28;
+ reserved 17; // prev IGNORED_UNKNOWN_VIBRATION
}
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 567844c..e2106c5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -6200,7 +6200,7 @@
@hide
@removed -->
<permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|role" />
<!-- Allows an application to know what content is playing and control its playback.
<p>Not for use by third-party applications due to privacy of media consumption</p> -->
diff --git a/core/res/OWNERS b/core/res/OWNERS
index 3489cac..a7d1a86 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -33,6 +33,19 @@
# Multiuser
per-file res/xml/config_user_types.xml = file:/MULTIUSER_OWNERS
+# Notifications
+per-file res/*/*notification* = file:/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+# TODO(b/337816136): Move notification values to separate files
+per-file res/values*/attrs.xml = jeffdq@google.com
+per-file res/values*/colors.xml = jeffdq@google.com
+per-file res/values*/dimens.xml = jeffdq@google.com
+per-file res/values*/config.xml = jeffdq@google.com
+per-file res/values/ids.xml = jeffdq@google.com
+per-file res/values/strings.xml = jeffdq@google.com
+per-file res/values/symbols.xml = jeffdq@google.com
+per-file res/values/themes_device_defaults.xml = jeffdq@google.com
+per-file res/values/styles_material.xml = jeffdq@google.com
+
# Battery Saver
per-file res/values/config_battery_saver.xml = file:/services/core/java/com/android/server/power/batterysaver/OWNERS
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 6f06d80..d80b765 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -41,7 +41,7 @@
android:visibility="gone"
/>
- <com.android.internal.widget.CachingIconView
+ <com.android.internal.widget.NotificationRowIconView
android:id="@+id/icon"
android:layout_width="@dimen/notification_icon_circle_size"
android:layout_height="@dimen/notification_icon_circle_size"
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index 64227d8..452df50 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -37,7 +37,7 @@
android:visibility="gone"
/>
- <com.android.internal.widget.CachingIconView
+ <com.android.internal.widget.NotificationRowIconView
android:id="@+id/icon"
android:layout_width="@dimen/notification_icon_circle_size"
android:layout_height="@dimen/notification_icon_circle_size"
diff --git a/core/res/res/layout/notification_template_material_compact_heads_up_base.xml b/core/res/res/layout/notification_template_material_compact_heads_up_base.xml
index 57da898..f38da26 100644
--- a/core/res/res/layout/notification_template_material_compact_heads_up_base.xml
+++ b/core/res/res/layout/notification_template_material_compact_heads_up_base.xml
@@ -23,7 +23,7 @@
android:gravity="center_vertical"
android:theme="@style/Theme.DeviceDefault.Notification"
android:importantForAccessibility="no">
- <com.android.internal.widget.CachingIconView
+ <com.android.internal.widget.NotificationRowIconView
android:id="@+id/icon"
android:layout_width="@dimen/notification_icon_circle_size"
android:layout_height="@dimen/notification_icon_circle_size"
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 8a94c48..6e9d17f 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -38,7 +38,7 @@
android:visibility="gone"
/>
- <com.android.internal.widget.CachingIconView
+ <com.android.internal.widget.NotificationRowIconView
android:id="@+id/icon"
android:layout_width="@dimen/notification_icon_circle_size"
android:layout_height="@dimen/notification_icon_circle_size"
diff --git a/core/res/res/layout/notification_template_material_messaging.xml b/core/res/res/layout/notification_template_material_messaging.xml
index a83d923..1eae41d 100644
--- a/core/res/res/layout/notification_template_material_messaging.xml
+++ b/core/res/res/layout/notification_template_material_messaging.xml
@@ -51,7 +51,7 @@
android:visibility="gone"
/>
- <com.android.internal.widget.CachingIconView
+ <com.android.internal.widget.NotificationRowIconView
android:id="@+id/icon"
android:layout_width="@dimen/notification_icon_circle_size"
android:layout_height="@dimen/notification_icon_circle_size"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 8218ff1..dbf09ee 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -830,7 +830,7 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"Stel wagwoordreëls"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Beheer die lengte en die karakters wat in skermslotwagwoorde en -PIN\'e toegelaat word."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"Monitor pogings om skerm te ontsluit"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Monitor die aantal keer wat \'n verkeerde wagwoorde ingevoer is wanneer die skerm ontsluit word. Sluit die tablet of vee al die data uit as die wagwoord te veel keer verkeerd ingevoer word."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Monitor die aantal keer wat \'n verkeerde wagwoord ingevoer word wanneer die skerm ontsluit word. Sluit die tablet of vee al die data uit as die wagwoord te veel keer verkeerd ingevoer word."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Monitor die aantal verkeerde wagwoorde wat ingetik word wanneer die skerm ontsluit word, en sluit jou Android TV-toestel of vee al jou Android TV-toestel se data uit as te veel verkeerde wagwoorde ingetik word."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Monitor die aantal verkeerde wagwoorde wat ingevoer word wanneer die skerm ontsluit word, en sluit die inligtingvermaakstelsel of vee al die inligtingvermaakstelsel se data uit as te veel verkeerde wagwoorde ingevoer word."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Monitor die aantal keer wat \'n verkeerde wagwoorde ingevoer is wanneer die skerm ontsluit word. Sluit die foon of vee al die data uit as die wagwoord te veel keer verkeerd ingevoer word."</string>
@@ -843,7 +843,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Om die skerm te sluit"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Beheer hoe en wanneer die skerm sluit."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Om alle data uit te vee"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Vee die tablet se data uit sonder waarskuwing, deur \'n fabrieksterugstelling uit te voer."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Vee die tablet se data uit sonder waarskuwing, deur \'n fabriekterugstelling uit te voer."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Vee jou Android TV-toestel se data sonder waarskuwing uit deur \'n fabrieksterugstelling uit te voer."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Vee die inligtingvermaakstelsel se data sonder waarskuwing uit deur \'n fabriekterugstelling te doen."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Vee die foon se data uit sonder waarskuwing, deur \'n fabrieksterugstelling uit te voer."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 5a79197..8a2fb4a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1899,8 +1899,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Traži PIN pre otkačinjanja"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži šablon za otključavanje pre otkačinjanja"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku pre otkačinjanja"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao je administrator.\nIdite u podešavanja da biste videli odobrene dozvole"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je administrator"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Potvrdi"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 0ee66fc..484e6f0 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -2179,7 +2179,7 @@
<string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Obavještenja"</string>
<string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Brze postavke"</string>
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dijaloški okvir za napajanje"</string>
- <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključavanje ekrana"</string>
+ <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključani ekran"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimak ekrana"</string>
<string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Kuka za slušalice"</string>
<string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Prečica za pristupačnost na ekranu"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 48ebcad..aafbb39 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -831,14 +831,14 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"Definir les normes de contrasenya"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Permet controlar la longitud i el nombre de caràcters permesos a les contrasenyes i als PIN del bloqueig de pantalla."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"Supervisar els intents de desbloqueig de la pantalla"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja la tauleta o n\'esborra totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
- <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Fa un seguiment del nombre de contrasenyes incorrectes que s\'han introduït en intentar desbloquejar la pantalla i bloqueja el dispositiu Android TV o esborra totes les dades del dispositiu si s\'introdueixen massa contrasenyes incorrectes."</string>
- <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Supervisa el nombre de contrasenyes incorrectes introduïdes en desbloquejar la pantalla, i bloqueja el sistema d\'informació i entreteniment o n\'esborra totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
- <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Supervisa el nombre de contrasenyes incorrectes introduïdes en desbloquejar la pantalla, i bloqueja el telèfon o esborra totes les dades del telèfon si s\'introdueixen massa contrasenyes incorrectes."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Fa un seguiment del nombre de contrasenyes incorrectes que s\'han escrit en intentar desbloquejar la pantalla i bloqueja la tauleta o n\'esborra totes les dades de l\'usuari si s\'escriuen massa contrasenyes incorrectes."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Fa un seguiment del nombre de contrasenyes incorrectes que s\'han introduït en intentar desbloquejar la pantalla i bloqueja el dispositiu Android TV o n\'esborra totes les dades de l\'usuari si s\'introdueixen massa contrasenyes incorrectes."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Supervisa el nombre de contrasenyes incorrectes introduïdes en desbloquejar la pantalla, i bloqueja el sistema d\'informació i entreteniment o esborra totes les dades d\'aquest perfil si s\'introdueixen massa contrasenyes incorrectes."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Fa un seguiment del nombre de contrasenyes incorrectes que s\'han escrit en intentar desbloquejar la pantalla i bloqueja el telèfon o n\'esborra totes les dades de l\'usuari si s\'escriuen massa contrasenyes incorrectes."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja la tauleta o esborra\'n totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
+ <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el dispositiu Android TV o esborra\'n totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
+ <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el sistema d\'informació i entreteniment o esborra\'n totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el telèfon o esborra\'n totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja la tauleta o esborra totes les dades d\'aquest usuari si s\'introdueixen massa contrasenyes incorrectes."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el dispositiu Android TV o esborra totes les dades d\'aquest usuari si s\'introdueixen massa contrasenyes incorrectes."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el sistema d\'informació i entreteniment o esborra totes les dades d\'aquest perfil si s\'introdueixen massa contrasenyes incorrectes."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el telèfon o esborra totes les dades d\'aquest usuari si s\'introdueixen massa contrasenyes incorrectes."</string>
<string name="policylab_resetPassword" msgid="214556238645096520">"Canviar el bloqueig de pantalla"</string>
<string name="policydesc_resetPassword" msgid="4626419138439341851">"Canvia el bloqueig de pantalla."</string>
<string name="policylab_forceLock" msgid="7360335502968476434">"Bloquejar la pantalla"</string>
@@ -1899,8 +1899,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Sol·licita el PIN per deixar de fixar"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sol·licita el patró de desbloqueig per deixar de fixar"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demana la contrasenya per deixar de fixar"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"Instal·lat per l\'administrador.\nVes a la configuració per veure els permisos concedits."</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Actualitzat per l\'administrador"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Suprimit per l\'administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"D\'acord"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index fef6fa6..f7b903f 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -832,7 +832,7 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"Nastavit pravidla pro heslo"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Ovládání délky a znaků povolených v heslech a kódech PIN zámku obrazovky."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"Sledovat pokusy o odemknutí obrazovky"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Sledovat počet nesprávných hesel zadaných při odemykání obrazovky a uzamknout tablet nebo vymazat z tabletu všechna data, pokud bylo zadáno příliš mnoho nesprávných hesel."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Monitoruje se počet nesprávných hesel zadaných při odemykání obrazovky, a pokud bylo zadáno příliš mnoho nesprávných hesel, tablet se uzamkne nebo se z něj vymažou všechna data."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Sledovat počet nesprávných hesel zadaných při odemykání obrazovky, a pokud jich bude zadáno příliš mnoho, uzamknout zařízení Android TV nebo z něj vymazat všechna data."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Monitorovat počet nesprávných hesel zadaných při odemykání obrazovky a uzamknout informační a zábavní systém nebo vymazat veškerá data v informačním a zábavním systému, pokud je zadáno příliš mnoho nesprávných hesel."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Sleduje počet nesprávných hesel zadaných při odemykání obrazovky a uzamkne telefon nebo vymaže z telefonu všechna data, pokud bylo zadáno příliš mnoho nesprávných hesel."</string>
@@ -845,7 +845,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Uzamknout obrazovku"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Určíte, jak a kdy se obrazovka uzamkne."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Mazat všechna data"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Bez upozornění smazat všechna data tabletu obnovením továrních dat."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Bez upozornění se smažou všechna data tabletu obnovením továrních dat."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Provést obnovení továrních dat a bez upozornění tím vymazat data v zařízení Android TV."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Bez upozornění se smažou všechna data informačního a zábavního systému obnovením továrních dat."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Bez upozornění se smažou všechna data telefonu obnovením továrních dat."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index ae1da16..0122a2c 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -830,7 +830,7 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"Passwortregeln festlegen"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Zulässige Länge und Zeichen für Passwörter für die Displaysperre festlegen"</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"Versuche zum Entsperren des Displays überwachen"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Displays überwachen und Tablet sperren oder alle Daten auf dem Tablet löschen, wenn zu häufig ein falsches Passwort eingegeben wird."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Displays überwachen und Tablet sperren oder alle Daten auf dem Tablet löschen, wenn zu häufig ein falsches Passwort eingegeben wird"</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Es wird überwacht, wie oft beim Versuch, den Bildschirm zu entsperren, ein falsches Passwort eingegeben wird. Wenn es zu viele Fehlversuche gibt, wird das Android TV-Gerät gesperrt oder alle Daten darauf werden gelöscht."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Displays erfassen und Infotainmentsystem sperren oder alle Daten des Infotainmentsystems löschen, wenn zu häufig ein falsches Passwort eingegeben wird."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Bildschirms überwachen und Telefon sperren oder alle Daten auf dem Telefon löschen, wenn zu häufig ein falsches Passwort eingegeben wird."</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 71b5903..15ac935 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -356,8 +356,7 @@
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
<string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for dream_accessibility_action_click (7392398629967797805) -->
- <skip />
+ <string name="dream_accessibility_action_click" msgid="7392398629967797805">"dismiss"</string>
<string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
<string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
<string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 25d6c18..78e4f32 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -356,8 +356,7 @@
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
<string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for dream_accessibility_action_click (7392398629967797805) -->
- <skip />
+ <string name="dream_accessibility_action_click" msgid="7392398629967797805">"dismiss"</string>
<string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
<string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
<string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 953bfbd..d524aac 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -844,7 +844,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Bloquear la pantalla"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Controla cómo y cuándo se bloquea la pantalla."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Borrar todos los datos"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Eliminar los datos de la tablet sin avisar y restablecer la configuración de fábrica"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Borra los datos de la tablet sin avisar y restablece la configuración de fábrica."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Restablece la configuración de fábrica para borrar los datos del dispositivo Android TV sin previo aviso."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Permite borrar los datos del sistema de infoentretenimiento sin previo aviso mediante el restablecimiento de la configuración de fábrica."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Borra los datos del dispositivo sin avisar y restablece la configuración de fábrica."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index ba2c5e5..5f48741 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -831,7 +831,7 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"Establecimiento de reglas de contraseña"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Controla la longitud y los caracteres permitidos en los PIN y en las contraseñas de bloqueo de pantalla."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"Supervisar los intentos de desbloqueo de pantalla"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla y bloquea el tablet o elimina todos sus datos si se introducen demasiadas contraseñas incorrectas."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla y bloquea la tablet o elimina todos sus datos si se introducen demasiadas contraseñas incorrectas."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Comprueba cuántas veces se han introducido contraseñas incorrectas para desbloquear la pantalla y, si te parece que han sido demasiadas, bloquea tu dispositivo Android TV o borra todos sus datos."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla y bloquea el sistema de infoentretenimiento o borra todos sus datos si se introducen demasiadas contraseñas incorrectas."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla y bloquea el teléfono o elimina todos sus datos si se introducen demasiadas contraseñas incorrectas."</string>
@@ -844,7 +844,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Bloquear la pantalla"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Controla cómo y cuándo se bloquea la pantalla"</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Borrar todos los datos"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Borrar los datos del tablet sin avisar restableciendo el estado de fábrica"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Borra los datos de la tablet sin avisar restableciendo el estado de fábrica"</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Restablece los datos de fábrica de tu dispositivo Android TV, eliminando sin previo aviso los datos que tuviera."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Borra los datos del sistema de infoentretenimiento sin avisar restableciendo el estado de fábrica."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Borra los datos del teléfono sin avisar restableciendo el estado de fábrica"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index b100016..1e50e92 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -843,7 +843,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Ekraani lukustamine"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Määrake, kuidas ja millal ekraan lukustub."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Kõikide andmete kustutamine"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Kustutage tahvelarvuti andmed hoiatamata, lähtestades arvuti tehaseandmetele."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Kustutab tahvelarvuti andmed hoiatamata, lähtestades arvuti tehaseandmetele."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Kustutatakse teie Android TV seadme andmed ilma hoiatamata, lähtestades seadme tehase andmetele."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Teabe ja meelelahutuse süsteemi andmete hoiatamata kustutamine tehase andmetele lähtestamise abil."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Kustutab telefoniandmed hoiatuseta, lähtestades telefoni tehaseseadetele."</string>
@@ -1898,8 +1898,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Enne vabastamist küsi PIN-koodi"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Enne vabastamist küsi avamismustrit"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Enne vabastamist küsi parooli"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"Installis teie administraator.\nAntud õiguste vaatamiseks avage seaded"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Administraator on seda värskendanud"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administraator on selle kustutanud"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index aa87f24..2a21478 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1898,8 +1898,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pyydä PIN ennen irrotusta"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pyydä salasana ennen irrotusta"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"Järjestelmänvalvojan asentama.\nTarkista myönnetyt luvat asetuksista."</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Järjestelmänvalvoja päivitti tämän."</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Järjestelmänvalvoja poisti tämän."</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f94ebac..a3d71d9 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1899,8 +1899,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Demander le code avant de retirer l\'épingle"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant de retirer l\'épingle"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant de retirer l\'épingle"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"Installé par votre administrateur.\nAllez dans les paramètres pour consulter les autorisations accordées."</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Mis à jour par votre administrateur"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f393074..9eb691f 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1898,8 +1898,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन करने से पहले पिन के लिए पूछें"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करने से पहले लॉक खोलने के पैटर्न के लिए पूछें"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"इसे आपके एडमिन ने इंस्टॉल किया है.\nजिन अनुमतियों को मंज़ूरी मिली है उन्हें देखने के लिए, सेटिंग में जाएं"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"आपके व्यवस्थापक ने अपडेट किया है"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"आपके व्यवस्थापक ने हटा दिया है"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ठीक है"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 33cde13..84598ed 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -831,7 +831,7 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"Postavi pravila zaporke"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Upravlja duljinom i znakovima koji su dopušteni u zaporkama i PIN-ovima zaključavanja zaslona."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"Nadzor pokušaja otključavanja zaslona"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Nadziri broj netočnih zaporki unesenih pri otključavanju zaslona i zaključaj tabletno računalo ili izbriši sve podatke na njemu ako je uneseno previše netočnih zaporki."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Nadzire se broj netočnih zaporki unesenih pri otključavanju zaslona, a tablet se zaključava ili se s njega brišu svi podaci ako je uneseno previše netočnih zaporki."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Prati broj netočnih zaporki unesenih prilikom otključavanja zaslona i zaključava Android TV uređaj ili s njega briše sve podatke ako se unese previše netočnih zaporki."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Prati broj netočnih zaporki unesenih prilikom otključavanja zaslona i zaključava sustav za informiranje i zabavu ili briše sve njegove podatke ako se unese previše netočnih zaporki."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Nadzire broj netočno unesenih zaporki pri otključavanju zaslona i zaključava telefon ili briše sve podatke na telefonu ako je uneseno previše netočnih zaporki."</string>
@@ -844,7 +844,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Zaključavanje zaslona"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Upravlja se načinom i vremenom zaključavanja zaslona."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Brisanje svih podataka"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Vraćanjem u tvorničko stanje izbriši podatke tabletnog računala bez upozorenja."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Vraćanjem na tvorničke postavke brišu se podaci tableta bez upozorenja."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Podatke Android TV uređaja izbrišite bez upozorenja vraćanjem uređaja na tvorničke postavke."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Briše podatke sustava za informiranje i zabavu bez upozorenja vraćanjem na tvorničko stanje."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Vraćanjem na tvorničke postavke brišu se podaci s telefona bez upozorenja."</string>
@@ -1537,7 +1537,7 @@
<string name="vpn_lockdown_config" msgid="8331697329868252169">"Promijenite mrežu ili postavke VPN-a"</string>
<string name="upload_file" msgid="8651942222301634271">"Odaberite datoteku"</string>
<string name="no_file_chosen" msgid="4146295695162318057">"Nema odabranih datoteka"</string>
- <string name="reset" msgid="3865826612628171429">"Ponovo postavi"</string>
+ <string name="reset" msgid="3865826612628171429">"Poništi"</string>
<string name="submit" msgid="862795280643405865">"Pošalji"</string>
<string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Pokrenuta je aplikacija za vožnju"</string>
<string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Dodirnite za zatvaranje aplikacije za vožnju."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index acf2266..d688035 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1898,8 +1898,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"PIN-kód kérése a kitűzés feloldásához"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Feloldási minta kérése a kitűzés feloldásához"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Jelszó kérése a rögzítés feloldásához"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"A rendszergazda által telepítve.\nLépjen a beállításokhoz a megadott engedélyek megtekintéséhez."</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"A rendszergazda által frissítve"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"A rendszergazda által törölve"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index b304edc..2692d06 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1898,8 +1898,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Biðja um PIN-númer til að losa"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Biðja um opnunarmynstur til að losa"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Biðja um aðgangsorð til að losa"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"Sett upp af stjórnanda.\nFarðu í stillingar til að sjá heimildir"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Kerfisstjóri uppfærði"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Kerfisstjóri eyddi"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Í lagi"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 00b79b6..2cc0590 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -844,7 +844,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"Bloccare lo schermo"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"Controlla come e quando si blocca lo schermo."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"Cancellare tutti i dati"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Cancella i dati del tablet senza preavviso eseguendo un ripristino dati di fabbrica."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Cancella i dati del tablet senza preavviso eseguendo un ripristino dei dati di fabbrica."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Consente di cancellare i dati del dispositivo Android TV senza preavviso eseguendo un ripristino dei dati di fabbrica."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Cancella i dati del sistema di infotainment senza preavviso eseguendo un ripristino dei dati di fabbrica."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Cancella i dati del telefono senza preavviso eseguendo un ripristino dei dati di fabbrica."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 5f6cd38..2ef91cd 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -843,7 +843,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"ចាក់សោអេក្រង់"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"គ្រប់គ្រងវិធី និងពេលវេលាចាក់សោអេក្រង់។"</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"លុបទិន្នន័យទាំងអស់"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"លុបទិន្នន័យកុំព្យូទ័របន្ទះដោយមិនព្រមានដោយអនុវត្តការកំណត់ទិន្នន័យដូចចេញពីរោងចក្រ។"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"លុបទិន្នន័យថេប្លេតដោយគ្មានការព្រមានដោយធ្វើការកំណត់ទិន្នន័យដូចចេញពីរោងចក្រ។"</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"លុបទិន្នន័យឧបករណ៍ Android TV របស់អ្នកដោយមិនមានការព្រមាន ដោយធ្វើការកំណត់ទិន្នន័យដូចចេញពីរោងចក្រ។"</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"លុបទិន្នន័យរបស់ប្រព័ន្ធព័ត៌មាន និងកម្សាន្តដោយមិនមានការព្រមាន ដោយធ្វើការកំណត់ទិន្នន័យដូចចេញពីរោងចក្រ។"</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"លុបទិន្នន័យទូរសព្ទដោយមិនមានការព្រមានជាមុន ដោយអនុវត្តការកំណត់ទិន្នន័យដូចចេញពីរោងចក្រ ។"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index ec92812..0d48bbb 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -830,7 +830,7 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"ಪಾಸ್ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"ಪರದೆ ಲಾಕ್ನಲ್ಲಿನ ಪಾಸ್ವರ್ಡ್ಗಳು ಮತ್ತು ಪಿನ್ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"ಪರದೆಯ ಅನ್ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ಪರದೆಯನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ ಪಾಸ್ವರ್ಡ್ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ, ಮತ್ತು ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಲಾಕ್ ಮಾಡಿ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಟೈಪ್ ಮಾಡಿದ್ದರೆ ಟ್ಯಾಬ್ಲೆಟ್ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ಸ್ಕ್ರೀನ್ ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ ಪಾಸ್ವರ್ಡ್ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ, ಮತ್ತು ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಟೈಪ್ ಮಾಡಿದ್ದರೆ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಲಾಕ್ ಮಾಡಿ ಅಥವಾ ಟ್ಯಾಬ್ಲೆಟ್ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"ಪರದೆಯನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ ಪಾಸ್ವರ್ಡ್ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಲಾಕ್ ಮಾಡುತ್ತದೆ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಟೈಪ್ ಮಾಡಿದರೆ ನಿಮ್ಮ ಎಲ್ಲಾ Android TV ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ ಪಾಸ್ವರ್ಡ್ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ ಮತ್ತು ಇನ್ಫೋಟೈನ್ಮೆಂಟ್ ಸಿಸ್ಟಂ ಅನ್ನು ಲಾಕ್ ಮಾಡಿ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಟೈಪ್ ಮಾಡಿದ್ದರೆ ಇನ್ಫೋಟೈನ್ಮೆಂಟ್ ಸಿಸ್ಟಂನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿ."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"ಪರದೆಯನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಿದಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ ಪಾಸ್ವರ್ಡ್ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ, ಮತ್ತು ಫೋನ್ ಅನ್ನು ಲಾಕ್ ಮಾಡಿ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಟೈಪ್ ಮಾಡಿದ್ದರೆ ಫೋನ್ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
@@ -1898,8 +1898,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ಅನ್ಪಿನ್ ಮಾಡಲು ಪಿನ್ ಕೇಳು"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ಅನ್ಪಿನ್ ಮಾಡಲು ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಕೇಳಿ"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ಅನ್ಪಿನ್ ಮಾಡಲು ಪಾಸ್ವರ್ಡ್ ಕೇಳು"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿದ್ದಾರೆ.\nನೀಡಲಾದ ಅನುಮತಿಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಅಪ್ಡೇಟ್ ಮಾಡಲ್ಪಟ್ಟಿದೆ"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅಳಿಸಿದ್ದಾರೆ"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"ಸರಿ"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 12adb17..1ffde6f 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -830,7 +830,7 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"ຄວບຄຸມຄວາມຍາວ ແລະຕົວອັກສອນທີ່ອະນຸຍາດໃຫ້ຢູ່ໃນລະຫັດລັອກໜ້າຈໍ ແລະ PIN."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ຕິດຕາມເບິ່ງຈຳນວນການພິມລະຫັດຜ່ານທີ່ບໍ່ຖືກຕ້ອງ ໃນເວລາປົດລັອກໜ້າຈໍ ແລະລັອກແທັບເລັດ ຫຼືລຶບຂໍ້ມູນທັງໝົດຂອງແທັບເລັດ ຖ້າມີການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງຫຼາຍເທື່ອເກີນໄປ."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ຕິດຕາມເບິ່ງຈຳນວນການພິມລະຫັດຜ່ານທີ່ບໍ່ຖືກຕ້ອງ ໃນເວລາປົດລັອກໜ້າຈໍ ແລະ ລັອກແທັບເລັດ ຫຼື ລຶບຂໍ້ມູນທັງໝົດຂອງແທັບເລັດ ຖ້າມີການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງຫຼາຍເທື່ອເກີນໄປ."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"ຕິດຕາມຈຳນວນລະຫັດຜ່ານທີ່ບໍ່ຖືກຕ້ອງທີ່ພິມຕອນກຳລັງປົດລັອກໜ້າຈໍ ແລະ ລັອກອຸປະກອນ Android TV ຂອງທ່ານ ຫຼື ລຶບຂໍ້ມູນຂອງອຸປະກອນ Android TV ຂອງທ່ານຫາກພິມລະຫັດຜ່ານຜິດຫຼາຍເທື່ອເກີນໄປ."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"ຕິດຕາມຈຳນວນການພິມລະຫັດຜ່ານທີ່ບໍ່ຖືກຕ້ອງໃນເວລາປົດລັອກໜ້າຈໍ ແລະ ລັອກລະບົບສາລະບັນເທີງ ຫຼື ລຶບຂໍ້ມູນຂອງລະບົບສາລະບັນເທີງທັງໝົດຫາກມີການພິມລະຫັດຜ່ານທີ່ບໍ່ຖືກຕ້ອງຫຼາຍເກີນໄປ."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"ຕິດຕາມເບິ່ງຈຳນວນການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ ໃນເວລາປົດລັອກໜ້າຈໍ ແລະລັອກໂທລະສັບ ຫຼືລຶບຂໍ້ມູນທັງໝົດຂອງໂປລະສັບ ຖ້າມີການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງຫຼາຍເທື່ອເກີນໄປ."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 230e701..30e4eca 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -830,14 +830,14 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"स्क्रिन लक पासवर्ड र PIN हरूमा अनुमति दिइएको लम्बाइ र वर्णहरूको नियन्त्रण गर्नुहोस्।"</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"स्क्रिन अनलक गर्न गरिएको प्रयासको अनुगमन गर्ने"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप भएको संख्या निरीक्षण गर्नुहोस् र यदि निकै धेरै गलत पासवर्डहरू टाइप भएका छन भने ट्याब्लेट लक गर्नुहोस् वा ट्याब्लेटका सबै डेटा मेट्नुहोस्।"</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुराको रेकर्ड राख्नुहोस् र धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा ट्याबलेट लक गर्नुहोस् वा यसका सबै डेटा मेटाउनुहोस्।"</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप गरेको सङ्ख्या निरीक्षण गर्नुहोस्, र धेरै पटक गलत पासवर्डहरू टाइप गरिएको खण्डमा आफ्नो Android टिभी यन्त्र लक गर्नुहोस् वा डिभाइसमा भएको सम्पूर्ण डेटा मेटाउनुहोस्।"</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुरा निगरानी गर्नुहोस् र अत्यन्तै धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा यो इन्फोटेनमेन्ट प्रणाली लक गर्नुहोस् वा यस इन्फोटेनमेन्ट प्रणालीका सबै डेटा मेटाउनुहोस्।"</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप भएको छ हेर्नुहोस् र निकै धेरै पटक गलत पासवर्ड टाइप भएको भने फोन लक गर्नुहोस् वा फोनका सबै डेटा मेट्नुहोस्।"</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप संख्या अनुगमन गर्नुहोस्, र यदि निकै धेरै गलत पासवर्डहरू टाइप गरिएमा ट्याब्लेट लक गर्नुहोस् वा प्रयोगकर्ताको डेटा मेटाउनुहोस्।"</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुराको रेकर्ड राख्नुहोस् र धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा ट्याबलेट लक गर्नुहोस् वा प्रयोगकर्ताका सबै डेटा मेटाउनुहोस्।"</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप गरेको सङ्ख्या निरीक्षण गर्नुहोस्, र धेरै पटक गलत पासवर्डहरू टाइप गरिएको खण्डमा आफ्नो Android टिभी यन्त्र लक गर्नुहोस् वा यो प्रयोगकर्ताको सम्पूर्ण डेटा मेटाउनुहोस्।"</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुरा निगरानी गर्नुहोस् र अत्यन्तै धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा यो इन्फोटेनमेन्ट प्रणाली लक गर्नुहोस् वा यस प्रोफाइलका सबै डेटा मेटाउनुहोस्।"</string>
- <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप संख्या अनुगमन गर्नुहोस्, र यदि निकै धेरै गलत पासवर्डहरू टाइप गरिएमा फोन लक गर्नुहोस् वा प्रयोगकर्ताको डेटा मेटाउनुहोस्।"</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुराको रेकर्ड राख्नुहोस् र धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा फोन लक गर्नुहोस् वा प्रयोगकर्ताका सबै डेटा मेटाउनुहोस्।"</string>
<string name="policylab_resetPassword" msgid="214556238645096520">"स्क्रिन लक परिवर्तन गर्ने"</string>
<string name="policydesc_resetPassword" msgid="4626419138439341851">"स्क्रिन लक परिवर्तन गर्नुहोस्।"</string>
<string name="policylab_forceLock" msgid="7360335502968476434">"स्क्रिन लक गर्ने"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 5de3287..f59d2ae 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -356,8 +356,7 @@
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Screenshot maken"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan een screenshot van het scherm maken."</string>
<string name="dream_preview_title" msgid="5570751491996100804">"Voorbeeld, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for dream_accessibility_action_click (7392398629967797805) -->
- <skip />
+ <string name="dream_accessibility_action_click" msgid="7392398629967797805">"sluiten"</string>
<string name="permlab_statusBar" msgid="8798267849526214017">"statusbalk uitzetten of wijzigen"</string>
<string name="permdesc_statusBar" msgid="5809162768651019642">"Hiermee kan de app de statusbalk uitzetten of systeemiconen toevoegen en verwijderen."</string>
<string name="permlab_statusBarService" msgid="2523421018081437981">"de statusbalk zijn"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 6f186ff..9c41d73 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -830,7 +830,7 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"ପାସ୍ୱର୍ଡ ନିୟମାବଳୀ ସେଟ୍ କରନ୍ତୁ"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"ଲକ୍ ସ୍କ୍ରୀନ୍ ପାସ୍ୱର୍ଡ ଓ PINରେ ଅନୁମୋଦିତ ଦୀର୍ଘତା ଓ ବର୍ଣ୍ଣ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ।"</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"ସ୍କ୍ରିନ-ଅନଲକ କରିବା ଉଦ୍ୟମ ନୀରିକ୍ଷଣ କରିବା"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ସ୍କ୍ରୀନ୍ ଅନଲକ୍ କରିବାବେଳେ ଟାଇପ୍ କରିଥିବା ଭୁଲ ପାସୱର୍ଡର ସଂଖ୍ୟାକୁ ନୀରିକ୍ଷଣ କରେ ଏବଂ ଟାବଲେଟ୍କୁ ଲକ୍ କରିଦିଏ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସୱର୍ଡ ଟାଇପ୍ କରାଯାଇଥାଏ, ତେବେ ଟାବଲେଟ୍ର ସମସ୍ତ ଡାଟା ଲିଭାଇଦିଏ।"</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ସ୍କ୍ରିନ ଅନଲକ କରିବା ସମୟରେ ଟାଇପ ହୋଇଥିବା ଭୁଲ ପାସୱାର୍ଡ ସଂଖ୍ୟା ମନିଟର କରେ ଏବଂ ଟାବଲେଟକୁ ଲକ କରିଦିଏ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସୱର୍ଡ ଟାଇପ କରାଯାଇଥାଏ, ତେବେ ଟାବଲେଟର ସବୁ ଡାଟା ଖାଲି ହୋଇଯାଏ।"</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"ସ୍କ୍ରିନ୍ ଅନ୍ଲକ୍ କରିବା ସମୟରେ ଟାଇପ୍ କରାଯାଇଥିବା ଭୁଲ ପାସ୍ୱାର୍ଡଗୁଡ଼ିକର ସଂଖ୍ୟାକୁ ନିରୀକ୍ଷଣ କରନ୍ତୁ ଏବଂ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍କୁ ଲକ୍ କରନ୍ତୁ କିମ୍ବା ଯଦି ଅନେକ ଭୁଲ ପାସ୍ୱାର୍ଡ ଟାଇପ୍ କରାଯାଇଥାଏ, ତେବେ ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍ର ସମସ୍ତ ଡାଟା ଲିଭାଇ ଦିଅନ୍ତୁ।"</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"ସ୍କ୍ରିନ ଅନଲକ କରିବା ସମୟରେ ଟାଇପ କରାଯାଇଥିବା ଭୁଲ ପାସୱାର୍ଡର ସଂଖ୍ୟାକୁ ମନିଟର କରନ୍ତୁ ଏବଂ ଇନଫୋଟେନମେଣ୍ଟ ସିଷ୍ଟମକୁ ଲକ କରନ୍ତୁ କିମ୍ବା ଯଦି ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପାସୱାର୍ଡ ଟାଇପ କରାଯାଇଥାଏ ତେବେ ଇନଫୋଟେନମେଣ୍ଟ ସିଷ୍ଟମର ସମସ୍ତ ଡାଟା ଖାଲି କରନ୍ତୁ।"</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"ଫୋନ ଅନଲକ କରିବା ବେଳେ ଟାଇପ କରାଯାଇଥିବା ଭୁଲ ପାସୱାର୍ଡର ସଂଖ୍ୟାକୁ ନୀରିକ୍ଷଣ କରିବା ଏବଂ ଯଦି ଏକାଧିକ ଥର ଭୁଲ ପାସୱାର୍ଡ ଟାଇପ କରାଯାଇଥାଏ ତେବେ ଫୋନକୁ ଲକ କରିବା ବା ଫୋନର ସମସ୍ତ ଡାଟା ଇରେଜ କରିବା।"</string>
@@ -843,7 +843,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"ସ୍କ୍ରିନ୍ ଲକ୍ କରିବା"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"ସ୍କ୍ରିନ୍ କିପରି ଓ କେତେବେଳେ ଲକ୍ କରାଯିବ, ତାହା ନିୟନ୍ତ୍ରଣ କରେ।"</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"ସମସ୍ତ ଡାଟା ଖାଲି କରିବା"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ବିନା ଚେତାବନୀରେ ଫ୍ୟାକ୍ଟୋରୀ ସେଟିଙ୍ଗ କରାଇ ଟାବ୍ଲେଟ୍ର ଡାଟା ଲିଭାଇଥାଏ।"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ଫେକ୍ଟୋରୀ ଡାଟା ରିସେଟ କରି ବିନା ଚେତାବନୀରେ ଟାବଲେଟର ଡାଟା ଖାଲି କରନ୍ତୁ।"</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"ଏକ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ୍ କରି ବିନା ଚେତାବନୀରେ ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ର ଡାଟା ଲିଭାନ୍ତୁ।"</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"ଏକ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ କରି ବିନା ଚେତାବନୀରେ ଇନଫୋଟେନମେଣ୍ଟ ସିଷ୍ଟମର ଡାଟା ଖାଲି କରନ୍ତୁ।"</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ବିନା ଚେତାବନୀରେ ଫେକ୍ଟୋରୀ ଡାଟା ରିସେଟ କରି ଫୋନର ଡାଟା ଇରେଜ କରିବା।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index a6937d2..ab40341 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -832,7 +832,7 @@
<string name="policylab_limitPassword" msgid="4851829918814422199">"Określ reguły hasła"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontrolowanie długości haseł blokady ekranu i kodów PIN oraz dozwolonych w nich znaków."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"Monitorowanie prób odblokowania ekranu"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Przy odblokowywaniu ekranu monitoruj, ile razy wpisano nieprawidłowe hasło i blokuj tablet lub usuń z niego wszystkie dane, jeśli nieprawidłowe hasło podano zbyt wiele razy."</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Przy odblokowywaniu ekranu monitoruje, ile razy wpisano nieprawidłowe hasło i blokuje tablet lub usuwa z niego wszystkie dane, jeśli nieprawidłowe hasło podano zbyt wiele razy"</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Monitorowanie liczby nieudanych prób odblokowania ekranu za pomocą hasła oraz blokowanie urządzenia z Androidem TV lub kasowanie z niego wszystkich danych w razie wpisania błędnego hasła zbyt wiele razy."</string>
<string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Monitorowanie przypadków nieprawidłowego wpisania hasła podczas odblokowywania ekranu i blokowanie systemu multimedialno-rozrywkowego lub usuwanie z niego wszystkich danych przy zbyt dużej liczbie błędnych prób."</string>
<string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Przy odblokowywaniu ekranu monitoruje, ile razy wpisano nieprawidłowe hasło, i blokuje telefon lub usuwa z niego wszystkie dane, jeśli nieprawidłowe hasło podano zbyt wiele razy."</string>
@@ -1267,7 +1267,7 @@
<string name="screen_compat_mode_scale" msgid="8627359598437527726">"Skala"</string>
<string name="screen_compat_mode_show" msgid="5080361367584709857">"Zawsze pokazuj"</string>
<string name="screen_compat_mode_hint" msgid="4032272159093750908">"Włącz ponownie, wybierając Ustawienia systemu > Aplikacje > Pobrane."</string>
- <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje obecnie ustawionego rozmiaru wyświetlacza i może działać niestabilnie."</string>
+ <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje obecnie ustawionego rozmiaru wyświetlanych elementów i może działać niestabilnie."</string>
<string name="unsupported_display_size_show" msgid="980129850974919375">"Zawsze pokazuj"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> została skompilowana pod niezgodną wersję systemu Android i może zachowywać się niezgodnie z oczekiwaniami. Sprawdź, czy jest dostępna zaktualizowana wersja aplikacji."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Zawsze pokazuj"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 4772ff8..4d61bdd 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -357,8 +357,7 @@
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer captura de ecrã"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"É possível tirar uma captura de ecrã."</string>
<string name="dream_preview_title" msgid="5570751491996100804">"Pré-visualização, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for dream_accessibility_action_click (7392398629967797805) -->
- <skip />
+ <string name="dream_accessibility_action_click" msgid="7392398629967797805">"ignorar"</string>
<string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar barra de estado"</string>
<string name="permdesc_statusBar" msgid="5809162768651019642">"Permite à app desativar a barra de estado ou adicionar e remover ícones do sistema."</string>
<string name="permlab_statusBarService" msgid="2523421018081437981">"ser apresentada na barra de estado"</string>
@@ -838,7 +837,7 @@
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Monitorizar o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã e bloquear o tablet ou apagar todos os dados deste utilizador se forem introduzidas demasiadas palavras-passe incorretas."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Monitorizar o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã e bloquear o dispositivo Android TV ou apagar todos os dados deste utilizador se forem introduzidas demasiadas palavras-passe incorretas."</string>
<string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Monitorize o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã e bloqueie o sistema de infoentretenimento ou apague todos os dados deste utilizador, se forem introduzidas demasiadas palavras-passe incorretas."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Monitorizar o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã e bloquear o telemóvel ou apagar todos os dados deste utilizador se forem introduzidas demasiadas palavras-passe incorretas."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Monitorizar o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã, e bloquear o telemóvel ou apagar todos os dados deste utilizador se forem introduzidas demasiadas palavras-passe incorretas."</string>
<string name="policylab_resetPassword" msgid="214556238645096520">"Alterar o bloqueio de ecrã"</string>
<string name="policydesc_resetPassword" msgid="4626419138439341851">"Altera o bloqueio de ecrã."</string>
<string name="policylab_forceLock" msgid="7360335502968476434">"Bloquear o ecrã"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 6768e29..569eb35 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1899,8 +1899,7 @@
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Тражи PIN пре откачињања"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Тражи шаблон за откључавање пре откачињања"</string>
<string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тражи лозинку пре откачињања"</string>
- <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
- <skip />
+ <string name="package_installed_device_owner" msgid="8684974629306529138">"Инсталирао је администратор.\nИдите у подешавања да бисте видели одобрене дозволе"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирао је администратор"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Избрисао је администратор"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Потврди"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 1c65e61..eb1e453 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -843,7 +843,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"திரையைப் பூட்டுதல்"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"திரை எப்படி, எப்போது பூட்டப்படுகிறது என்பதைக் கட்டுப்படுத்தலாம்."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"எல்லா டேட்டாவையும் அழித்தல்"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ஆரம்பநிலைத் தரவு மீட்டமைப்பின் மூலம் எச்சரிக்கை வழங்காமல் டேப்லெட்டின் தரவை அழிக்கலாம்."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ஆரம்பநிலைத் தரவு மீட்டமைப்பின் மூலம் எச்சரிக்கை வழங்காமல் டேப்லெட்டின் தரவை அழிக்கும்."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"தரவின் ஆரம்பநிலைக்கு மீட்டமைப்பதன் மூலம் எச்சரிக்கை செய்யாமல் Android TVயின் தரவை அழிக்கும்."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"தரவின் ஆரம்பநிலை மீட்டமைப்பைச் செயல்படுத்துவதன் மூலம் எச்சரிக்கை எதுவுமின்றி இன்ஃபோடெயின்மென்ட் சிஸ்டமின் தரவை அழிக்கும்."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ஆரம்பநிலைத் தரவு மீட்டமைப்பின் மூலம் எச்சரிக்கை வழங்காமல் மொபைலின் தரவை அழிக்கலாம்."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 423cf88..3c82307 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -843,7 +843,7 @@
<string name="policylab_forceLock" msgid="7360335502968476434">"స్క్రీన్ను లాక్ చేయడానికి"</string>
<string name="policydesc_forceLock" msgid="1008844760853899693">"స్క్రీన్ను ఎలా మరియు ఎప్పుడు లాక్ చేయాలనే దాన్ని నియంత్రిస్తుంది."</string>
<string name="policylab_wipeData" msgid="1359485247727537311">"మొత్తం డేటాను ఎరేజ్ చేయడానికి"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"ఫ్యాక్టరీ డేటా రీసెట్ను అమలు చేయడం ద్వారా హెచ్చరించకుండానే టాబ్లెట్ డేటాను ఎరేజ్ చేయండి."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"\'ఫ్యాక్టరీ డేటా రీసెట్\'ను అమలు చేయడం ద్వారా వార్నింగ్తో పని లేకుండా టాబ్లెట్ డేటాను ఎరేజ్ చేయండి."</string>
<string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"హెచ్చరించకుండానే మీ Android TV పరికరం డేటాను ఫ్యాక్టరీ డేటా రీసెట్ ద్వారా తొలగిస్తుంది."</string>
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"ఫ్యాక్టరీ డేటా రీసెట్ను అమలు చేయడం ద్వారా, హెచ్చరిక లేకుండానే సమాచారంతో కూడిన వినోదం సిస్టమ్ డేటాను తొలగించి ఫ్యాక్టరీ రీసెట్ చేయబడుతుంది."</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"ఫ్యాక్టరీ డేటా రీసెట్ను అమలు చేయడం ద్వారా హెచ్చరించకుండానే ఫోన్ డేటాను ఎరేజ్ చేస్తుంది."</string>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index a248ede..cc02a7e 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -190,6 +190,13 @@
<integer name="config_satellite_nb_iot_inactivity_timeout_millis">180000</integer>
<java-symbol type="integer" name="config_satellite_nb_iot_inactivity_timeout_millis" />
+ <!-- The time duration in millis after which cellular scanning will be enabled and satellite
+ will move to IDLE state. This timeout duration is used for satellite with NB IOT radio
+ technologies in demo mode.
+ -->
+ <integer name="config_satellite_demo_mode_nb_iot_inactivity_timeout_millis">60000</integer>
+ <java-symbol type="integer" name="config_satellite_demo_mode_nb_iot_inactivity_timeout_millis" />
+
<!-- The time duration in millis needed to switch the modem image from TN to NTN. -->
<integer name="config_satellite_modem_image_switching_duration_millis">20000</integer>
<java-symbol type="integer" name="config_satellite_modem_image_switching_duration_millis" />
diff --git a/core/res/res/values/required_apps_managed_device.xml b/core/res/res/values/required_apps_managed_device.xml
index c455bd8..c80d66c 100644
--- a/core/res/res/values/required_apps_managed_device.xml
+++ b/core/res/res/values/required_apps_managed_device.xml
@@ -29,5 +29,6 @@
<item>com.android.providers.downloads.ui</item>
<item>com.android.documentsui</item>
<item>com.android.cellbroadcastreceiver</item>
+ <item>com.android.webview</item>
</string-array>
</resources>
diff --git a/core/res/res/values/required_apps_managed_profile.xml b/core/res/res/values/required_apps_managed_profile.xml
index 6ed385a..5f52e1e 100644
--- a/core/res/res/values/required_apps_managed_profile.xml
+++ b/core/res/res/values/required_apps_managed_profile.xml
@@ -26,5 +26,6 @@
<item>com.android.providers.downloads</item>
<item>com.android.providers.downloads.ui</item>
<item>com.android.documentsui</item>
+ <item>com.android.webview</item>
</string-array>
</resources>
diff --git a/core/res/res/values/required_apps_managed_user.xml b/core/res/res/values/required_apps_managed_user.xml
index a6fc573..3e75a4c 100644
--- a/core/res/res/values/required_apps_managed_user.xml
+++ b/core/res/res/values/required_apps_managed_user.xml
@@ -28,5 +28,6 @@
<item>com.android.providers.downloads</item>
<item>com.android.providers.downloads.ui</item>
<item>com.android.documentsui</item>
+ <item>com.android.webview</item>
</string-array>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2f9f4df..4ea97a5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -6050,6 +6050,10 @@
<!-- Dialog text. Shown when the user is unable to send a text message from a personal app due to restrictions set
by their organization, and so must switch to a work app or cancel. [CHAR LIMIT=NONE] -->
<string name="miniresolver_sms_information">Your organization only allows you to send messages from work apps</string>
+ <!-- Dialog text. Shown as when redirecting Calls from Private Space to the main user. [CHAR LIMIT=NONE] -->
+ <string name="miniresolver_private_space_phone_information">"You can only make phone calls from your personal Phone app. Calls made with personal Phone will be added to your personal call history."</string>
+ <!-- Dialog text. Shown as when redirecting SMS and MMS messages from Private Space to the main user. [CHAR LIMIT=NONE] -->
+ <string name="miniresolver_private_space_messages_information">"You can only send SMS messages from your personal Messages app."</string>
<!-- Button option. Open the link in the personal browser. [CHAR LIMIT=NONE] -->
<string name="miniresolver_use_personal_browser">Use personal browser</string>
<!-- Button option. Open the link in the work browser. [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 90132c3..e304027 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1628,6 +1628,8 @@
<java-symbol type="string" name="miniresolver_switch" />
<java-symbol type="string" name="miniresolver_call_information" />
<java-symbol type="string" name="miniresolver_sms_information" />
+ <java-symbol type="string" name="miniresolver_private_space_phone_information" />
+ <java-symbol type="string" name="miniresolver_private_space_messages_information" />
<java-symbol type="id" name="miniresolver_info_section" />
<java-symbol type="id" name="miniresolver_info_section_text" />
<java-symbol type="id" name="button_open" />
diff --git a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
index 9bb064c..62d89f6 100644
--- a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
+++ b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
@@ -19,10 +19,20 @@
import static android.os.storage.VolumeInfo.STATE_MOUNTED;
import static android.os.storage.VolumeInfo.STATE_UNMOUNTED;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.os.Bundle;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.platform.test.annotations.Presubmit;
@@ -35,9 +45,11 @@
import junit.framework.TestCase;
import org.mockito.Mockito;
+import org.xmlpull.v1.XmlPullParser;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
@Presubmit
@@ -93,9 +105,11 @@
private static final class MockedApplicationPackageManager extends ApplicationPackageManager {
private boolean mForceAllowOnExternal = false;
private boolean mAllow3rdPartyOnInternal = true;
+ private HashMap<ApplicationInfo, Resources> mResourcesMap;
public MockedApplicationPackageManager() {
super(null, null);
+ mResourcesMap = new HashMap<ApplicationInfo, Resources>();
}
public void setForceAllowOnExternal(boolean forceAllowOnExternal) {
@@ -106,6 +120,10 @@
mAllow3rdPartyOnInternal = allow3rdPartyOnInternal;
}
+ public void setResourcesForApplication(ApplicationInfo info, Resources resources) {
+ mResourcesMap.put(info, resources);
+ }
+
@Override
public boolean isForceAllowOnExternal(Context context) {
return mForceAllowOnExternal;
@@ -122,6 +140,16 @@
StorageManager storageManager, IPackageManager pm) {
return super.getPackageCandidateVolumes(app, storageManager, pm);
}
+
+ @Override
+ public Resources getResourcesForApplication(ApplicationInfo app)
+ throws NameNotFoundException {
+ if (mResourcesMap.containsKey(app)) {
+ return mResourcesMap.get(app);
+ }
+
+ return super.getResourcesForApplication(app);
+ }
}
private StorageManager getMockedStorageManager() {
@@ -254,4 +282,73 @@
verifyReturnedVolumes(candidates, sAdoptedVol);
}
}
+
+ public void testExtractPackageItemInfoAttributes_noServiceInfo() {
+ final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+ assertThat(appPkgMgr.extractPackageItemInfoAttributes(null, null, null,
+ new int[]{})).isNull();
+ }
+
+ public void testExtractPackageItemInfoAttributes_noMetaData() {
+ final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+ final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+ assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null,
+ new int[]{})).isNull();
+ }
+
+ public void testExtractPackageItemInfoAttributes_noParser() {
+ final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+ final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+ final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+ when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
+ assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null,
+ new int[]{})).isNull();
+ }
+
+ public void testExtractPackageItemInfoAttributes_noMetaDataXml() {
+ final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+ final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+ final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+ when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
+ when(packageItemInfo.loadXmlMetaData(any(), any())).thenReturn(null);
+ assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null,
+ new int[]{})).isNull();
+ }
+
+ public void testExtractPackageItemInfoAttributes_nonMatchingRootTag() throws Exception {
+ final String rootTag = "rootTag";
+ final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+ final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+ final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+ final XmlResourceParser parser = Mockito.mock(XmlResourceParser.class);
+
+ when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
+ packageItemInfo.metaData = new Bundle();
+ when(packageItemInfo.loadXmlMetaData(any(), any())).thenReturn(parser);
+ when(parser.next()).thenReturn(XmlPullParser.END_DOCUMENT);
+ when(parser.getName()).thenReturn(rootTag + "0");
+ assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, rootTag,
+ new int[]{})).isNull();
+ }
+
+ public void testExtractPackageItemInfoAttributes_successfulExtraction() throws Exception {
+ final String rootTag = "rootTag";
+ final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+ final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+ final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+ final XmlResourceParser parser = Mockito.mock(XmlResourceParser.class);
+ final Resources resources = Mockito.mock(Resources.class);
+ final TypedArray attributes = Mockito.mock(TypedArray.class);
+
+ when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
+ packageItemInfo.metaData = new Bundle();
+ when(packageItemInfo.loadXmlMetaData(any(), any())).thenReturn(parser);
+ when(parser.next()).thenReturn(XmlPullParser.END_DOCUMENT);
+ when(parser.getName()).thenReturn(rootTag);
+ when(resources.obtainAttributes(any(), any())).thenReturn(attributes);
+ appPkgMgr.setResourcesForApplication(applicationInfo, resources);
+
+ assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, rootTag,
+ new int[]{})).isEqualTo(attributes);
+ }
}
diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
index 4cdc993..f885e31 100644
--- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java
+++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
@@ -19,6 +19,7 @@
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
+import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
@@ -435,6 +436,107 @@
waitForAfterDraw();
}
+ @Test
+ @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+ FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY
+ })
+ public void willNotDrawUsesCategory() throws Throwable {
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.setWillNotDraw(true);
+ mMovingView.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_LOW);
+ });
+ waitForFrameRateCategoryToSettle();
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.invalidate();
+ runAfterDraw(() -> assertEquals(FRAME_RATE_CATEGORY_LOW,
+ mViewRoot.getLastPreferredFrameRateCategory()));
+ });
+ waitForAfterDraw();
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_NORMAL);
+ mMovingView.setAlpha(0.9f);
+ runAfterDraw(() -> {
+ assertEquals(FRAME_RATE_CATEGORY_NORMAL,
+ mViewRoot.getLastPreferredFrameRateCategory());
+ });
+ });
+ waitForAfterDraw();
+ }
+
+ /**
+ * A common behavior is for two different views to be invalidated in succession, but
+ * intermittently. We want to treat this as an intermittent invalidation.
+ *
+ * This test will only succeed on non-cuttlefish devices, so it is commented out
+ * for potential manual testing.
+ */
+// @Test
+ @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+ FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
+ public void intermittentDoubleInvalidate() throws Throwable {
+ View parent = (View) mMovingView.getParent();
+ mActivityRule.runOnUiThread(() -> {
+ parent.setWillNotDraw(false);
+ // Make sure the View is large
+ ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
+ layoutParams.width = parent.getWidth();
+ layoutParams.height = parent.getHeight();
+ mMovingView.setLayoutParams(layoutParams);
+ });
+ waitForFrameRateCategoryToSettle();
+ for (int i = 0; i < 5; i++) {
+ int expectedCategory;
+ if (i < 4) {
+ // not intermittent yet.
+ // It takes 2 frames of intermittency before Views vote as intermittent.
+ // It takes 4 more frames for the category to drop to the next category.
+ expectedCategory =
+ toolkitFrameRateDefaultNormalReadOnly() ? FRAME_RATE_CATEGORY_NORMAL
+ : FRAME_RATE_CATEGORY_HIGH;
+ } else {
+ // intermittent
+ expectedCategory = FRAME_RATE_CATEGORY_NORMAL;
+ }
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.invalidate();
+ runAfterDraw(() -> assertEquals(expectedCategory,
+ mViewRoot.getLastPreferredFrameRateCategory()));
+ });
+ waitForAfterDraw();
+ mActivityRule.runOnUiThread(() -> {
+ parent.invalidate();
+ runAfterDraw(() -> assertEquals(expectedCategory,
+ mViewRoot.getLastPreferredFrameRateCategory()));
+ });
+ waitForAfterDraw();
+ Thread.sleep(90);
+ }
+ }
+
+ // When a view has two motions that offset each other, the overall motion
+ // should be canceled and be considered unmoved.
+ @Test
+ @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+ FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY
+ })
+ public void sameFrameMotion() throws Throwable {
+ mMovingView.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE);
+ waitForFrameRateCategoryToSettle();
+
+ mActivityRule.runOnUiThread(() -> {
+ mMovingView.offsetLeftAndRight(10);
+ mMovingView.offsetLeftAndRight(-10);
+ mMovingView.offsetTopAndBottom(100);
+ mMovingView.offsetTopAndBottom(-100);
+ mMovingView.invalidate();
+ runAfterDraw(() -> {
+ assertEquals(0f, mViewRoot.getLastPreferredFrameRate(), 0f);
+ assertEquals(FRAME_RATE_CATEGORY_NO_PREFERENCE,
+ mViewRoot.getLastPreferredFrameRateCategory());
+ });
+ });
+ waitForAfterDraw();
+ }
private void runAfterDraw(@NonNull Runnable runnable) {
Handler handler = new Handler(Looper.getMainLooper());
mAfterDrawLatch = new CountDownLatch(1);
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index 36bede9..852d696 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -34,6 +34,7 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
@@ -403,7 +404,9 @@
mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
OnBackInvokedCallbackInfo callbackInfo = assertSetCallbackInfo();
- mDispatcher.onMotionEvent(mMotionEvent);
+ // Send motion event in View's main thread.
+ final Handler main = Handler.getMain();
+ main.runWithScissors(() -> mDispatcher.onMotionEvent(mMotionEvent), 100);
assertFalse(mDispatcher.mTouchTracker.isActive());
callbackInfo.getCallback().onBackStarted(mBackEvent);
@@ -411,8 +414,9 @@
assertTrue(mDispatcher.isDispatching());
assertTrue(mDispatcher.mTouchTracker.isActive());
- mDispatcher.onMotionEvent(mMotionEvent);
+ main.runWithScissors(() -> mDispatcher.onMotionEvent(mMotionEvent), 100);
waitForIdle();
- verify(mCallback1).onBackProgressed(any());
+ // onBackPressed is called from animator, so it can happen more than once.
+ verify(mCallback1, atLeast(1)).onBackProgressed(any());
}
}
diff --git a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
index 9cb9122..03cb17e 100644
--- a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
+++ b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -95,6 +96,16 @@
}
@Test
+ public void testPackageMonitorNotRegisterWithoutSupportPackageRestartQuery() throws Exception {
+ PackageMonitor spyPackageMonitor = spy(new TestPackageMonitor(false));
+
+ spyPackageMonitor.register(mMockContext, UserHandle.ALL, mMockHandler);
+
+ verify(mMockContext, never()).registerReceiverAsUser(any(), eq(UserHandle.ALL), any(),
+ eq(null), eq(mMockHandler));
+ }
+
+ @Test
public void testPackageMonitorDoHandlePackageEventUidRemoved() throws Exception {
PackageMonitor spyPackageMonitor = spy(new TestPackageMonitor());
@@ -471,5 +482,12 @@
}
public static class TestPackageMonitor extends PackageMonitor {
+ public TestPackageMonitor(boolean b) {
+ super(b);
+ }
+
+ public TestPackageMonitor() {
+ super();
+ }
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 46a3e7f..89d3058 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -67,7 +67,6 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
-import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -113,8 +112,7 @@
public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmentCallback,
ActivityEmbeddingComponent, DividerPresenter.DragEventCallback {
static final String TAG = "SplitController";
- static final boolean ENABLE_SHELL_TRANSITIONS =
- SystemProperties.getBoolean("persist.wm.debug.shell_transit", true);
+ static final boolean ENABLE_SHELL_TRANSITIONS = true;
// TODO(b/243518738): Move to WM Extensions if we have requirement of overlay without
// association. It's not set in WM Extensions nor Wm Jetpack library currently.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
index 1fb966f..9440e98 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
@@ -468,9 +468,9 @@
final int index = mLayout.indexOfChild(bubbleView);
final PointF p = mPositioner.getExpandedBubbleXY(index, mBubbleStackView.getState());
animationForChildAtIndex(index)
- .position(p.x, p.y)
+ .position(p.x, p.y, /* translationZ= */ 0f)
.withPositionStartVelocities(velX, velY)
- .start(() -> bubbleView.setTranslationZ(0f) /* after */);
+ .start();
mMagnetizedBubbleDraggingOut = null;
@@ -509,6 +509,7 @@
return Sets.newHashSet(
DynamicAnimation.TRANSLATION_X,
DynamicAnimation.TRANSLATION_Y,
+ DynamicAnimation.TRANSLATION_Z,
DynamicAnimation.SCALE_X,
DynamicAnimation.SCALE_Y,
DynamicAnimation.ALPHA);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
index bfddff0..06305f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
@@ -419,7 +419,8 @@
// be animating in this case, even if the physics animations haven't been started yet.
final boolean isTranslation =
property.equals(DynamicAnimation.TRANSLATION_X)
- || property.equals(DynamicAnimation.TRANSLATION_Y);
+ || property.equals(DynamicAnimation.TRANSLATION_Y)
+ || property.equals(DynamicAnimation.TRANSLATION_Z);
if (isTranslation && targetAnimator != null && targetAnimator.isRunning()) {
return true;
}
@@ -495,6 +496,8 @@
return "TRANSLATION_X";
} else if (property.equals(DynamicAnimation.TRANSLATION_Y)) {
return "TRANSLATION_Y";
+ } else if (property.equals(DynamicAnimation.TRANSLATION_Z)) {
+ return "TRANSLATION_Z";
} else if (property.equals(DynamicAnimation.SCALE_X)) {
return "SCALE_X";
} else if (property.equals(DynamicAnimation.SCALE_Y)) {
@@ -598,6 +601,8 @@
return R.id.translation_x_dynamicanimation_tag;
} else if (property.equals(DynamicAnimation.TRANSLATION_Y)) {
return R.id.translation_y_dynamicanimation_tag;
+ } else if (property.equals(DynamicAnimation.TRANSLATION_Z)) {
+ return R.id.translation_z_dynamicanimation_tag;
} else if (property.equals(DynamicAnimation.SCALE_X)) {
return R.id.scale_x_dynamicanimation_tag;
} else if (property.equals(DynamicAnimation.SCALE_Y)) {
@@ -763,6 +768,12 @@
return property(DynamicAnimation.TRANSLATION_X, translationX, endActions);
}
+ /** Animate the view's translationZ value to the provided value. */
+ public PhysicsPropertyAnimator translationZ(float translationZ, Runnable... endActions) {
+ mPathAnimator = null; // We aren't using the path anymore if we're translating.
+ return property(DynamicAnimation.TRANSLATION_Z, translationZ, endActions);
+ }
+
/** Set the view's translationX value to 'from', then animate it to the given value. */
public PhysicsPropertyAnimator translationX(
float from, float to, Runnable... endActions) {
@@ -785,13 +796,14 @@
/**
* Animate the view's translationX and translationY values, and call the end actions only
- * once both TRANSLATION_X and TRANSLATION_Y animations have completed.
+ * once both TRANSLATION_X, TRANSLATION_Y and TRANSLATION_Z animations have completed.
*/
- public PhysicsPropertyAnimator position(
- float translationX, float translationY, Runnable... endActions) {
+ public PhysicsPropertyAnimator position(float translationX, float translationY,
+ float translationZ, Runnable... endActions) {
mPositionEndActions = endActions;
translationX(translationX);
- return translationY(translationY);
+ translationY(translationY);
+ return translationZ(translationZ);
}
/**
@@ -845,10 +857,13 @@
private void clearTranslationValues() {
mAnimatedProperties.remove(DynamicAnimation.TRANSLATION_X);
mAnimatedProperties.remove(DynamicAnimation.TRANSLATION_Y);
+ mAnimatedProperties.remove(DynamicAnimation.TRANSLATION_Z);
mInitialPropertyValues.remove(DynamicAnimation.TRANSLATION_X);
mInitialPropertyValues.remove(DynamicAnimation.TRANSLATION_Y);
+ mInitialPropertyValues.remove(DynamicAnimation.TRANSLATION_Z);
mEndActionForProperty.remove(DynamicAnimation.TRANSLATION_X);
mEndActionForProperty.remove(DynamicAnimation.TRANSLATION_Y);
+ mEndActionForProperty.remove(DynamicAnimation.TRANSLATION_Z);
}
/** Animate the view's scaleX value to the provided value. */
@@ -939,15 +954,19 @@
}, propertiesArray);
}
- // If we used position-specific end actions, we'll need to listen for both TRANSLATION_X
- // and TRANSLATION_Y animations ending, and call them once both have finished.
+ // If we used position-specific end actions, we'll need to listen for TRANSLATION_X
+ // TRANSLATION_Y and TRANSLATION_Z animations ending, and call them once both have
+ // finished.
if (mPositionEndActions != null) {
final SpringAnimation translationXAnim =
getSpringAnimationFromView(DynamicAnimation.TRANSLATION_X, mView);
final SpringAnimation translationYAnim =
getSpringAnimationFromView(DynamicAnimation.TRANSLATION_Y, mView);
- final Runnable waitForBothXAndY = () -> {
- if (!translationXAnim.isRunning() && !translationYAnim.isRunning()) {
+ final SpringAnimation translationZAnim =
+ getSpringAnimationFromView(DynamicAnimation.TRANSLATION_Z, mView);
+ final Runnable waitForXYZ = () -> {
+ if (!translationXAnim.isRunning() && !translationYAnim.isRunning()
+ && !translationZAnim.isRunning()) {
if (mPositionEndActions != null) {
for (Runnable callback : mPositionEndActions) {
callback.run();
@@ -959,9 +978,11 @@
};
mEndActionsForProperty.put(DynamicAnimation.TRANSLATION_X,
- new Runnable[]{waitForBothXAndY});
+ new Runnable[]{waitForXYZ});
mEndActionsForProperty.put(DynamicAnimation.TRANSLATION_Y,
- new Runnable[]{waitForBothXAndY});
+ new Runnable[]{waitForXYZ});
+ mEndActionsForProperty.put(DynamicAnimation.TRANSLATION_Z,
+ new Runnable[]{waitForXYZ});
}
if (mPathAnimator != null) {
@@ -972,9 +993,10 @@
for (DynamicAnimation.ViewProperty property : properties) {
// Don't start translation animations if we're using a path animator, the update
// listeners added to that animator will take care of that.
- if (mPathAnimator != null
- && (property.equals(DynamicAnimation.TRANSLATION_X)
- || property.equals(DynamicAnimation.TRANSLATION_Y))) {
+ boolean isTranslationProperty = property.equals(DynamicAnimation.TRANSLATION_X)
+ || property.equals(DynamicAnimation.TRANSLATION_Y)
+ || property.equals(DynamicAnimation.TRANSLATION_Z);
+ if (mPathAnimator != null && isTranslationProperty) {
return;
}
@@ -1006,6 +1028,7 @@
if (mPathAnimator != null) {
animatedProperties.add(DynamicAnimation.TRANSLATION_X);
animatedProperties.add(DynamicAnimation.TRANSLATION_Y);
+ animatedProperties.add(DynamicAnimation.TRANSLATION_Z);
}
return animatedProperties;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index c6b127d..9b2922d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -44,9 +44,11 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
+import android.app.AppGlobals;
import android.app.IApplicationThread;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.IBinder;
@@ -126,8 +128,7 @@
static final String TAG = "ShellTransitions";
/** Set to {@code true} to enable shell transitions. */
- public static final boolean ENABLE_SHELL_TRANSITIONS =
- SystemProperties.getBoolean("persist.wm.debug.shell_transit", true);
+ public static final boolean ENABLE_SHELL_TRANSITIONS = getShellTransitEnabled();
public static final boolean SHELL_TRANSITIONS_ROTATION = ENABLE_SHELL_TRANSITIONS
&& SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
@@ -1710,4 +1711,16 @@
}
}
}
+
+ private static boolean getShellTransitEnabled() {
+ try {
+ if (AppGlobals.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE, 0)) {
+ return SystemProperties.getBoolean("persist.wm.debug.shell_transit", true);
+ }
+ } catch (RemoteException re) {
+ Log.w(TAG, "Error getting system features");
+ }
+ return true;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/tracing/PerfettoTransitionTracer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/tracing/PerfettoTransitionTracer.java
index ed4ae05..1897560 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/tracing/PerfettoTransitionTracer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/tracing/PerfettoTransitionTracer.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.transition.tracing;
+import static android.tracing.perfetto.DataSourceParams.PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_STALL_AND_ABORT;
+
import android.internal.perfetto.protos.ShellTransitionOuterClass.ShellHandlerMapping;
import android.internal.perfetto.protos.ShellTransitionOuterClass.ShellHandlerMappings;
import android.internal.perfetto.protos.ShellTransitionOuterClass.ShellTransition;
@@ -47,7 +49,8 @@
public PerfettoTransitionTracer() {
Producer.init(InitArguments.DEFAULTS);
- mDataSource.register(DataSourceParams.DEFAULTS);
+ mDataSource.register(
+ new DataSourceParams(PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_STALL_AND_ABORT));
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 43fd32b..6671391 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -200,7 +200,6 @@
mRelayoutParams.mShadowRadiusId = shadowRadiusID;
mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
mRelayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition;
- mRelayoutParams.mAllowCaptionInputFallthrough = false;
relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
// After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
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 6a9d17f..922c55f 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
@@ -1037,7 +1037,6 @@
mSyncQueue,
mRootTaskDisplayAreaOrganizer);
mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
- windowDecoration.createResizeVeil();
final DragPositioningCallback dragPositioningCallback;
if (!DesktopModeStatus.isVeiledResizeEnabled()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 9349c93..cb6495c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -44,6 +44,7 @@
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.os.Trace;
import android.util.Log;
import android.util.Size;
import android.view.Choreographer;
@@ -51,6 +52,7 @@
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.WindowManager;
import android.widget.ImageButton;
import android.window.WindowContainerTransaction;
@@ -158,7 +160,9 @@
mSyncQueue = syncQueue;
mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+ Trace.beginSection("DesktopModeWindowDecoration#loadAppInfo");
loadAppInfo();
+ Trace.endSection();
}
void setCaptionListeners(
@@ -204,6 +208,7 @@
void relayout(ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
+ Trace.beginSection("DesktopModeWindowDecoration#relayout");
if (isHandleMenuActive()) {
mHandleMenu.relayout(startT);
}
@@ -215,16 +220,22 @@
final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
final WindowContainerTransaction wct = new WindowContainerTransaction();
+ Trace.beginSection("DesktopModeWindowDecoration#relayout-inner");
relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
+ Trace.endSection();
// After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
+ Trace.beginSection("DesktopModeWindowDecoration#relayout-applyWCT");
mTaskOrganizer.applyTransaction(wct);
+ Trace.endSection();
if (mResult.mRootView == null) {
// This means something blocks the window decor from showing, e.g. the task is hidden.
// Nothing is set up in this case including the decoration surface.
+ Trace.endSection(); // DesktopModeWindowDecoration#relayout
return;
}
+
if (oldRootView != mResult.mRootView) {
if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_focused_window_decor) {
mWindowDecorViewHolder = new DesktopModeFocusedWindowDecorationViewHolder(
@@ -252,7 +263,9 @@
throw new IllegalArgumentException("Unexpected layout resource id");
}
}
+ Trace.beginSection("DesktopModeWindowDecoration#relayout-binding");
mWindowDecorViewHolder.bindData(mTaskInfo);
+ Trace.endSection();
if (!mTaskInfo.isFocused) {
closeHandleMenu();
@@ -268,11 +281,13 @@
updateExclusionRegion();
}
closeDragResizeListener();
+ Trace.endSection(); // DesktopModeWindowDecoration#relayout
return;
}
if (oldDecorationSurface != mDecorationContainerSurface || mDragResizeListener == null) {
closeDragResizeListener();
+ Trace.beginSection("DesktopModeWindowDecoration#relayout-DragResizeInputListener");
mDragResizeListener = new DragResizeInputListener(
mContext,
mHandler,
@@ -283,6 +298,7 @@
mSurfaceControlBuilderSupplier,
mSurfaceControlTransactionSupplier,
mDisplayController);
+ Trace.endSection();
}
final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext())
@@ -307,6 +323,7 @@
mMaximizeMenu.positionMenu(calculateMaximizeMenuPosition(), startT);
}
}
+ Trace.endSection(); // DesktopModeWindowDecoration#relayout
}
@VisibleForTesting
@@ -324,11 +341,12 @@
relayoutParams.mCaptionWidthId = getCaptionWidthId(relayoutParams.mLayoutResId);
if (captionLayoutId == R.layout.desktop_mode_app_controls_window_decor) {
- // If the app is requesting to customize the caption bar, allow input to fall through
- // to the windows below so that the app can respond to input events on their custom
- // content.
- relayoutParams.mAllowCaptionInputFallthrough =
- TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo);
+ if (TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
+ // If the app is requesting to customize the caption bar, allow input to fall
+ // through to the windows below so that the app can respond to input events on
+ // their custom content.
+ relayoutParams.mInputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
+ }
// Report occluding elements as bounding rects to the insets system so that apps can
// draw in the empty space in the center:
// First, the "app chip" section of the caption bar (+ some extra margins).
@@ -343,6 +361,11 @@
controlsElement.mWidthResId = R.dimen.desktop_mode_customizable_caption_margin_end;
controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END;
relayoutParams.mOccludingCaptionElements.add(controlsElement);
+ } else if (captionLayoutId == R.layout.desktop_mode_focused_window_decor) {
+ // The focused decor (fullscreen/split) does not need to handle input because input in
+ // the App Handle is handled by the InputMonitor in DesktopModeWindowDecorViewModel.
+ relayoutParams.mInputFeatures
+ |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
}
if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ taskInfo.isFocused)) {
relayoutParams.mShadowRadiusId = taskInfo.isFocused
@@ -464,7 +487,8 @@
* Create the resize veil for this task. Note the veil's visibility is View.GONE by default
* until a resize event calls showResizeVeil below.
*/
- void createResizeVeil() {
+ private void createResizeVeilIfNeeded() {
+ if (mResizeVeil != null) return;
mResizeVeil = new ResizeVeil(mContext, mDisplayController, mAppIconBitmap, mTaskInfo,
mTaskSurface, mSurfaceControlTransactionSupplier);
}
@@ -473,6 +497,7 @@
* Show the resize veil.
*/
public void showResizeVeil(Rect taskBounds) {
+ createResizeVeilIfNeeded();
mResizeVeil.showVeil(mTaskSurface, taskBounds);
}
@@ -480,6 +505,7 @@
* Show the resize veil.
*/
public void showResizeVeil(SurfaceControl.Transaction tx, Rect taskBounds) {
+ createResizeVeilIfNeeded();
mResizeVeil.showVeil(tx, mTaskSurface, taskBounds, false /* fadeIn */);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java
index a3c3ece..93e2a21 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java
@@ -29,6 +29,7 @@
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.os.Trace;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.SurfaceControl;
@@ -135,6 +136,7 @@
// Display may not be available yet, skip this until then.
return;
}
+ Trace.beginSection("ResizeVeil#setupResizeVeil");
mVeilSurface = mSurfaceControlBuilderFactory
.create("Resize veil of Task=" + mTaskInfo.taskId)
.setContainerLayer()
@@ -179,6 +181,7 @@
mViewHost = mSurfaceControlViewHostFactory.create(mContext, mDisplay, wwm, "ResizeVeil");
mViewHost.setView(root, lp);
+ Trace.endSection();
}
private boolean obtainDisplayOrRegisterListener() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 36da1ac..54656ff 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -33,6 +33,7 @@
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Binder;
+import android.os.Trace;
import android.view.Display;
import android.view.InsetsSource;
import android.view.InsetsState;
@@ -311,7 +312,7 @@
boundingRects = null;
} else {
// The customizable region can at most be equal to the caption bar.
- if (params.mAllowCaptionInputFallthrough) {
+ if (params.hasInputFeatureSpy()) {
outResult.mCustomizableCaptionRegion.set(mCaptionInsetsRect);
}
boundingRects = new Rect[numOfElements];
@@ -324,7 +325,7 @@
calculateBoundingRect(element, elementWidthPx, mCaptionInsetsRect);
// Subtract the regions used by the caption elements, the rest is
// customizable.
- if (params.mAllowCaptionInputFallthrough) {
+ if (params.hasInputFeatureSpy()) {
outResult.mCustomizableCaptionRegion.op(boundingRects[i],
Region.Op.DIFFERENCE);
}
@@ -378,6 +379,7 @@
startT.unsetColor(mTaskSurface);
}
+ Trace.beginSection("CaptionViewHostLayout");
if (mCaptionWindowManager == null) {
// Put caption under a container surface because ViewRootImpl sets the destination frame
// of windowless window layers and BLASTBufferQueue#update() doesn't support offset.
@@ -394,11 +396,7 @@
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
lp.setTitle("Caption of Task=" + mTaskInfo.taskId);
lp.setTrustedOverlay();
- if (params.mAllowCaptionInputFallthrough) {
- lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
- } else {
- lp.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY;
- }
+ lp.inputFeatures = params.mInputFeatures;
if (mViewHost == null) {
mViewHost = mSurfaceControlViewHostFactory.create(mDecorWindowContext, mDisplay,
mCaptionWindowManager);
@@ -412,6 +410,7 @@
}
mViewHost.relayout(lp);
}
+ Trace.endSection(); // CaptionViewHostLayout
}
private Rect calculateBoundingRect(@NonNull OccludingCaptionElement element,
@@ -605,7 +604,7 @@
int mCaptionHeightId;
int mCaptionWidthId;
final List<OccludingCaptionElement> mOccludingCaptionElements = new ArrayList<>();
- boolean mAllowCaptionInputFallthrough;
+ int mInputFeatures;
int mShadowRadiusId;
int mCornerRadius;
@@ -620,7 +619,7 @@
mCaptionHeightId = Resources.ID_NULL;
mCaptionWidthId = Resources.ID_NULL;
mOccludingCaptionElements.clear();
- mAllowCaptionInputFallthrough = false;
+ mInputFeatures = 0;
mShadowRadiusId = Resources.ID_NULL;
mCornerRadius = 0;
@@ -630,6 +629,10 @@
mWindowDecorConfig = null;
}
+ boolean hasInputFeatureSpy() {
+ return (mInputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_SPY) != 0;
+ }
+
/**
* Describes elements within the caption bar that could occlude app content, and should be
* sent as bounding rectangles to the insets system.
diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS
index d718e15..0f24bb5 100644
--- a/libs/WindowManager/Shell/tests/OWNERS
+++ b/libs/WindowManager/Shell/tests/OWNERS
@@ -12,3 +12,4 @@
nmusgrave@google.com
pbdr@google.com
tkachenkoi@google.com
+mpodolian@google.com
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTest.java
index 964711e..0431285 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayoutTest.java
@@ -69,7 +69,8 @@
// to animate child views out before actually removing them).
mTestableController.setAnimatedProperties(Sets.newHashSet(
DynamicAnimation.TRANSLATION_X,
- DynamicAnimation.TRANSLATION_Y));
+ DynamicAnimation.TRANSLATION_Y,
+ DynamicAnimation.TRANSLATION_Z));
mTestableController.setChainedProperties(Sets.newHashSet(DynamicAnimation.TRANSLATION_X));
mTestableController.setOffsetForProperty(
DynamicAnimation.TRANSLATION_X, TEST_TRANSLATION_X_OFFSET);
@@ -282,10 +283,13 @@
addOneMoreThanBubbleLimitBubbles();
assertFalse(mLayout.arePropertiesAnimating(
- DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y));
+ DynamicAnimation.TRANSLATION_X,
+ DynamicAnimation.TRANSLATION_Y,
+ DynamicAnimation.TRANSLATION_Z));
mTestableController.animationForChildAtIndex(0)
.translationX(100f)
+ .translationZ(100f)
.start();
// Wait for the animations to get underway.
@@ -293,11 +297,13 @@
assertTrue(mLayout.arePropertiesAnimating(DynamicAnimation.TRANSLATION_X));
assertFalse(mLayout.arePropertiesAnimating(DynamicAnimation.TRANSLATION_Y));
+ assertTrue(mLayout.arePropertiesAnimating(DynamicAnimation.TRANSLATION_Z));
- waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X);
+ waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Z);
assertFalse(mLayout.arePropertiesAnimating(
- DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y));
+ DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y,
+ DynamicAnimation.TRANSLATION_Z));
}
@Test
@@ -307,7 +313,7 @@
addOneMoreThanBubbleLimitBubbles();
mTestableController.animationForChildAtIndex(0)
- .position(1000, 1000)
+ .position(1000, 1000, 1000)
.start();
mLayout.cancelAllAnimations();
@@ -315,6 +321,7 @@
// Animations should be somewhere before their end point.
assertTrue(mViews.get(0).getTranslationX() < 1000);
assertTrue(mViews.get(0).getTranslationY() < 1000);
+ assertTrue(mViews.get(0).getZ() < 10000);
}
/** Standard test of chained translation animations. */
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index f9b5882..608f74b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -18,6 +18,7 @@
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.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND;
import static com.google.common.truth.Truth.assertThat;
@@ -44,6 +45,7 @@
import android.view.Display;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
+import android.view.WindowManager;
import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
@@ -187,7 +189,7 @@
/* applyStartTransactionOnDraw= */ true,
/* shouldSetTaskPositionAndCrop */ false);
- assertThat(relayoutParams.mAllowCaptionInputFallthrough).isTrue();
+ assertThat(relayoutParams.hasInputFeatureSpy()).isTrue();
}
@Test
@@ -204,7 +206,7 @@
/* applyStartTransactionOnDraw= */ true,
/* shouldSetTaskPositionAndCrop */ false);
- assertThat(relayoutParams.mAllowCaptionInputFallthrough).isFalse();
+ assertThat(relayoutParams.hasInputFeatureSpy()).isFalse();
}
@Test
@@ -220,7 +222,55 @@
/* applyStartTransactionOnDraw= */ true,
/* shouldSetTaskPositionAndCrop */ false);
- assertThat(relayoutParams.mAllowCaptionInputFallthrough).isFalse();
+ assertThat(relayoutParams.hasInputFeatureSpy()).isFalse();
+ }
+
+ @Test
+ public void updateRelayoutParams_freeform_inputChannelNeeded() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ final RelayoutParams relayoutParams = new RelayoutParams();
+
+ DesktopModeWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ mTestableContext,
+ taskInfo,
+ /* applyStartTransactionOnDraw= */ true,
+ /* shouldSetTaskPositionAndCrop */ false);
+
+ assertThat(hasNoInputChannelFeature(relayoutParams)).isFalse();
+ }
+
+ @Test
+ public void updateRelayoutParams_fullscreen_inputChannelNotNeeded() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ final RelayoutParams relayoutParams = new RelayoutParams();
+
+ DesktopModeWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ mTestableContext,
+ taskInfo,
+ /* applyStartTransactionOnDraw= */ true,
+ /* shouldSetTaskPositionAndCrop */ false);
+
+ assertThat(hasNoInputChannelFeature(relayoutParams)).isTrue();
+ }
+
+ @Test
+ public void updateRelayoutParams_multiwindow_inputChannelNotNeeded() {
+ final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+ taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ final RelayoutParams relayoutParams = new RelayoutParams();
+
+ DesktopModeWindowDecoration.updateRelayoutParams(
+ relayoutParams,
+ mTestableContext,
+ taskInfo,
+ /* applyStartTransactionOnDraw= */ true,
+ /* shouldSetTaskPositionAndCrop */ false);
+
+ assertThat(hasNoInputChannelFeature(relayoutParams)).isTrue();
}
private void fillRoundedCornersResources(int fillValue) {
@@ -268,4 +318,9 @@
return taskInfo;
}
+
+ private static boolean hasNoInputChannelFeature(RelayoutParams params) {
+ return (params.mInputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL)
+ != 0;
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
index a9f4492..48ac1e5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
@@ -197,7 +197,7 @@
rectAfterEnd.top += 20
rectAfterEnd.bottom += 20
- verify(mockDesktopWindowDecoration, never()).createResizeVeil()
+ verify(mockDesktopWindowDecoration, never()).showResizeVeil(any())
verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
return@argThat wct.changes.any { (token, change) ->
diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp
index a8e8547..0f29613 100644
--- a/libs/hwui/renderthread/VulkanSurface.cpp
+++ b/libs/hwui/renderthread/VulkanSurface.cpp
@@ -322,11 +322,16 @@
return false;
}
- err = native_window_set_buffer_count(window, windowInfo.bufferCount);
- if (err != 0) {
- ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s (%d)",
- windowInfo.bufferCount, strerror(-err), err);
- return false;
+ // If bufferCount == 1 then we're in shared buffer mode and we cannot actually call
+ // set_buffer_count, it'll just fail.
+ if (windowInfo.bufferCount > 1) {
+ err = native_window_set_buffer_count(window, windowInfo.bufferCount);
+ if (err != 0) {
+ ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s "
+ "(%d)",
+ windowInfo.bufferCount, strerror(-err), err);
+ return false;
+ }
}
err = native_window_set_usage(window, windowInfo.windowUsageFlags);
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index ffd6e16..554fe5e 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -1005,7 +1005,6 @@
* RoutingController#wasTransferInitiatedBySelf()}.
* @hide
*/
- @FlaggedApi(FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES)
public void transfer(
@NonNull RoutingController controller,
@NonNull MediaRoute2Info route,
diff --git a/nfc/jarjar-rules.txt b/nfc/jarjar-rules.txt
index 99ae144..63a6a58 100644
--- a/nfc/jarjar-rules.txt
+++ b/nfc/jarjar-rules.txt
@@ -27,9 +27,8 @@
rule android.os.PersistableBundleProto* com.android.nfc.x.@0
# Used by framework-nfc for reading trunk stable flags
-rule android.nfc.FakeFeatureFlagsImpl* com.android.nfc.x.@0
-rule android.nfc.FeatureFlags* com.android.nfc.x.@0
-rule android.nfc.Flags* com.android.nfc.x.@0
+rule android.nfc.*Flags* com.android.nfc.x.@0
+rule android.nfc.Flags com.android.nfc.x.@0
rule android.permission.flags.** com.android.nfc.x.@0
# Used by framework-nfc for misc utilities
diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java
index f03fc0a..0e40db6 100644
--- a/nfc/java/android/nfc/NfcActivityManager.java
+++ b/nfc/java/android/nfc/NfcActivityManager.java
@@ -195,16 +195,25 @@
Bundle extras) {
boolean isResumed;
Binder token;
+ int pollTech, listenTech;
synchronized (NfcActivityManager.this) {
NfcActivityState state = getActivityState(activity);
state.readerCallback = callback;
state.readerModeFlags = flags;
state.readerModeExtras = extras;
+ pollTech = state.mPollTech;
+ listenTech = state.mListenTech;
token = state.token;
isResumed = state.resumed;
}
if (isResumed) {
- setReaderMode(token, flags, extras);
+ if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
+ || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
+ throw new IllegalStateException(
+ "Cannot be used when alternative DiscoveryTechnology is set");
+ } else {
+ setReaderMode(token, flags, extras);
+ }
}
}
@@ -385,15 +394,12 @@
boolean readerModeFlagsSet;
synchronized (NfcActivityManager.this) {
NfcActivityState state = getActivityState(activity);
- readerModeFlagsSet = state.readerModeFlags != 0;
state.mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
state.mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
token = state.token;
isResumed = state.resumed;
}
- if (readerModeFlagsSet) {
- disableReaderMode(activity);
- } else if (isResumed) {
+ if (isResumed) {
changeDiscoveryTech(token, NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 25fecac..e43d104 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -1880,10 +1880,7 @@
throw new UnsupportedOperationException();
}
}
- mNfcActivityManager.enableReaderMode(activity, null, pollTechnology, null);
- return;
- }
- if (pollTechnology == FLAG_READER_DISABLE) {
+ } else if (pollTechnology == FLAG_READER_DISABLE) {
synchronized (sLock) {
if (!sHasCeFeature) {
throw new UnsupportedOperationException();
diff --git a/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml
index c2d452db..8d44d9c 100644
--- a/packages/CredentialManager/res/values-bs/strings.xml
+++ b/packages/CredentialManager/res/values-bs/strings.xml
@@ -48,7 +48,7 @@
<string name="passwords" msgid="5419394230391253816">"lozinke"</string>
<string name="sign_ins" msgid="4710739369149469208">"prijave"</string>
<string name="sign_in_info" msgid="2627704710674232328">"informacije o prijavi"</string>
- <string name="save_credential_to_title" msgid="3172811692275634301">"Sačuvaj <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> na"</string>
+ <string name="save_credential_to_title" msgid="3172811692275634301">"Sačuvaj vrstu akreditiva \"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>\" na"</string>
<string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Kreirati pristupni ključ na drugom uređaju?"</string>
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Sačuvati lozinku na drugom uređaju?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Sačuvati akreditive za prijavu na drugom uređaju?"</string>
diff --git a/packages/CredentialManager/res/values-ca/strings.xml b/packages/CredentialManager/res/values-ca/strings.xml
index 32405a4..95b6c29 100644
--- a/packages/CredentialManager/res/values-ca/strings.xml
+++ b/packages/CredentialManager/res/values-ca/strings.xml
@@ -20,7 +20,7 @@
<string name="app_name" msgid="4539824758261855508">"Gestor de credencials"</string>
<string name="string_cancel" msgid="6369133483981306063">"Cancel·la"</string>
<string name="string_continue" msgid="1346732695941131882">"Continua"</string>
- <string name="string_more_options" msgid="2763852250269945472">"Desa diferent"</string>
+ <string name="string_more_options" msgid="2763852250269945472">"Desa d\'altra forma"</string>
<string name="string_learn_more" msgid="4541600451688392447">"Més informació"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Mostra la contrasenya"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Amaga la contrasenya"</string>
@@ -74,7 +74,7 @@
<string name="get_dialog_description_single_tap" msgid="2797059565126030879">"Utilitza el bloqueig de pantalla per iniciar la sessió a <xliff:g id="APP_NAME">%1$s</xliff:g> amb <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
<string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"Desbloqueja les opcions d\'inici de sessió per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Tria una clau d\'accés desada per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Tria una clau d\'accés desada per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Tria una contrasenya desada per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Tria un inici de sessió desat per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_sign_in_for" msgid="645728947702442421">"Selecciona un compte per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"Vols triar una opció per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
diff --git a/packages/CredentialManager/res/values-de/strings.xml b/packages/CredentialManager/res/values-de/strings.xml
index ccff535..115f544 100644
--- a/packages/CredentialManager/res/values-de/strings.xml
+++ b/packages/CredentialManager/res/values-de/strings.xml
@@ -48,7 +48,7 @@
<string name="passwords" msgid="5419394230391253816">"Passwörter"</string>
<string name="sign_ins" msgid="4710739369149469208">"Anmeldungen"</string>
<string name="sign_in_info" msgid="2627704710674232328">"Anmeldedaten"</string>
- <string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> speichern unter"</string>
+ <string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> speichern in"</string>
<string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Passkey auf einem anderen Gerät erstellen?"</string>
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Passwort auf einem anderen Gerät speichern?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Anmeldedaten auf einem anderen Gerät speichern?"</string>
@@ -74,7 +74,7 @@
<string name="get_dialog_description_single_tap" msgid="2797059565126030879">"Du kannst die Displaysperre verwenden, um dich in <xliff:g id="APP_NAME">%1$s</xliff:g> als <xliff:g id="USERNAME">%2$s</xliff:g> anzumelden"</string>
<string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"Anmeldeoptionen für <xliff:g id="APP_NAME">%1$s</xliff:g> freischalten"</string>
<string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Einen gespeicherten Passkey für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
- <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Ein gespeichertes Passwort für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
+ <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Gespeichertes Passwort für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
<string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Gespeicherte Anmeldedaten für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
<string name="get_dialog_title_choose_sign_in_for" msgid="645728947702442421">"Konto für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
<string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"Option für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen?"</string>
diff --git a/packages/CredentialManager/res/values-fr/strings.xml b/packages/CredentialManager/res/values-fr/strings.xml
index c406857..b239fc3 100644
--- a/packages/CredentialManager/res/values-fr/strings.xml
+++ b/packages/CredentialManager/res/values-fr/strings.xml
@@ -20,7 +20,7 @@
<string name="app_name" msgid="4539824758261855508">"Gestionnaire d\'identifiants"</string>
<string name="string_cancel" msgid="6369133483981306063">"Annuler"</string>
<string name="string_continue" msgid="1346732695941131882">"Continuer"</string>
- <string name="string_more_options" msgid="2763852250269945472">"Sauver autrement"</string>
+ <string name="string_more_options" msgid="2763852250269945472">"Autre façon"</string>
<string name="string_learn_more" msgid="4541600451688392447">"En savoir plus"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Afficher le mot de passe"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Masquer le mot de passe"</string>
diff --git a/packages/CredentialManager/res/values-ko/strings.xml b/packages/CredentialManager/res/values-ko/strings.xml
index 468f4e7..7067a40 100644
--- a/packages/CredentialManager/res/values-ko/strings.xml
+++ b/packages/CredentialManager/res/values-ko/strings.xml
@@ -89,7 +89,7 @@
<string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"탭하여 잠금 해제"</string>
<string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"로그인 정보 없음"</string>
<string name="no_sign_in_info_in" msgid="2641118151920288356">"<xliff:g id="SOURCE">%1$s</xliff:g>의 로그인 정보 없음"</string>
- <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"로그인 관리"</string>
+ <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"로그인 정보 관리"</string>
<string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"다른 기기에서"</string>
<string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"다른 기기 사용"</string>
<string name="request_cancelled_by" msgid="3735222326886267820">"<xliff:g id="APP_NAME">%1$s</xliff:g>에 의해 요청이 취소됨"</string>
diff --git a/packages/CredentialManager/res/values-my/strings.xml b/packages/CredentialManager/res/values-my/strings.xml
index 2f6086a..e0def18 100644
--- a/packages/CredentialManager/res/values-my/strings.xml
+++ b/packages/CredentialManager/res/values-my/strings.xml
@@ -20,7 +20,7 @@
<string name="app_name" msgid="4539824758261855508">"အထောက်အထားမန်နေဂျာ"</string>
<string name="string_cancel" msgid="6369133483981306063">"မလုပ်တော့"</string>
<string name="string_continue" msgid="1346732695941131882">"ရှေ့ဆက်ရန်"</string>
- <string name="string_more_options" msgid="2763852250269945472">"အခြားနည်း သိမ်းရန်"</string>
+ <string name="string_more_options" msgid="2763852250269945472">"အခြားနည်းသုံးရန်"</string>
<string name="string_learn_more" msgid="4541600451688392447">"ပိုမိုလေ့လာရန်"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"စကားဝှက်ကို ပြရန်"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"စကားဝှက်ကို ဖျောက်ရန်"</string>
diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml
index 336b29f..e3a9191 100644
--- a/packages/CredentialManager/res/values-or/strings.xml
+++ b/packages/CredentialManager/res/values-or/strings.xml
@@ -20,7 +20,7 @@
<string name="app_name" msgid="4539824758261855508">"କ୍ରେଡେନସିଆଲ ମେନେଜର"</string>
<string name="string_cancel" msgid="6369133483981306063">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="string_continue" msgid="1346732695941131882">"ଜାରି ରଖନ୍ତୁ"</string>
- <string name="string_more_options" msgid="2763852250269945472">"ଅନ୍ୟ ଉପାୟରେ ସେଭ କର"</string>
+ <string name="string_more_options" msgid="2763852250269945472">"ଅନ୍ୟ ଭାବେ ସେଭ କରନ୍ତୁ"</string>
<string name="string_learn_more" msgid="4541600451688392447">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"ପାସୱାର୍ଡ ଦେଖାନ୍ତୁ"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"ପାସୱାର୍ଡ ଲୁଚାନ୍ତୁ"</string>
diff --git a/packages/CredentialManager/res/values-pt-rPT/strings.xml b/packages/CredentialManager/res/values-pt-rPT/strings.xml
index 2204e02..a3476d9 100644
--- a/packages/CredentialManager/res/values-pt-rPT/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rPT/strings.xml
@@ -20,7 +20,7 @@
<string name="app_name" msgid="4539824758261855508">"Credential Manager"</string>
<string name="string_cancel" msgid="6369133483981306063">"Cancelar"</string>
<string name="string_continue" msgid="1346732695941131882">"Continuar"</string>
- <string name="string_more_options" msgid="2763852250269945472">"Guardar outra forma"</string>
+ <string name="string_more_options" msgid="2763852250269945472">"Guardar de outra forma"</string>
<string name="string_learn_more" msgid="4541600451688392447">"Saber mais"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Mostrar palavra-passe"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Ocultar palavra-passe"</string>
diff --git a/packages/CredentialManager/res/values-ru/strings.xml b/packages/CredentialManager/res/values-ru/strings.xml
index ec2a2d6..936ff79 100644
--- a/packages/CredentialManager/res/values-ru/strings.xml
+++ b/packages/CredentialManager/res/values-ru/strings.xml
@@ -20,7 +20,7 @@
<string name="app_name" msgid="4539824758261855508">"Менеджер учетных данных"</string>
<string name="string_cancel" msgid="6369133483981306063">"Отмена"</string>
<string name="string_continue" msgid="1346732695941131882">"Продолжить"</string>
- <string name="string_more_options" msgid="2763852250269945472">"Сохранить"</string>
+ <string name="string_more_options" msgid="2763852250269945472">"Другой способ"</string>
<string name="string_learn_more" msgid="4541600451688392447">"Подробнее"</string>
<string name="content_description_show_password" msgid="3283502010388521607">"Показать пароль"</string>
<string name="content_description_hide_password" msgid="6841375971631767996">"Скрыть пароль"</string>
diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml
index 8dc0fc2..d943979 100644
--- a/packages/CredentialManager/res/values-sq/strings.xml
+++ b/packages/CredentialManager/res/values-sq/strings.xml
@@ -48,7 +48,7 @@
<string name="passwords" msgid="5419394230391253816">"fjalëkalime"</string>
<string name="sign_ins" msgid="4710739369149469208">"identifikimet"</string>
<string name="sign_in_info" msgid="2627704710674232328">"informacionet e identifikimit"</string>
- <string name="save_credential_to_title" msgid="3172811692275634301">"Ruaj <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> te"</string>
+ <string name="save_credential_to_title" msgid="3172811692275634301">"Të ruhet <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> te"</string>
<string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Të krijohet çelësi i kalimit në një pajisje tjetër?"</string>
<string name="save_password_on_other_device_title" msgid="5829084591948321207">"Të ruhet fjalëkalimi në një pajisje tjetër?"</string>
<string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Të ruhet identifikimi në një pajisje tjetër?"</string>
diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml
index 3c9c3b7..b423b2c 100644
--- a/packages/CredentialManager/res/values-tr/strings.xml
+++ b/packages/CredentialManager/res/values-tr/strings.xml
@@ -74,7 +74,7 @@
<string name="get_dialog_description_single_tap" msgid="2797059565126030879">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında <xliff:g id="USERNAME">%2$s</xliff:g> hesabıyla oturum açmak için ekran kilidinizi kullanın"</string>
<string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"<xliff:g id="APP_NAME">%1$s</xliff:g> için oturum açma seçeneklerinin kilidini açın"</string>
<string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı bir geçiş anahtarı kullanın"</string>
- <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı bir şifre kullanın"</string>
+ <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı bir şifre seçin"</string>
<string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı oturum açma bilgilerini kullanın"</string>
<string name="get_dialog_title_choose_sign_in_for" msgid="645728947702442421">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması için bir hesap seçin"</string>
<string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"<xliff:g id="APP_NAME">%1$s</xliff:g> için bir seçim yapmak ister misiniz?"</string>
diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml
index a3f79ca..cd5b7bb 100644
--- a/packages/CredentialManager/res/values-uk/strings.xml
+++ b/packages/CredentialManager/res/values-uk/strings.xml
@@ -82,7 +82,7 @@
<string name="get_dialog_use_saved_passkey_for" msgid="4618100798664888512">"Увійти іншим способом"</string>
<string name="snackbar_action" msgid="37373514216505085">"Переглянути варіанти"</string>
<string name="get_dialog_button_label_continue" msgid="6446201694794283870">"Продовжити"</string>
- <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Опції входу"</string>
+ <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Способи входу"</string>
<string name="button_label_view_more" msgid="3429098227286495651">"Переглянути більше"</string>
<string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Для користувача <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
<string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Заблоковані менеджери паролів"</string>
diff --git a/packages/CredentialManager/res/values-zh-rTW/strings.xml b/packages/CredentialManager/res/values-zh-rTW/strings.xml
index d5f3093..6b22e36 100644
--- a/packages/CredentialManager/res/values-zh-rTW/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rTW/strings.xml
@@ -40,7 +40,7 @@
<string name="choose_provider_title" msgid="8870795677024868108">"選擇要將<xliff:g id="CREATETYPES">%1$s</xliff:g>存在哪裡"</string>
<string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具並儲存資訊,下次就能更快登入"</string>
<string name="choose_create_option_passkey_title" msgid="8762295821604276511">"要建立用於登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼金鑰嗎?"</string>
- <string name="choose_create_option_password_title" msgid="4481366993598649224">"要儲存用於登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼嗎?"</string>
+ <string name="choose_create_option_password_title" msgid="4481366993598649224">"要儲存登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼嗎?"</string>
<string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"要儲存「<xliff:g id="APP_NAME">%1$s</xliff:g>」的登入資訊嗎?"</string>
<string name="passkey" msgid="632353688396759522">"密碼金鑰"</string>
<string name="password" msgid="6738570945182936667">"密碼"</string>
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index a2f55cd..8cde454 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -125,6 +125,7 @@
return Triple(true, false, null)
}
val shouldShowCancellationUi = cancelUiRequest.shouldShowCancellationExplanation()
+ viewModel?.onDeveloperCancellationReceivedForBiometricPrompt()
Log.d(
Constants.LOG_TAG, "Received UI cancellation intent. Should show cancellation" +
" ui = $shouldShowCancellationUi")
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index 7bc3241..d4a8110 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -19,6 +19,7 @@
import android.app.Activity
import android.hardware.biometrics.BiometricPrompt
import android.hardware.biometrics.BiometricPrompt.AuthenticationResult
+import android.os.CancellationSignal
import android.os.IBinder
import android.text.TextUtils
import android.util.Log
@@ -232,8 +233,13 @@
authResult: BiometricPrompt.AuthenticationResult? = null,
authError: BiometricError? = null,
) {
- Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
- ", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
+ if (authError == null) {
+ Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
+ ", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
+ } else {
+ Log.d(Constants.LOG_TAG, "Biometric flow error: ${authError.errorCode} " +
+ "propagating to provider, message: ${authError.errorMessage}.")
+ }
uiState = if (entry.pendingIntent != null) {
uiState.copy(
selectedEntry = entry,
@@ -385,9 +391,15 @@
val providerId = selectedEntry.providerId
val entryKey = selectedEntry.entryKey
val entrySubkey = selectedEntry.entrySubkey
- Log.d(
- Constants.LOG_TAG, "Option selected for entry: " +
- " {provider=$providerId, key=$entryKey, subkey=$entrySubkey")
+ if (authError == null) {
+ Log.d(
+ Constants.LOG_TAG, "Option selected for entry: " +
+ " {provider=$providerId, key=$entryKey, subkey=$entrySubkey"
+ )
+ } else {
+ Log.d(Constants.LOG_TAG, "Biometric flow error: ${authError.errorCode} " +
+ "propagating to provider, message: ${authError.errorMessage}.")
+ }
if (selectedEntry.pendingIntent != null) {
uiState = uiState.copy(
selectedEntry = selectedEntry,
@@ -424,6 +436,33 @@
/**************************************************************************/
/**
+ * Cancels the biometric prompt's cancellation signal. Should only be called when the credential
+ * manager ui receives a developer cancellation signal. If the prompt is already done, we do
+ * not allow a cancellation, given the UI cancellation will be caught by the backend. We also
+ * set the biometricStatus to CANCELED, so that only in this case, we do *not* propagate the
+ * ERROR_CANCELED when a developer cancellation signal is the root cause.
+ */
+ fun onDeveloperCancellationReceivedForBiometricPrompt() {
+ val biometricCancellationSignal = uiState.biometricState.biometricCancellationSignal
+ if (!biometricCancellationSignal.isCanceled && uiState.biometricState.biometricStatus
+ != BiometricPromptState.COMPLETE) {
+ uiState = uiState.copy(
+ biometricState = uiState.biometricState.copy(
+ biometricStatus = BiometricPromptState.CANCELED
+ )
+ )
+ biometricCancellationSignal.cancel()
+ }
+ }
+
+ /**
+ * Retrieve the biometric prompt's cancellation signal (e.g. to pass into the 'authenticate'
+ * API).
+ */
+ fun getBiometricCancellationSignal(): CancellationSignal =
+ uiState.biometricState.biometricCancellationSignal
+
+ /**
* This allows falling back from the biometric prompt screen to the normal get flow by applying
* a reset to all necessary states involved in the fallback.
*/
@@ -450,9 +489,9 @@
}
/**
- * This returns the present biometric state.
+ * This returns the present biometric prompt state's status.
*/
- fun getBiometricPromptState(): BiometricPromptState =
+ fun getBiometricPromptStateStatus(): BiometricPromptState =
uiState.biometricState.biometricStatus
/**************************************************************************/
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
index 0d19a45..b43b5f3 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
@@ -65,7 +65,6 @@
* ).
*
* The above are examples; the credential type can change depending on scenario.
- * // TODO(b/333445112) : Finalize once all the strings and create flow is iterated to completion
*/
data class BiometricDisplayInfo(
val providerIcon: Bitmap,
@@ -84,7 +83,8 @@
data class BiometricState(
val biometricResult: BiometricResult? = null,
val biometricError: BiometricError? = null,
- val biometricStatus: BiometricPromptState = BiometricPromptState.INACTIVE
+ val biometricStatus: BiometricPromptState = BiometricPromptState.INACTIVE,
+ val biometricCancellationSignal: CancellationSignal = CancellationSignal(),
)
/**
@@ -118,6 +118,7 @@
getBiometricPromptState: () -> BiometricPromptState,
onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
onBiometricFailureFallback: (BiometricFlowType) -> Unit,
+ getBiometricCancellationSignal: () -> CancellationSignal,
getRequestDisplayInfo: RequestDisplayInfo? = null,
getProviderInfoList: List<ProviderInfo>? = null,
getProviderDisplayInfo: ProviderDisplayInfo? = null,
@@ -141,11 +142,13 @@
val callback: BiometricPrompt.AuthenticationCallback =
setupBiometricAuthenticationCallback(sendDataToProvider, biometricEntry,
- onCancelFlowAndFinish, onIllegalStateAndFinish, onBiometricPromptStateChange)
+ onCancelFlowAndFinish, onIllegalStateAndFinish, onBiometricPromptStateChange,
+ getBiometricPromptState)
- Log.d(TAG, "The BiometricPrompt API call begins.")
+ Log.d(TAG, "The BiometricPrompt API call begins for Get.")
runBiometricFlow(context, biometricDisplayInfo, callback, openMoreOptionsPage,
- onBiometricFailureFallback, BiometricFlowType.GET, onCancelFlowAndFinish)
+ onBiometricFailureFallback, BiometricFlowType.GET, onCancelFlowAndFinish,
+ getBiometricCancellationSignal)
}
/**
@@ -163,6 +166,7 @@
getBiometricPromptState: () -> BiometricPromptState,
onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
onBiometricFailureFallback: (BiometricFlowType) -> Unit,
+ getBiometricCancellationSignal: () -> CancellationSignal,
createRequestDisplayInfo: com.android.credentialmanager.createflow
.RequestDisplayInfo? = null,
createProviderInfo: EnabledProviderInfo? = null,
@@ -185,11 +189,13 @@
val callback: BiometricPrompt.AuthenticationCallback =
setupBiometricAuthenticationCallback(sendDataToProvider, biometricEntry,
- onCancelFlowAndFinish, onIllegalStateAndFinish, onBiometricPromptStateChange)
+ onCancelFlowAndFinish, onIllegalStateAndFinish, onBiometricPromptStateChange,
+ getBiometricPromptState)
- Log.d(TAG, "The BiometricPrompt API call begins.")
+ Log.d(TAG, "The BiometricPrompt API call begins for Create.")
runBiometricFlow(context, biometricDisplayInfo, callback, openMoreOptionsPage,
- onBiometricFailureFallback, BiometricFlowType.CREATE, onCancelFlowAndFinish)
+ onBiometricFailureFallback, BiometricFlowType.CREATE, onCancelFlowAndFinish,
+ getBiometricCancellationSignal)
}
/**
@@ -206,7 +212,8 @@
openMoreOptionsPage: () -> Unit,
onBiometricFailureFallback: (BiometricFlowType) -> Unit,
biometricFlowType: BiometricFlowType,
- onCancelFlowAndFinish: () -> Unit
+ onCancelFlowAndFinish: () -> Unit,
+ getBiometricCancellationSignal: () -> CancellationSignal,
) {
try {
if (!canCallBiometricPrompt(biometricDisplayInfo, context)) {
@@ -217,12 +224,7 @@
val biometricPrompt = setupBiometricPrompt(context, biometricDisplayInfo,
openMoreOptionsPage, biometricDisplayInfo.biometricRequestInfo, onCancelFlowAndFinish)
- val cancellationSignal = CancellationSignal()
- cancellationSignal.setOnCancelListener {
- Log.d(TAG, "Your cancellation signal was called.")
- // TODO(b/333445112) : Migrate towards passing along the developer cancellation signal
- // or validate the necessity for this
- }
+ val cancellationSignal = getBiometricCancellationSignal()
val executor = getMainExecutor(context)
@@ -251,8 +253,6 @@
* Note that if device credential is the only available modality but not requested, or if none
* of the requested modalities are available, we fallback to the normal flow to ensure a selector
* shows up.
- * // TODO(b/334197980) : While we already fallback in cases the selector doesn't show, confirm
- * // final plan.
*/
private fun canCallBiometricPrompt(
biometricDisplayInfo: BiometricDisplayInfo,
@@ -270,12 +270,12 @@
return false
}
- if (ifOnlySupportsAtMostDeviceCredentials(biometricManager)) return false
+ if (onlySupportsAtMostDeviceCredentials(biometricManager)) return false
return true
}
-private fun ifOnlySupportsAtMostDeviceCredentials(biometricManager: BiometricManager): Boolean {
+private fun onlySupportsAtMostDeviceCredentials(biometricManager: BiometricManager): Boolean {
if (biometricManager.canAuthenticate(Authenticators.BIOMETRIC_WEAK) !=
BiometricManager.BIOMETRIC_SUCCESS &&
biometricManager.canAuthenticate(Authenticators.BIOMETRIC_STRONG) !=
@@ -343,11 +343,11 @@
selectedEntry: EntryInfo,
onCancelFlowAndFinish: () -> Unit,
onIllegalStateAndFinish: (String) -> Unit,
- onBiometricPromptStateChange: (BiometricPromptState) -> Unit
+ onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
+ getBiometricPromptState: () -> BiometricPromptState,
): BiometricPrompt.AuthenticationCallback {
val callback: BiometricPrompt.AuthenticationCallback =
object : BiometricPrompt.AuthenticationCallback() {
- // TODO(b/333445772) : Validate remaining callbacks
override fun onAuthenticationSucceeded(
authResult: BiometricPrompt.AuthenticationResult?
) {
@@ -374,6 +374,12 @@
override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) {
super.onAuthenticationError(errorCode, errString)
Log.d(TAG, "Authentication error-ed out: $errorCode and $errString")
+ if (getBiometricPromptState() == BiometricPromptState.CANCELED && errorCode
+ == BiometricPrompt.BIOMETRIC_ERROR_CANCELED) {
+ Log.d(TAG, "Developer cancellation signal received. Nothing more to do.")
+ // This unique edge case means a developer cancellation signal was sent.
+ return
+ }
onBiometricPromptStateChange(BiometricPromptState.COMPLETE)
if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED) {
// Note that because the biometric prompt is imbued directly
@@ -471,8 +477,7 @@
val singleEntryType = selectedEntry.credentialType
val username = selectedEntry.userName
- // TODO(b/330396140) : Finalize localization and parsing for specific sign in option flows
- // (fingerprint, face, etc...))
+ // TODO(b/336362538) : In W, utilize updated localization strings
displayTitleText = context.getString(
generateDisplayTitleTextResCode(singleEntryType),
getRequestDisplayInfo.appName
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricPromptState.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricPromptState.kt
index e1aa041..eb77937 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricPromptState.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricPromptState.kt
@@ -22,5 +22,10 @@
/** The biometric prompt is active but data hasn't been returned yet. */
PENDING,
/** The biometric prompt has closed and returned data we then send to the provider activity. */
- COMPLETE
+ COMPLETE,
+ /**
+ * The biometric prompt has been canceled by a developer signal. If this is true, certain
+ * conditions can be triggered, such as no longer propagating ERROR_CANCELED.
+ */
+ CANCELED,
}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index 282a1b5..7d61f73 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -18,6 +18,7 @@
import android.credentials.flags.Flags.selectorUiImprovementsEnabled
import android.hardware.biometrics.BiometricPrompt
+import android.os.CancellationSignal
import android.text.TextUtils
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.result.ActivityResult
@@ -118,9 +119,11 @@
fallbackToOriginalFlow =
viewModel::fallbackFromBiometricToNormalFlow,
getBiometricPromptState =
- viewModel::getBiometricPromptState,
+ viewModel::getBiometricPromptStateStatus,
onBiometricPromptStateChange =
- viewModel::onBiometricPromptStateChange
+ viewModel::onBiometricPromptStateChange,
+ getBiometricCancellationSignal =
+ viewModel::getBiometricCancellationSignal
)
CreateScreenState.MORE_OPTIONS_SELECTION_ONLY -> MoreOptionsSelectionCard(
requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
@@ -638,6 +641,7 @@
fallbackToOriginalFlow: (BiometricFlowType) -> Unit,
getBiometricPromptState: () -> BiometricPromptState,
onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
+ getBiometricCancellationSignal: () -> CancellationSignal,
) {
if (biometricEntry == null) {
fallbackToOriginalFlow(BiometricFlowType.CREATE)
@@ -655,5 +659,6 @@
createProviderInfo = enabledProviderInfo,
onBiometricFailureFallback = fallbackToOriginalFlow,
onIllegalStateAndFinish = onIllegalScreenStateAndFinish,
+ getBiometricCancellationSignal = getBiometricCancellationSignal,
)
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index c98bb5e..ba61b90 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -20,6 +20,7 @@
import android.credentials.flags.Flags.selectorUiImprovementsEnabled
import android.graphics.drawable.Drawable
import android.hardware.biometrics.BiometricPrompt
+import android.os.CancellationSignal
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.result.ActivityResult
import androidx.activity.result.IntentSenderRequest
@@ -161,9 +162,11 @@
fallbackToOriginalFlow =
viewModel::fallbackFromBiometricToNormalFlow,
getBiometricPromptState =
- viewModel::getBiometricPromptState,
+ viewModel::getBiometricPromptStateStatus,
onBiometricPromptStateChange =
- viewModel::onBiometricPromptStateChange
+ viewModel::onBiometricPromptStateChange,
+ getBiometricCancellationSignal =
+ viewModel::getBiometricCancellationSignal
)
} else if (credmanBiometricApiEnabled() &&
getCredentialUiState.currentScreenState
@@ -256,6 +259,7 @@
fallbackToOriginalFlow: (BiometricFlowType) -> Unit,
getBiometricPromptState: () -> BiometricPromptState,
onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
+ getBiometricCancellationSignal: () -> CancellationSignal,
) {
if (biometricEntry == null) {
fallbackToOriginalFlow(BiometricFlowType.GET)
@@ -273,7 +277,8 @@
getRequestDisplayInfo = requestDisplayInfo,
getProviderInfoList = providerInfoList,
getProviderDisplayInfo = providerDisplayInfo,
- onBiometricFailureFallback = fallbackToOriginalFlow
+ onBiometricFailureFallback = fallbackToOriginalFlow,
+ getBiometricCancellationSignal = getBiometricCancellationSignal
)
}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_thai_pattachote.kcm b/packages/InputDevices/res/raw/keyboard_layout_thai_pattachote.kcm
new file mode 100644
index 0000000..a136aca
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_thai_pattachote.kcm
@@ -0,0 +1,317 @@
+# 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.
+
+#
+# Thai Pattachote keyboard layout.
+#
+
+type OVERLAY
+
+map key 86 PLUS
+
+### ROW 1
+
+key GRAVE {
+ label: '_'
+ base: '_'
+ shift, capslock: '\u0e3f'
+}
+
+key 1 {
+ label: '='
+ base: '='
+ shift, capslock: '+'
+}
+
+key 2 {
+ label: '\u0e52'
+ base: '\u0e52'
+ shift, capslock: '\u0022'
+}
+
+key 3 {
+ label: '\u0e53'
+ base: '\u0e53'
+ shift, capslock: '/'
+}
+
+key 4 {
+ label: '\u0e54'
+ base: '\u0e54'
+ shift, capslock: ','
+}
+
+key 5 {
+ label: '\u0e55'
+ base: '\u0e55'
+ shift, capslock: '?'
+}
+
+key 6 {
+ label: '\u0e39'
+ base: '\u0e39'
+ shift, capslock: '\u0e38'
+}
+
+key 7 {
+ label: '\u0e57'
+ base: '\u0e57'
+ shift, capslock: '_'
+}
+
+key 8 {
+ label: '\u0e58'
+ base: '\u0e58'
+ shift, capslock: '.'
+}
+
+key 9 {
+ label: '\u0e59'
+ base: '\u0e59'
+ shift, capslock: '('
+}
+
+key 0 {
+ label: '\u0e50'
+ base: '\u0e50'
+ shift, capslock: ')'
+}
+
+key MINUS {
+ label: '\u0e51'
+ base: '\u0e51'
+ shift, capslock: '-'
+}
+
+key EQUALS {
+ label: '\u0e56'
+ base: '\u0e56'
+ shift, capslock: '%'
+}
+
+### ROW 2
+
+key Q {
+ label: '\u0e47'
+ base: '\u0e47'
+ shift, capslock: '\u0e4a'
+}
+
+key W {
+ label: '\u0e15'
+ base: '\u0e15'
+ shift, capslock: '\u0e24'
+}
+
+key E {
+ label: '\u0e22'
+ base: '\u0e22'
+ shift, capslock: '\u0e46'
+}
+
+key R {
+ label: '\u0e2d'
+ base: '\u0e2d'
+ shift, capslock: '\u0e0d'
+}
+
+key T {
+ label: '\u0e23'
+ base: '\u0e23'
+ shift, capslock: '\u0e29'
+}
+
+key Y {
+ label: '\u0e48'
+ base: '\u0e48'
+ shift, capslock: '\u0e36'
+}
+
+key U {
+ label: '\u0e14'
+ base: '\u0e14'
+ shift, capslock: '\u0e1d'
+}
+
+key I {
+ label: '\u0e21'
+ base: '\u0e21'
+ shift, capslock: '\u0e0b'
+}
+
+key O {
+ label: '\u0e27'
+ base: '\u0e27'
+ shift, capslock: '\u0e16'
+}
+
+key P {
+ label: '\u0e41'
+ base: '\u0e41'
+ shift, capslock: '\u0e12'
+}
+
+key LEFT_BRACKET {
+ label: '\u0e43'
+ base: '\u0e43'
+ shift, capslock: '\u0e2f'
+}
+
+key RIGHT_BRACKET {
+ label: '\u0e0c'
+ base: '\u0e0c'
+ shift, capslock: '\u0e26'
+}
+
+### ROW 3
+
+key A {
+ label: '\u0e49'
+ base: '\u0e49'
+ shift, capslock: '\u0e4b'
+}
+
+key S {
+ label: '\u0e17'
+ base: '\u0e17'
+ shift, capslock: '\u0e18'
+}
+
+key D {
+ label: '\u0e07'
+ base: '\u0e07'
+ shift, capslock: '\u0e33'
+}
+
+key F {
+ label: '\u0e01'
+ base: '\u0e01'
+ shift, capslock: '\u0e13'
+}
+
+key G {
+ label: '\u0e31'
+ base: '\u0e31'
+ shift, capslock: '\u0e4c'
+}
+
+key H {
+ label: '\u0e35'
+ base: '\u0e35'
+ shift, capslock: '\u0e37'
+}
+
+key J {
+ label: '\u0e32'
+ base: '\u0e32'
+ shift, capslock: '\u0e1c'
+}
+
+key K {
+ label: '\u0e19'
+ base: '\u0e19'
+ shift, capslock: '\u0e0a'
+}
+
+key L {
+ label: '\u0e40'
+ base: '\u0e40'
+ shift, capslock: '\u0e42'
+}
+
+key SEMICOLON {
+ label: '\u0e44'
+ base: '\u0e44'
+ shift, capslock: '\u0e06'
+}
+
+key APOSTROPHE {
+ label: '\u0e02'
+ base: '\u0e02'
+ shift, capslock: '\u0e11'
+}
+
+key BACKSLASH {
+ label: '\u0e45'
+ base: '\u0e45'
+ shift, capslock: '\u0e4d'
+}
+
+### ROW 4
+
+key PLUS {
+ label: '\u0e45'
+ base: '\u0e45'
+ shift, capslock: '\u0e4d'
+}
+
+key Z {
+ label: '\u0e1a'
+ base: '\u0e1a'
+ shift, capslock: '\u0e0e'
+}
+
+key X {
+ label: '\u0e1b'
+ base: '\u0e1b'
+ shift, capslock: '\u0e0f'
+}
+
+key C {
+ label: '\u0e25'
+ base: '\u0e25'
+ shift, capslock: '\u0e10'
+}
+
+key V {
+ label: '\u0e2b'
+ base: '\u0e2b'
+ shift, capslock: '\u0e20'
+}
+
+key B {
+ label: '\u0e34'
+ base: '\u0e34'
+ shift, capslock: '\u0e31'
+}
+
+key N {
+ label: '\u0e04'
+ base: '\u0e04'
+ shift, capslock: '\u0e28'
+}
+
+key M {
+ label: '\u0e2a'
+ base: '\u0e2a'
+ shift, capslock: '\u0e2e'
+}
+
+key COMMA {
+ label: '\u0e30'
+ base: '\u0e30'
+ shift, capslock: '\u0e1f'
+}
+
+key PERIOD {
+ label: '\u0e08'
+ base: '\u0e08'
+ shift, capslock: '\u0e09'
+}
+
+key SLASH {
+ label: '\u0e1e'
+ base: '\u0e1e'
+ shift, capslock: '\u0e2c'
+}
\ No newline at end of file
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
index 33a1d76..e10bd7f 100644
--- a/packages/InputDevices/res/values/strings.xml
+++ b/packages/InputDevices/res/values/strings.xml
@@ -149,4 +149,7 @@
<!-- Thai (Kedmanee variant) keyboard layout label. [CHAR LIMIT=35] -->
<string name="keyboard_layout_thai_kedmanee">Thai (Kedmanee)</string>
+
+ <!-- Thai (Pattachote variant) keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_thai_pattachote">Thai (Pattachote)</string>
</resources>
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index 4b7ea90..c18d73c 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -325,4 +325,11 @@
android:keyboardLayout="@raw/keyboard_layout_thai_kedmanee"
android:keyboardLocale="th-Thai"
android:keyboardLayoutType="extended" />
+
+ <keyboard-layout
+ android:name="keyboard_layout_thai_pattachote"
+ android:label="@string/keyboard_layout_thai_pattachote"
+ android:keyboardLayout="@raw/keyboard_layout_thai_pattachote"
+ android:keyboardLocale="th-Thai"
+ android:keyboardLayoutType="extended" />
</keyboard-layouts>
diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
index c39956d..a0a1eb9 100644
--- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
@@ -99,7 +99,7 @@
<string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"Para sua segurança, o relógio não está atualmente autorizado a instalar apps desconhecidas a partir desta origem. Pode alterar esta opção nas Definições."</string>
<string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Para sua segurança, o telemóvel não está atualmente autorizado a instalar apps desconhecidas a partir desta origem. Pode alterar esta opção nas Definições."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"O seu telemóvel e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta app, concorda que é responsável por quaisquer danos causados ao telemóvel ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
- <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"O seu tablet e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta app, concorda que é responsável por quaisquer danos causados ao tablet ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"O seu tablet e os dados pessoais estão mais vulneráveis a ataques por parte de apps desconhecidas. Ao instalar esta app, concorda que é responsável por quaisquer danos causados ao tablet ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"A sua TV e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta app, concorda que é responsável por quaisquer danos causados à TV ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
<string name="cloned_app_label" msgid="7503612829833756160">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="archiving_app_label" msgid="1127085259724124725">"Arquivar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>?"</string>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index f9800b3..9641204 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -94,41 +94,32 @@
<string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Gekoppel (geen foon nie), battery <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">"Gekoppel (geen media nie), battery <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">"Gekoppel (geen foon of media nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
- <!-- no translation found for bluetooth_active_battery_level (2685517576209066008) -->
+ <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"Aktief. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+ <string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"Aktief. L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
- <skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
- <skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batterykrag"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
- <!-- no translation found for bluetooth_battery_level_untethered (1616774716076301755) -->
- <skip />
- <!-- no translation found for bluetooth_battery_level_untethered_left (5725764679536058365) -->
- <skip />
- <!-- no translation found for bluetooth_battery_level_untethered_right (8377995536997790142) -->
- <skip />
+ <string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+ <string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+ <string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Regs: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktief"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Gestoor"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktief, net links"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktief, net regs"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktief, links en regs"</string>
- <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
<skip />
- <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
<skip />
- <!-- no translation found for bluetooth_battery_level_lea_support (5968584103507988820) -->
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
<skip />
- <!-- no translation found for bluetooth_battery_level_untethered_lea_support (803110681688633362) -->
- <skip />
- <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (7707464334346454950) -->
- <skip />
- <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (8941549024377771038) -->
- <skip />
- <!-- no translation found for bluetooth_no_battery_level_lea_support (5721725041048434075) -->
- <skip />
+ <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktief (net media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+ <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiewe (net media). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery"</string>
+ <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Gekoppel (steun oudiodeling). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+ <string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Gekoppel (steun oudiodeling). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+ <string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Gekoppel (steun oudiodeling). Links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+ <string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Gekoppel (steun oudiodeling). Regs: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+ <string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Gekoppel (steun oudiodeling)"</string>
<string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktief (net media)"</string>
<string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Steun oudiodeling"</string>
<string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktief (net media), net linkerkant"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 729ac28..51cf441 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ንቁ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ተቀምጧል"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ገቢር፣ ግራ ብቻ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ገቢር፣ ቀኝ ብቻ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ገቢር፣ ግራ እና ቀኝ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 9f13551..b1a7332 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"مستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"مستوى شحن البطارية: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"نشط"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"محفوظ"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"السمّاعة الطبية اليسرى فقط مفعَّلة"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"السمّاعة الطبية اليمنى فقط مفعَّلة"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"السمّاعتان اليسرى واليمنى مفعَّلتان"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 62c1201..13b639a 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"বেটাৰী <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"সক্ৰিয়"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ছেভ কৰা হৈছে"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"কেৱল বাঁওফালৰটো সক্ৰিয় হৈছে"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"কেৱল সোঁফালৰটো সক্ৰিয় হৈছে"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"বাওঁ আৰু সোঁ দুয়োফালৰ সক্ৰিয় হৈছে"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index b1bbf34..809601e 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batareya: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Yadda saxlandı"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, yalnız sol"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, yalnız sağ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, sol və sağ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 4af26f2..24830b4 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterija, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Sačuvano"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo s leve strane"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, s desne strane"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, s leve i desne strane"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 9998c9e..986c089 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Уключана"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Захавана"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Уключана, толькі для левага вуха"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Уключана, толькі для правага вуха"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Уключана, для левага і правага вуха"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 03065c6..7097078 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активно"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Запазено"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активно – само лявото"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активно – само дясното"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активно – лявото и дясното"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index b69a542..e4637fe 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"চালু আছে"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"সেভ করা আছে"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"শুধুমাত্র বাঁদিকের হিয়ারিং এড অ্যাক্টিভ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"শুধুমাত্র ডানদিকের হিয়ারিং এড অ্যাক্টিভ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"বাঁ ও ডানদিকের হিয়ারিং এড, অ্যাক্টিভ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 2cc6dc5..e71c2ec 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Sačuvano"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo lijevi"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, samo desni"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, lijevi i desni"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 5a4a923..09b4297 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actiu"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Desat"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actiu, només l\'esquerre"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Actiu, només el dret"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Actiu, esquerre i dret"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 9a3ba63..b2d75bd 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterie"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivní"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Uloženo"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivní, pouze levé"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivní, pouze pravé"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivní, levé a pravé"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index c7f1c6e..0f92316 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batteri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Gemt"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, kun venstre"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, kun højre"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, venstre og højre"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index cc962b4..c8d7acd 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akku – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Gespeichert"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, nur links"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, nur rechts"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, links und rechts"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 2ea96a7..2cc9350 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ενεργό"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Αποθηκεύτηκε"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ενεργό, μόνο το αριστερό"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ενεργό, μόνο το δεξί"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ενεργό, αριστερό και δεξί"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index d4f14f4..af00515 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Active"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Saved"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 6b49bc9..bc08544 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -96,10 +96,8 @@
<string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Connected (no phone or media), battery <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">"Active. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"Active. L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
- <skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
- <skip />
+ <string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"Active. L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+ <string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"Active. R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
@@ -107,9 +105,9 @@
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Right: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Active"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Saved"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+ <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Active (left only)"</string>
+ <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Active (right only)"</string>
+ <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Active (left and right)"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index d4f14f4..af00515 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Active"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Saved"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index d4f14f4..af00515 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Active"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Saved"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index c255633..b123a13 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -96,10 +96,8 @@
<string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Connected (no phone or media), battery <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">"Active. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"Active. L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
- <skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
- <skip />
+ <string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"Active. L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+ <string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"Active. R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
@@ -107,9 +105,9 @@
<string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Right: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Active"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Saved"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+ <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Active (left only)"</string>
+ <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Active (right only)"</string>
+ <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Active (left and right)"</string>
<string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
<string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
<string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 6a40c42..5142f24 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activado"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Guardado"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo; solo oído izquierdo"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo; solo oído derecho"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activo; oídos izquierdo y derecho"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index ab75219..7dc1225 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batería <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Guardado"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo, solo oído izquierdo"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo, solo oído derecho"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activo, oídos izquierdo y derecho"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index c730457..a47a218 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> akut"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akutase: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiivne"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvestatud"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiivne, ainult vasak"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiivne, ainult parem"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiivne, vasak ja parem"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 0668fb2..91b9d20be 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktibo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Gordeta"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktibo, ezkerrekoa soilik"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktibo, eskuinekoa soilik"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktibo, ezkerreko eta eskuineko audifonoak"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 3c7f1f8..7ab13ba 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> شارژ باتری"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"فعال"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ذخیرهشده"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"فعال، فقط چپ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"فعال، فقط راست"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"فعال، چپ و راست"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index da80499..cafeb1b 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akku (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>)"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiivinen"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Tallennettu"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiivinen, vain vasen"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiivinen, vain oikea"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiivinen, vasen ja oikea"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 6988384..0d96205 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actif"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Enregistré"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actif, gauche seulement"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, droite seulement"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, gauche et droite"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 709477b..1928f32 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batterie (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>)"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actif"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Enregistré"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actif, gauche uniquement"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Actif, droit uniquement"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Actifs, gauche et droit"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index e5c7f1e..d0f47a8 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Gardado"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo (só o esquerdo)"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo (só o dereito)"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activos (o esquerdo e o dereito)"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index d520536..b750ae5 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"બૅટરી <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"સક્રિય"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"સાચવેલું"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"સક્રિય, માત્ર ડાબું"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"સક્રિય, માત્ર જમણું"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"સક્રિય, ડાબું અને જમણું બન્ને"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index a81daf7..0f0d516 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"चालू"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"सेव किया गया"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"सिर्फ़ बाईं तरफ़ वाला चालू है"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"सिर्फ़ दाईं तरफ़ वाला चालू है"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"बाईं और दाईं तरफ़ वाला चालू है"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 362393e..db2c318 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Spremljeno"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo lijevo"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, samo desno"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, lijevo i desno"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index f251464..207e84a 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktív"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Mentve"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktív, csak bal"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktív, csak jobb"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktív, bal és jobb"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 4b6d727..1b8b236 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ակտիվ է"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Պահված է"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ակտիվ, միայն ձախ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ակտիվ, միայն աջ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ակտիվ, ձախ և աջ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 1594d11..d9730b3 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktif"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Disimpan"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktif, hanya kiri"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktif, hanya kanan"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktif, kiri dan kanan"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index b85f453..60370f5 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Rafhlaða <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Virkt"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Vistað"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Virkt, aðeins vinstra"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Virkt, aðeins hægra"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Virkt, vinstra og hægra"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 08a2397..fbae08d 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Attivo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Dispositivo salvato"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Attiva, solo sinistra"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Attiva, solo destra"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Attivo, destra e sinistra"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 9ecf47b..5a6c751 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"טעינת הסוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"סוללה <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"פעיל"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"בוצעה שמירה"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"פועל: שמאל בלבד"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"פועל: ימין בלבד"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"פועל: ימין ושמאל"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index a51ba39..aac7223 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"有効"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"保存済み"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"有効、左のみ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"有効、右のみ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"有効、左と右"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index ba1dae0..79dbbe7 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ბატარეა"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ბატარეა <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"აქტიური"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"შენახული"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"აქტიური, მხოლოდ მარცხნივ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"აქტიური, მხოლოდ მარჯვნივ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"აქტიური, მარცხნივ და მარჯვნივ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index b8f8fa3..eee0ac6 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Батарея қуаты: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батарея: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Қосулы"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Сақталған"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Тек сол жағы қосулы"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Тек оң жағы қосулы"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Екеуі де қосулы"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index d049fd4..447126b 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"សកម្ម"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"បានរក្សាទុក"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"សកម្ម ខាងឆ្វេងតែប៉ុណ្ណោះ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"សកម្មខាងស្ដាំតែប៉ុណ្ណោះ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"សកម្មខាងឆ្វេង និងស្ដាំ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 70257de..f8d3b73 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಇದೆ"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ಸಕ್ರಿಯ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ಎಡಕಿವಿಯ ಸಾಧನ ಮಾತ್ರ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ಬಲಕಿವಿಯ ಸಾಧನ ಮಾತ್ರ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ಎಡ ಮತ್ತು ಬಲಕಿವಿಯ ಸಾಧನಗಳು ಸಕ್ರಿಯವಾಗಿವೆ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 9ced8a0..b6988ce 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"활성"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"저장됨"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"활성, 왼쪽만"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"활성, 오른쪽만"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"활성, 왼쪽 및 오른쪽"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 7be7f38..d084a9bf 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батареянын кубаты: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Жигердүү"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Сакталган"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Иштеп жатат, сол кулак гана"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Жигердүү, оң кулакчын гана"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Жигердүү, сол жана оң кулакчын"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index c6a5bd4..19bea08 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ອອນລາຍ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ບັນທຶກແລ້ວ"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ນຳໃຊ້ຢູ່, ຊ້າຍເທົ່ານັ້ນ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ນຳໃຊ້ຢູ່, ຂວາເທົ່ານັ້ນ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ນຳໃຊ້ຢູ່, ຊ້າຍ ແລະ ຂວາ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 94b8173..4f7b350 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Akumuliatoriaus įkrova: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akumuliatorius: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktyvus"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Išsaugota"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktyvus, tik kairysis"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktyvus, tik dešinysis"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktyvus, kairysis ir dešinysis"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index ff1f3f3..55fa4d3 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktīvs"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Saglabāta"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ierīce aktīva, tikai kreisā auss"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ierīce aktīva, tikai labā auss"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ierīces aktīvas, kreisā un labā auss"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index c5b4a5e..6d3d54c 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Батерија: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батерија: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активен"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Зачувано"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активно, само лево"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активно, само десно"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активно, лево и десно"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 0ba9122..914b967 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ബാറ്ററി ചാർജ് <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ആണ്"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"സജീവം"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"സംരക്ഷിച്ചു"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"സജീവമാണ്, ഇടത്തേത് മാത്രം"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"സജീവമാണ്, വലത്തേത് മാത്രം"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"സജീവമാണ്, ഇടത്തേതും വലത്തേതും"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index c431857..c39717c 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Идэвхтэй"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Хадгалсан"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Идэвхтэй, зөвхөн зүүн тал"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Идэвхтэй, зөвхөн баруун тал"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Идэвхтэй, зүүн болон баруун тал"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index a916a1c..5c5ec07 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"अॅक्टिव्ह"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"सेव्ह केली आहेत"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"फक्त डावे अॅक्टिव्ह आहे"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"फक्त उजवे अॅक्टिव्ह आहे"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"डावे आणि उजवे अॅक्टिव्ह आहे"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index f86206c..b36098b 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktif"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Disimpan"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktif, kiri sahaja"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktif, kanan sahaja"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktif, kiri dan kanan"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 2dde99f..23c892f 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ဖွင့်ထားသည်"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"သိမ်းထားသည်များ"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ဖွင့်ထားသည်၊ ဘယ်သီးသန့်"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ဖွင့်ထားသည်၊ ညာသီးသန့်"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ဖွင့်ထားသည်၊ ဘယ်နှင့် ညာ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index d2021ba..d7814eb 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batteri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Lagret"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, bare venstre"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, bare høyre"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, venstre og høyre"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index d01fc16..a7e01a1 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"ब्याट्रीको स्तर: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ब्याट्री <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"सक्रिय"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"सेभ गरिएको"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"बायाँ मात्र अन छ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"सक्रिय, दायाँ मात्र"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"सक्रिय, बायाँ र दायाँ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 6394cb6..3f2e003 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actief"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Opgeslagen"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actief, alleen links"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Actief, alleen rechts"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Actief, links en rechts"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index eb31f96..b233b544 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ବେଟେରୀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ସକ୍ରିୟ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ସେଭ କରାଯାଇଛି"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ସକ୍ରିୟ, କେବଳ ବାମ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ସକ୍ରିୟ, କେବଳ ଡାହାଣ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ସକ୍ରିୟ, ବାମ ଏବଂ ଡାହାଣ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
@@ -195,7 +198,7 @@
<string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"ସୁରକ୍ଷିତ ନେଟ୍ୱର୍କ"</string>
<string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"କଢ଼ାଯାଇଥିବା ଆପ୍ଗୁଡ଼ିକ"</string>
- <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"ଆପ୍ ଏବଂ ଉପଯୋଗକର୍ତ୍ତା ବାହାର କରାଗଲା"</string>
+ <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"ଆପ୍ସ ଏବଂ ୟୁଜରଙ୍କୁ କାଢ଼ି ଦିଆଯାଇଛି"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"ସିଷ୍ଟମ୍ ଅପ୍ଡେଟ୍"</string>
<string name="tether_settings_title_usb" msgid="3728686573430917722">"USB ଟିଥରିଂ"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"ପୋର୍ଟବଲ୍ ହଟସ୍ପଟ୍"</string>
@@ -204,7 +207,7 @@
<string name="tether_settings_title_all" msgid="8910259483383010470">"ଟିଥରିଙ୍ଗ ଓ ପୋର୍ଟବଲ୍ ହଟ୍ସ୍ପଟ୍"</string>
<string name="managed_user_title" msgid="449081789742645723">"ସମସ୍ତ କାର୍ଯ୍ୟ ଆପ୍"</string>
<string name="unknown" msgid="3544487229740637809">"ଅଜଣା"</string>
- <string name="running_process_item_user_label" msgid="3988506293099805796">"ଉପଯୋଗକର୍ତ୍ତା: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+ <string name="running_process_item_user_label" msgid="3988506293099805796">"ୟୁଜର: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"କିଛି ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ ମାନ ସେଟ୍ ହୋଇଛି"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"କୌଣସି ଡିଫଲ୍ଟ ସେଟ୍ ହୋଇନାହିଁ"</string>
<string name="tts_settings" msgid="8130616705989351312">"ଟେକ୍ସଟ୍-ଟୁ-ସ୍ପିଚ୍ ସେଟିଂସ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 64c4e96..73fe924 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ਕਿਰਿਆਸ਼ੀਲ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ਕਿਰਿਆਸ਼ੀਲ, ਸਿਰਫ਼ ਖੱਬਾ"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ਕਿਰਿਆਸ਼ੀਲ, ਸਿਰਫ਼ ਸੱਜਾ"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ਕਿਰਿਆਸ਼ੀਲ, ਖੱਬਾ ਅਤੇ ਸੱਜਾ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index d4d27e1..767b87d 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Urządzenie aktywne"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Zapisano"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktywne, tylko lewa strona"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktywne, tylko prawa strona"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktywny, lewa i prawa strona"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 38df760..5bc01f1 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ativo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvo"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ativo, apenas o esquerdo"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ativo, apenas o direito"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ativo, esquerdo e direito"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 9e98623..f0b94bf 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ativo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Guardado"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ativo, apenas esquerdo"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ativo, apenas direito"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ativo, esquerdo e direito"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 38df760..5bc01f1 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ativo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvo"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ativo, apenas o esquerdo"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ativo, apenas o direito"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ativo, esquerdo e direito"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index dddc116..4d6638a 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activ"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvat"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activ, numai stânga"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activ, numai dreapta"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activ, stânga și dreapta"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 9a5a400..e155948 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Уровень заряда: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батарея <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активно"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Сохранено"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активен, только левое ухо"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активен, только правое ухо"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активен, оба уха"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 0fce42b..dff692e 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ක්රියාකාරී"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"සුරැකිණි"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"සක්රිය, වම පමණි"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"සක්රිය, දකුණ පමණි"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"සක්රිය, වම සහ දකුණ"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 74c9e1f..e85e96d 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktívne"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Uložené"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktívne, iba ľavá strana"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktívne, iba pravá strana"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktívne, ľavá aj pravá strana"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index a6d35c80..6eb655c 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterija: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivna"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Shranjeno"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo levo"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, samo desno"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, levo in desno"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 3f6e803..f112060 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Të ruajtura"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktive, vetëm majtas"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktive, vetëm djathtas"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktive, majtas dhe djathtas"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 135176b..9341616 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батерија, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активан"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Сачувано"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активно, само с леве стране"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активно, с десне стране"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активно, с леве и десне стране"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 7712203..d3370e8 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batteri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Sparad"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, bara vänster"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, bara höger"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, vänster och höger"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 53d583a..d230022 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Kimeunganishwa"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Imeokoa"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Inatumika, kushoto pekee"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Inatumika, kulia pekee"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Inatumika, kushoto na kulia"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index db11263..8097be0 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"செயலில் உள்ளது"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"சேமிக்கப்பட்டது"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"இடது பக்கம் மட்டும் செயலில் உள்ளது"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"வலது பக்கம் மட்டும் செயலில் உள்ளது"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"வலது மற்றும் இடது பக்கம் செயலில் உள்ளது"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index c2faca9..a9d4c03 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"యాక్టివ్గా ఉంది"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"సేవ్ చేయబడింది"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"యాక్టివ్గా ఉంది, ఎడమవైపు మాత్రమే యాక్టివ్గా ఉంది"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"యాక్టివ్గా ఉంది, కుడివైపు యాక్టివ్గా ఉంది"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"యాక్టివ్గా ఉంది, ఎడమవైపు, కుడివైపు యాక్టివ్గా ఉంది"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 7b03f81..8f59f36 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ใช้งานอยู่"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"บันทึกแล้ว"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ใช้งานอยู่ เฉพาะข้างซ้าย"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ใช้งานอยู่ เฉพาะข้างขวา"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ใช้งานอยู่ ข้างซ้ายและขวา"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 8eef17e..58b6e84 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktibo"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Na-save"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktibo, kaliwa lang"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktibo, kanan lang"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktibo, kaliwa at kanan"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index cf5bd2d..0300ddc 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Pil <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Etkin"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Kaydedildi"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Yalnızca sol tarafta etkin"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Yalnızca sağ tarafta etkin"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Sol ve sağ tarafta etkin"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 4b40503..807bc51 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активовано"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Збережено"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активовано, лише лівий"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активовано, лише правий"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активовано, лівий і правий"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index a1b2198..cee510b 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"فعال"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"محفوظ ہے"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"فعال، صرف بائیں طرف"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"فعال، صرف دائیں طرف"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"فعال، صرف بائیں اور دائیں طرف"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 82f4576..4415667 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batareya: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Faol"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Saqlangan"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Faol, faqat chap"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Faol, faqat oʻng"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Faol, chap va oʻng"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 9a1386e..f33d909 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"Mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Đang hoạt động"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Đã lưu"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Đang hoạt động, chỉ tai bên trái"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Đang hoạt động, chỉ tai phải"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Đang hoạt động, cả tai phải và tai trái"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index d3f8945..816ba8d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 的电量"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"电池电量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"使用中"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"已保存的设备"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"使用中,仅左耳助听器"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"使用中,仅右耳助听器"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"使用中,左右耳助听器"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index b5a1d51..b26efb2 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"使用中"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"已儲存"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"使用中,僅左耳"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"使用中,僅右耳"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"使用中,左右耳"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index a131c12..149022c 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"使用中"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"已儲存"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"使用中,僅左耳"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"使用中,僅右耳"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"使用中,左右耳"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index f9bdfbf..7aea126 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -98,9 +98,9 @@
<skip />
<!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
<skip />
- <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+ <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
<skip />
<string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri"</string>
<string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Ibhethri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
<skip />
<string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Iyasebenza"</string>
<string name="bluetooth_saved_device" msgid="4895871321722311428">"Ilondoloziwe"</string>
- <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Iyasebenza, ngakwesokunxele kuphela"</string>
- <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Iyasebenza, ngakwesokudla kuphela"</string>
- <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Iyasebenza, ngakwesokunxele nakwesokudla"</string>
+ <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+ <skip />
+ <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+ <skip />
<!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
<skip />
<!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index fa27db9..dc40304 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -202,8 +202,8 @@
dreamInfo.componentName = componentName;
dreamInfo.isActive = dreamInfo.componentName.equals(activeDream);
- final DreamService.DreamMetadata dreamMetadata = DreamService.getDreamMetadata(mContext,
- resolveInfo.serviceInfo);
+ final DreamService.DreamMetadata dreamMetadata = DreamService.getDreamMetadata(
+ mContext.getPackageManager(), resolveInfo.serviceInfo);
if (dreamMetadata != null) {
dreamInfo.settingsComponentName = dreamMetadata.settingsActivity;
dreamInfo.previewImage = dreamMetadata.previewImage;
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 5cc3caf..59e2b91 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -906,14 +906,6 @@
android:exported="true"
/>
- <activity
- android:name=".volume.panel.ui.activity.VolumePanelActivity"
- android:label="@string/accessibility_volume_settings"
- android:excludeFromRecents="true"
- android:exported="false"
- android:launchMode="singleInstance"
- android:theme="@style/Theme.VolumePanelActivity" />
-
<activity android:name=".wallet.ui.WalletActivity"
android:label="@string/wallet_title"
android:theme="@style/Wallet.Theme"
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml
index 749a6f2..199b0c9 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml
@@ -9,7 +9,7 @@
<string name="power_label" msgid="7699720321491287839">"Napajanje"</string>
<string name="power_utterance" msgid="7444296686402104807">"Opcije napajanja"</string>
<string name="recent_apps_label" msgid="6583276995616385847">"Nedavne aplikacije"</string>
- <string name="lockscreen_label" msgid="648347953557887087">"Zaključavanje ekrana"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Zaključani ekran"</string>
<string name="quick_settings_label" msgid="2999117381487601865">"Brze postavke"</string>
<string name="notifications_label" msgid="6829741046963013567">"Obavještenja"</string>
<string name="screenshot_label" msgid="863978141223970162">"Snimak ekrana"</string>
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 7033e2b..b3aa7e1 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -226,6 +226,13 @@
}
flag {
+ name: "dual_shade"
+ namespace: "systemui"
+ description: "Enables the BC25 Dual Shade (go/bc25-dual-shade-design)."
+ bug: "337259436"
+}
+
+flag {
name: "keyguard_bottom_area_refactor"
namespace: "systemui"
description: "Bottom area of keyguard refactor move into KeyguardRootView. Includes "
@@ -835,3 +842,13 @@
description: "Enforce BaseUserRestriction for DISALLOW_CONFIG_BRIGHTNESS."
bug: "329205638"
}
+
+flag {
+ name: "ambient_touch_monitor_listen_to_display_changes"
+ namespace: "systemui"
+ description: "listen to display changes and cache window metrics"
+ bug: "330906135"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffect.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffect.kt
deleted file mode 100644
index ffa2b46..0000000
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffect.kt
+++ /dev/null
@@ -1,111 +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.surfaceeffects.revealeffect
-
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.ValueAnimator
-import android.graphics.RenderEffect
-import androidx.core.graphics.ColorUtils
-import com.android.systemui.surfaceeffects.RenderEffectDrawCallback
-import com.android.systemui.surfaceeffects.utils.MathUtils
-import kotlin.math.max
-import kotlin.math.min
-
-/** Creates a reveal effect with a circular ripple sparkles on top. */
-class RippleRevealEffect(
- private val config: RippleRevealEffectConfig,
- private val renderEffectCallback: RenderEffectDrawCallback,
- private val stateChangedCallback: AnimationStateChangedCallback? = null
-) {
- private val rippleRevealShader = RippleRevealShader().apply { applyConfig(config) }
- private val animator: ValueAnimator = ValueAnimator.ofFloat(0f, 1f)
-
- fun play() {
- if (animator.isRunning) {
- return
- }
-
- animator.duration = config.duration.toLong()
- animator.addUpdateListener { updateListener ->
- val playTime = updateListener.currentPlayTime.toFloat()
- rippleRevealShader.setTime(playTime * TIME_SCALE_FACTOR)
-
- // Compute radius.
- val progress = updateListener.animatedValue as Float
- val innerRad = MathUtils.lerp(config.innerRadiusStart, config.innerRadiusEnd, progress)
- val outerRad = MathUtils.lerp(config.outerRadiusStart, config.outerRadiusEnd, progress)
- rippleRevealShader.setInnerRadius(innerRad)
- rippleRevealShader.setOuterRadius(outerRad)
-
- // Compute alphas.
- val innerAlphaProgress =
- MathUtils.constrainedMap(
- 1f,
- 0f,
- config.innerFadeOutStart,
- config.duration,
- playTime
- )
- val outerAlphaProgress =
- MathUtils.constrainedMap(
- 1f,
- 0f,
- config.outerFadeOutStart,
- config.duration,
- playTime
- )
- val innerAlpha = MathUtils.lerp(0f, 255f, innerAlphaProgress)
- val outerAlpha = MathUtils.lerp(0f, 255f, outerAlphaProgress)
-
- val innerColor = ColorUtils.setAlphaComponent(config.innerColor, innerAlpha.toInt())
- val outerColor = ColorUtils.setAlphaComponent(config.outerColor, outerAlpha.toInt())
- rippleRevealShader.setInnerColor(innerColor)
- rippleRevealShader.setOuterColor(outerColor)
-
- // Pass in progresses since those functions take in normalized alpha values.
- rippleRevealShader.setBackgroundAlpha(max(innerAlphaProgress, outerAlphaProgress))
- rippleRevealShader.setSparkleAlpha(min(innerAlphaProgress, outerAlphaProgress))
-
- // Trigger draw callback.
- renderEffectCallback.onDraw(
- RenderEffect.createRuntimeShaderEffect(
- rippleRevealShader,
- RippleRevealShader.BACKGROUND_UNIFORM
- )
- )
- }
- animator.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- stateChangedCallback?.onAnimationEnd()
- }
- }
- )
- animator.start()
- stateChangedCallback?.onAnimationStart()
- }
-
- interface AnimationStateChangedCallback {
- fun onAnimationStart()
- fun onAnimationEnd()
- }
-
- private companion object {
- private const val TIME_SCALE_FACTOR = 0.00175f
- }
-}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectConfig.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectConfig.kt
deleted file mode 100644
index 9675f19..0000000
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectConfig.kt
+++ /dev/null
@@ -1,65 +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.surfaceeffects.revealeffect
-
-import android.graphics.Color
-
-/** Defines parameters needed for [RippleRevealEffect]. */
-data class RippleRevealEffectConfig(
- /** Total duration of the animation. */
- val duration: Float = 0f,
- /** Timestamp of when the inner mask starts fade out. (Linear fadeout) */
- val innerFadeOutStart: Float = 0f,
- /** Timestamp of when the outer mask starts fade out. (Linear fadeout) */
- val outerFadeOutStart: Float = 0f,
- /** Center x position of the effect. */
- val centerX: Float = 0f,
- /** Center y position of the effect. */
- val centerY: Float = 0f,
- /** Start radius of the inner circle. */
- val innerRadiusStart: Float = 0f,
- /** End radius of the inner circle. */
- val innerRadiusEnd: Float = 0f,
- /** Start radius of the outer circle. */
- val outerRadiusStart: Float = 0f,
- /** End radius of the outer circle. */
- val outerRadiusEnd: Float = 0f,
- /**
- * Pixel density of the display. Do not pass a random value. The value must come from
- * [context.resources.displayMetrics.density].
- */
- val pixelDensity: Float = 1f,
- /**
- * The amount the circle masks should be softened. Higher value will make the edge of the circle
- * mask soft.
- */
- val blurAmount: Float = 0f,
- /** Color of the inner circle mask. */
- val innerColor: Int = Color.WHITE,
- /** Color of the outer circle mask. */
- val outerColor: Int = Color.WHITE,
- /** Multiplier to make the sparkles visible. */
- val sparkleStrength: Float = SPARKLE_STRENGTH,
- /** Size of the sparkle. Expected range [0, 1]. */
- val sparkleScale: Float = SPARKLE_SCALE
-) {
- /** Default parameters. */
- companion object {
- const val SPARKLE_STRENGTH: Float = 0.3f
- const val SPARKLE_SCALE: Float = 0.8f
- }
-}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealShader.kt
deleted file mode 100644
index a3f9795..0000000
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealShader.kt
+++ /dev/null
@@ -1,144 +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.surfaceeffects.revealeffect
-
-import android.graphics.RuntimeShader
-import com.android.systemui.surfaceeffects.shaderutil.SdfShaderLibrary
-import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
-
-/** Circular reveal effect with sparkles. */
-class RippleRevealShader : RuntimeShader(SHADER) {
- // language=AGSL
- companion object {
- const val BACKGROUND_UNIFORM = "in_dst"
- private const val MAIN =
- """
- uniform shader ${BACKGROUND_UNIFORM};
- uniform half in_dstAlpha;
- uniform half in_time;
- uniform vec2 in_center;
- uniform half in_innerRadius;
- uniform half in_outerRadius;
- uniform half in_sparkleStrength;
- uniform half in_blur;
- uniform half in_pixelDensity;
- uniform half in_sparkleScale;
- uniform half in_sparkleAlpha;
- layout(color) uniform vec4 in_innerColor;
- layout(color) uniform vec4 in_outerColor;
-
- vec4 main(vec2 p) {
- half innerMask = soften(sdCircle(p - in_center, in_innerRadius), in_blur);
- half outerMask = soften(sdCircle(p - in_center, in_outerRadius), in_blur);
-
- // Flip it since we are interested in the circle.
- innerMask = 1.-innerMask;
- outerMask = 1.-outerMask;
-
- // Color two circles using the mask.
- vec4 inColor = vec4(in_innerColor.rgb, 1.) * in_innerColor.a;
- vec4 outColor = vec4(in_outerColor.rgb, 1.) * in_outerColor.a;
- vec4 blend = mix(inColor, outColor, innerMask);
-
- vec4 dst = vec4(in_dst.eval(p).rgb, 1.);
- dst *= in_dstAlpha;
-
- blend *= blend.a;
- // Do normal blend with the background.
- blend = blend + dst * (1. - blend.a);
-
- half sparkle =
- sparkles(p - mod(p, in_pixelDensity * in_sparkleScale), in_time);
- // Add sparkles using additive blending.
- blend += sparkle * in_sparkleStrength * in_sparkleAlpha;
-
- // Mask everything at the end.
- blend *= outerMask;
-
- return blend;
- }
- """
-
- private const val SHADER =
- ShaderUtilLibrary.SHADER_LIB +
- SdfShaderLibrary.SHADER_SDF_OPERATION_LIB +
- SdfShaderLibrary.CIRCLE_SDF +
- MAIN
- }
-
- fun applyConfig(config: RippleRevealEffectConfig) {
- setCenter(config.centerX, config.centerY)
- setInnerRadius(config.innerRadiusStart)
- setOuterRadius(config.outerRadiusStart)
- setBlurAmount(config.blurAmount)
- setPixelDensity(config.pixelDensity)
- setSparkleScale(config.sparkleScale)
- setSparkleStrength(config.sparkleStrength)
- setInnerColor(config.innerColor)
- setOuterColor(config.outerColor)
- }
-
- fun setTime(time: Float) {
- setFloatUniform("in_time", time)
- }
-
- fun setCenter(centerX: Float, centerY: Float) {
- setFloatUniform("in_center", centerX, centerY)
- }
-
- fun setInnerRadius(radius: Float) {
- setFloatUniform("in_innerRadius", radius)
- }
-
- fun setOuterRadius(radius: Float) {
- setFloatUniform("in_outerRadius", radius)
- }
-
- fun setBlurAmount(blurAmount: Float) {
- setFloatUniform("in_blur", blurAmount)
- }
-
- fun setPixelDensity(density: Float) {
- setFloatUniform("in_pixelDensity", density)
- }
-
- fun setSparkleScale(scale: Float) {
- setFloatUniform("in_sparkleScale", scale)
- }
-
- fun setSparkleStrength(strength: Float) {
- setFloatUniform("in_sparkleStrength", strength)
- }
-
- fun setInnerColor(color: Int) {
- setColorUniform("in_innerColor", color)
- }
-
- fun setOuterColor(color: Int) {
- setColorUniform("in_outerColor", color)
- }
-
- /** Sets the background alpha. Range [0,1]. */
- fun setBackgroundAlpha(alpha: Float) {
- setFloatUniform("in_dstAlpha", alpha)
- }
-
- /** Sets the sparkle alpha. Range [0,1]. */
- fun setSparkleAlpha(alpha: Float) {
- setFloatUniform("in_sparkleAlpha", alpha)
- }
-}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt
deleted file mode 100644
index 1411c32..0000000
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt
+++ /dev/null
@@ -1,50 +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.surfaceeffects.utils
-
-/** Copied from android.utils.MathUtils */
-object MathUtils {
- fun constrainedMap(
- rangeMin: Float,
- rangeMax: Float,
- valueMin: Float,
- valueMax: Float,
- value: Float
- ): Float {
- return lerp(rangeMin, rangeMax, lerpInvSat(valueMin, valueMax, value))
- }
-
- fun lerp(start: Float, stop: Float, amount: Float): Float {
- return start + (stop - start) * amount
- }
-
- fun lerpInv(a: Float, b: Float, value: Float): Float {
- return if (a != b) (value - a) / (b - a) else 0.0f
- }
-
- fun saturate(value: Float): Float {
- return constrain(value, 0.0f, 1.0f)
- }
-
- fun lerpInvSat(a: Float, b: Float, value: Float): Float {
- return saturate(lerpInv(a, b, value))
- }
-
- fun constrain(amount: Float, low: Float, high: Float): Float {
- return if (amount < low) low else if (amount > high) high else amount
- }
-}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
index 19d6038..7af8408 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
@@ -52,7 +52,6 @@
import com.android.internal.R
import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PatternDotViewModel
-import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sqrt
@@ -110,30 +109,14 @@
remember(dots) {
dots.associateWith { dot -> with(density) { (80 + (20 * dot.y)).dp.toPx() } }
}
- val dotAppearScaleAnimatables = remember(dots) { dots.associateWith { Animatable(0f) } }
LaunchedEffect(Unit) {
dotAppearFadeInAnimatables.forEach { (dot, animatable) ->
scope.launch {
- // Maps a dot at x and y to an ordinal number to denote the order in which all dots
- // are visited by the fade-in animation.
- //
- // The order is basically starting from the top-left most dot (at 0,0) and ending at
- // the bottom-right most dot (at 2,2). The visitation order happens
- // diagonal-by-diagonal. Here's a visual representation of the expected output:
- // [0][1][3]
- // [2][4][6]
- // [5][7][8]
- //
- // There's an assumption here that the grid is 3x3. If it's not, this formula needs
- // to be revisited.
- check(viewModel.columnCount == 3 && viewModel.rowCount == 3)
- val staggerOrder = max(0, min(8, 2 * (dot.x + dot.y) + (dot.y - 1)))
-
animatable.animateTo(
targetValue = 1f,
animationSpec =
tween(
- delayMillis = 33 * staggerOrder,
+ delayMillis = 33 * dot.y,
durationMillis = 450,
easing = Easings.LegacyDecelerate,
)
@@ -153,19 +136,6 @@
)
}
}
- dotAppearScaleAnimatables.forEach { (dot, animatable) ->
- scope.launch {
- animatable.animateTo(
- targetValue = 1f,
- animationSpec =
- tween(
- delayMillis = 33 * dot.y,
- durationMillis = 450,
- easing = Easings.LegacyDecelerate,
- )
- )
- }
- }
}
val view = LocalView.current
@@ -401,10 +371,7 @@
),
color =
dotColor.copy(alpha = checkNotNull(dotAppearFadeInAnimatables[dot]).value),
- radius =
- dotRadius *
- checkNotNull(dotScalingAnimatables[dot]).value *
- checkNotNull(dotAppearScaleAnimatables[dot]).value,
+ radius = dotRadius * checkNotNull(dotScalingAnimatables[dot]).value
)
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index 89d4343..338987a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -132,6 +132,7 @@
import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.ui.viewmodel.PopupType
import com.android.systemui.communal.widgets.WidgetConfigurator
import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.SystemUIDialogFactory
@@ -148,8 +149,7 @@
onEditDone: (() -> Unit)? = null,
) {
val communalContent by viewModel.communalContent.collectAsState(initial = emptyList())
- val isPopupOnDismissCtaShowing by
- viewModel.isPopupOnDismissCtaShowing.collectAsState(initial = false)
+ val currentPopup by viewModel.currentPopup.collectAsState(initial = null)
var removeButtonCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
var toolbarSize: IntSize? by remember { mutableStateOf(null) }
var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
@@ -161,7 +161,6 @@
val removeButtonEnabled by remember {
derivedStateOf { selectedKey.value != null || reorderingWidgets }
}
- var isButtonToEditWidgetsShowing by remember { mutableStateOf(false) }
val isEmptyState by viewModel.isEmptyState.collectAsState(initial = false)
val contentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
@@ -214,7 +213,7 @@
communalContent[index] is
CommunalContentModel.CtaTileInViewMode
) {
- isButtonToEditWidgetsShowing = true
+ viewModel.onShowCustomizeWidgetButton()
}
val key =
index?.let { keyAtIndexIfEditable(communalContent, index) }
@@ -290,18 +289,22 @@
)
}
- if (isPopupOnDismissCtaShowing) {
- PopupOnDismissCtaTile(viewModel::onHidePopupAfterDismissCta)
- }
-
- if (isButtonToEditWidgetsShowing) {
- ButtonToEditWidgets(
- onClick = {
- isButtonToEditWidgetsShowing = false
- viewModel.onOpenWidgetEditor(selectedKey.value)
- },
- onHide = { isButtonToEditWidgetsShowing = false },
- )
+ if (currentPopup != null) {
+ when (currentPopup) {
+ PopupType.CtaTile -> {
+ PopupOnDismissCtaTile(viewModel::onHidePopup)
+ }
+ PopupType.CustomizeWidgetButton -> {
+ ButtonToEditWidgets(
+ onClick = {
+ viewModel.onHidePopup()
+ viewModel.onOpenWidgetEditor(selectedKey.value)
+ },
+ onHide = { viewModel.onHidePopup()}
+ )
+ }
+ null -> {}
+ }
}
if (viewModel is CommunalViewModel && dialogFactory != null) {
@@ -679,11 +682,11 @@
}
@Composable
-private fun PopupOnDismissCtaTile(onHidePopupAfterDismissCta: () -> Unit) {
+private fun PopupOnDismissCtaTile(onHidePopup: () -> Unit) {
Popup(
alignment = Alignment.TopCenter,
offset = IntOffset(0, 40),
- onDismissRequest = onHidePopupAfterDismissCta
+ onDismissRequest = onHidePopup
) {
val colors = LocalAndroidColorScheme.current
Row(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt
index dae120c..556bbbe 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt
@@ -17,21 +17,14 @@
package com.android.systemui.keyguard.ui.composable.section
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.onSizeChanged
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.dimensionResource
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.keyguard.ui.viewmodel.MediaCarouselViewModel
import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dagger.MediaModule
-import com.android.systemui.res.R
-import com.android.systemui.util.animation.MeasurementInput
import javax.inject.Inject
import javax.inject.Named
@@ -43,29 +36,19 @@
private val mediaCarouselViewModel: MediaCarouselViewModel,
) {
- @Composable
- fun SceneScope.MediaCarousel(modifier: Modifier = Modifier) {
- if (!mediaCarouselViewModel.isMediaVisible) {
- return
- }
-
+ private fun isVisible(): Boolean {
if (mediaCarouselController.mediaFrame == null) {
- return
+ return false
}
+ return mediaCarouselViewModel.isMediaVisible
+ }
- val mediaHeight = dimensionResource(R.dimen.qs_media_session_height_expanded)
- // TODO(b/312714128): MediaPlayer background size is not as expected.
+ @Composable
+ fun SceneScope.KeyguardMediaCarousel() {
MediaCarousel(
- modifier =
- modifier.height(mediaHeight).fillMaxWidth().onSizeChanged { size ->
- // Notify controller to size the carousel for the
- // current space
- mediaHost.measurementInput = MeasurementInput(size.width, size.height)
- mediaCarouselController.setSceneContainerSize(size.width, size.height)
- },
+ isVisible = ::isVisible,
mediaHost = mediaHost,
- layoutWidth = 0, // Layout width is not used.
- layoutHeight = with(LocalDensity.current) { mediaHeight.toPx() }.toInt(),
+ modifier = Modifier.fillMaxWidth(),
carouselController = mediaCarouselController,
)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
index e0540bf..722032c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
@@ -125,7 +125,7 @@
onTopChanged = burnIn.onSmartspaceTopChanged,
)
}
- with(mediaCarouselSection) { MediaCarousel() }
+ with(mediaCarouselSection) { KeyguardMediaCarousel() }
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
index f0d356c..241c171 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
@@ -18,14 +18,20 @@
import android.view.ViewGroup
import android.widget.FrameLayout
+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.layout.layout
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.contains
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.res.R
import com.android.systemui.util.animation.MeasurementInput
private object MediaCarousel {
@@ -36,18 +42,40 @@
@Composable
fun SceneScope.MediaCarousel(
+ isVisible: () -> Boolean,
mediaHost: MediaHost,
modifier: Modifier = Modifier,
- layoutWidth: Int,
- layoutHeight: Int,
carouselController: MediaCarouselController,
) {
+ if (!isVisible()) {
+ return
+ }
+
+ val density = LocalDensity.current
+ val mediaHeight = dimensionResource(R.dimen.qs_media_session_height_expanded)
+
+ val layoutWidth = 0
+ val layoutHeight = with(density) { mediaHeight.toPx() }.toInt()
+
// Notify controller to size the carousel for the current space
mediaHost.measurementInput = MeasurementInput(layoutWidth, layoutHeight)
carouselController.setSceneContainerSize(layoutWidth, layoutHeight)
AndroidView(
- modifier = modifier.element(MediaCarousel.Elements.Content),
+ modifier =
+ modifier
+ .element(MediaCarousel.Elements.Content)
+ .height(mediaHeight)
+ .fillMaxWidth()
+ .layout { measurable, constraints ->
+ val placeable = measurable.measure(constraints)
+
+ // Notify controller to size the carousel for the current space
+ mediaHost.measurementInput = MeasurementInput(placeable.width, placeable.height)
+ carouselController.setSceneContainerSize(placeable.width, placeable.height)
+
+ layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
+ },
factory = { context ->
FrameLayout(context).apply {
val mediaFrame = carouselController.mediaFrame
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index f6575dc..62619f5 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -67,6 +67,10 @@
import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.media.controls.ui.composable.MediaCarousel
+import com.android.systemui.media.controls.ui.controller.MediaCarouselController
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.media.dagger.MediaModule
import com.android.systemui.notifications.ui.composable.NotificationScrollingStack
import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility
import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel
@@ -82,6 +86,7 @@
import com.android.systemui.statusbar.phone.ui.StatusBarIconController
import com.android.systemui.statusbar.phone.ui.TintedIconManager
import javax.inject.Inject
+import javax.inject.Named
import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -98,6 +103,8 @@
private val tintedIconManagerFactory: TintedIconManager.Factory,
private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
private val statusBarIconController: StatusBarIconController,
+ private val mediaCarouselController: MediaCarouselController,
+ @Named(MediaModule.QS_PANEL) private val mediaHost: MediaHost,
) : ComposableScene {
override val key = Scenes.QuickSettings
@@ -118,6 +125,8 @@
createTintedIconManager = tintedIconManagerFactory::create,
createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
statusBarIconController = statusBarIconController,
+ mediaCarouselController = mediaCarouselController,
+ mediaHost = mediaHost,
modifier = modifier,
)
}
@@ -130,6 +139,8 @@
createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
statusBarIconController: StatusBarIconController,
+ mediaCarouselController: MediaCarouselController,
+ mediaHost: MediaHost,
modifier: Modifier = Modifier,
) {
val brightnessMirrorShowing by viewModel.brightnessMirrorViewModel.isShowing.collectAsState()
@@ -282,6 +293,13 @@
isSplitShade = false,
modifier = Modifier.sysuiResTag("expanded_qs_scroll_view"),
)
+
+ MediaCarousel(
+ isVisible = viewModel::isMediaVisible,
+ mediaHost = mediaHost,
+ modifier = Modifier.fillMaxWidth(),
+ carouselController = mediaCarouselController,
+ )
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index 91a9d2a..cda8059 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -50,11 +50,9 @@
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.Layout
-import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.colorResource
-import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.LowestZIndexScenePicker
@@ -85,7 +83,6 @@
import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.phone.ui.StatusBarIconController
import com.android.systemui.statusbar.phone.ui.TintedIconManager
-import com.android.systemui.util.animation.MeasurementInput
import javax.inject.Inject
import javax.inject.Named
import kotlin.math.roundToInt
@@ -243,10 +240,11 @@
)
}
- MediaIfVisible(
- viewModel = viewModel,
- mediaCarouselController = mediaCarouselController,
+ MediaCarousel(
+ isVisible = viewModel::isMediaVisible,
mediaHost = mediaHost,
+ modifier = Modifier.fillMaxWidth(),
+ carouselController = mediaCarouselController,
)
Spacer(modifier = Modifier.height(16.dp))
@@ -406,11 +404,11 @@
)
}
- MediaIfVisible(
- viewModel = viewModel,
- mediaCarouselController = mediaCarouselController,
+ MediaCarousel(
+ isVisible = viewModel::isMediaVisible,
mediaHost = mediaHost,
modifier = Modifier.fillMaxWidth(),
+ carouselController = mediaCarouselController,
)
}
FooterActionsWithAnimatedVisibility(
@@ -437,34 +435,3 @@
}
}
}
-
-@Composable
-private fun SceneScope.MediaIfVisible(
- viewModel: ShadeSceneViewModel,
- mediaCarouselController: MediaCarouselController,
- mediaHost: MediaHost,
- modifier: Modifier = Modifier,
-) {
- if (viewModel.isMediaVisible()) {
- val density = LocalDensity.current
- val mediaHeight = dimensionResource(R.dimen.qs_media_session_height_expanded)
-
- MediaCarousel(
- modifier =
- modifier.height(mediaHeight).fillMaxWidth().layout { measurable, constraints ->
- val placeable = measurable.measure(constraints)
-
- // Notify controller to size the carousel for the
- // current space
- mediaHost.measurementInput = MeasurementInput(placeable.width, placeable.height)
- mediaCarouselController.setSceneContainerSize(placeable.width, placeable.height)
-
- layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
- },
- mediaHost = mediaHost,
- layoutWidth = 0,
- layoutHeight = with(density) { mediaHeight.toPx() }.toInt(),
- carouselController = mediaCarouselController,
- )
- }
-}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/EdgeToEdgeDialogDelegate.kt b/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/EdgeToEdgeDialogDelegate.kt
new file mode 100644
index 0000000..55dfed4
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/EdgeToEdgeDialogDelegate.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.statusbar.phone
+
+import android.os.Bundle
+import android.view.Gravity
+import android.view.WindowManager
+
+/** [DialogDelegate] that configures a dialog to be an edge-to-edge one. */
+class EdgeToEdgeDialogDelegate : DialogDelegate<SystemUIDialog> {
+
+ override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+ dialog.window?.apply {
+ setGravity(Gravity.BOTTOM or Gravity.CENTER)
+ attributes =
+ attributes.apply {
+ fitInsetsSides = 0
+ attributes.apply {
+ layoutInDisplayCutoutMode =
+ WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+ }
+ }
+ }
+ }
+
+ override fun getWidth(dialog: SystemUIDialog): Int = WindowManager.LayoutParams.MATCH_PARENT
+
+ override fun getHeight(dialog: SystemUIDialog): Int = WindowManager.LayoutParams.MATCH_PARENT
+}
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 d66bada..fe97405 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
@@ -17,13 +17,33 @@
package com.android.systemui.statusbar.phone
import android.content.Context
+import android.content.res.Configuration
+import android.os.Bundle
import androidx.annotation.GravityInt
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.safeDrawing
+import androidx.compose.foundation.layout.widthIn
+import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
import com.android.compose.theme.PlatformTheme
+import com.android.systemui.res.R
/**
* Create a [SystemUIDialog] with the given [content].
@@ -56,7 +76,73 @@
@GravityInt dialogGravity: Int? = null,
content: @Composable (SystemUIDialog) -> Unit,
): ComponentSystemUIDialog {
- val dialog = create(context, theme, dismissOnDeviceLock, dialogGravity)
+ 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) }
+ }
+ },
+ content = content,
+ )
+}
+
+/** Same as [create] but creates a bottom sheet dialog. */
+fun SystemUIDialogFactory.createBottomSheet(
+ context: Context = this.applicationContext,
+ theme: Int = R.style.Theme_SystemUI_BottomSheet,
+ dismissOnDeviceLock: Boolean = SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK,
+ content: @Composable (SystemUIDialog) -> Unit,
+): ComponentSystemUIDialog {
+ return create(
+ context = context,
+ theme = theme,
+ dismissOnDeviceLock = dismissOnDeviceLock,
+ delegate = EdgeToEdgeDialogDelegate(),
+ content = { dialog ->
+ Box(
+ modifier = Modifier.bottomSheetClickable { dialog.dismiss() },
+ contentAlignment = Alignment.BottomCenter
+ ) {
+ val radius = dimensionResource(R.dimen.bottom_sheet_corner_radius)
+ Surface(
+ modifier =
+ Modifier.bottomSheetPaddings()
+ // consume input so it doesn't get to the parent Composable
+ .bottomSheetClickable {}
+ // TODO(b/337205027) change width
+ .widthIn(max = 800.dp),
+ shape = RoundedCornerShape(topStart = radius, topEnd = radius),
+ color = MaterialTheme.colorScheme.surfaceContainer,
+ ) {
+ Box(
+ Modifier.padding(
+ bottom =
+ with(LocalDensity.current) {
+ WindowInsets.safeDrawing.getBottom(this).toDp()
+ }
+ )
+ ) {
+ content(dialog)
+ }
+ }
+ }
+ },
+ )
+}
+
+private fun SystemUIDialogFactory.create(
+ context: Context,
+ theme: Int,
+ dismissOnDeviceLock: Boolean,
+ delegate: DialogDelegate<SystemUIDialog>,
+ content: @Composable (SystemUIDialog) -> Unit,
+): ComponentSystemUIDialog {
+ val dialog = create(context, theme, dismissOnDeviceLock, delegate)
// Create the dialog so that it is properly constructed before we set the Compose content.
// Otherwise, the ComposeView won't render properly.
@@ -79,3 +165,29 @@
return dialog
}
+
+/** Adds paddings for the bottom sheet surface. */
+@Composable
+private fun Modifier.bottomSheetPaddings(): Modifier {
+ val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT
+ return with(LocalDensity.current) {
+ val insets = WindowInsets.safeDrawing
+ // TODO(b/337205027) change paddings
+ val horizontalPadding: Dp = if (isPortrait) 0.dp else 48.dp
+ padding(
+ start = insets.getLeft(this, LocalLayoutDirection.current).toDp() + horizontalPadding,
+ top = insets.getTop(this).toDp(),
+ end = insets.getRight(this, LocalLayoutDirection.current).toDp() + horizontalPadding
+ )
+ }
+}
+
+/**
+ * For some reason adding clickable modifier onto the VolumePanel affects the traversal order:
+ * b/331155283.
+ *
+ * TODO(b/334870995) revert this to Modifier.clickable
+ */
+@Composable
+private fun Modifier.bottomSheetClickable(onClick: () -> Unit) =
+ pointerInput(onClick) { detectTapGestures { onClick() } }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt
index b489dfc..bb4e957 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt
@@ -65,7 +65,7 @@
) {
val dialog =
dialogFactory.create(
- theme = R.style.Theme_VolumePanelActivity_Popup,
+ theme = R.style.Theme_VolumePanel_Popup,
dialogGravity = Gravity.BOTTOM,
) {
PopupComposable(it, title, content)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
index 1bf541a..c51e8b0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
@@ -16,40 +16,22 @@
package com.android.systemui.volume.panel.ui.composable
-import androidx.compose.foundation.gestures.detectTapGestures
-import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.WindowInsets
-import androidx.compose.foundation.layout.displayCutout
-import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
-import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.widthIn
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.input.pointer.pointerInput
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.platform.LocalLayoutDirection
-import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.max
-import com.android.compose.theme.PlatformTheme
-import com.android.systemui.res.R
import com.android.systemui.volume.panel.ui.layout.ComponentsLayout
import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelState
import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel
-import kotlin.math.max
private val padding = 24.dp
@@ -67,39 +49,20 @@
}
}
- PlatformTheme(isSystemInDarkTheme()) {
- val state: VolumePanelState by viewModel.volumePanelState.collectAsState()
- val components by viewModel.componentsLayout.collectAsState(null)
+ val state: VolumePanelState by viewModel.volumePanelState.collectAsState()
+ val components by viewModel.componentsLayout.collectAsState(null)
- with(VolumePanelComposeScope(state)) {
- Box(
- modifier =
- modifier
- .fillMaxSize()
- .volumePanelClick(onDismiss)
- .volumePanelPaddings(isPortrait = isPortrait),
- contentAlignment = Alignment.BottomCenter,
- ) {
- val radius = dimensionResource(R.dimen.volume_panel_corner_radius)
- Surface(
- modifier = Modifier.volumePanelClick {},
- shape = RoundedCornerShape(topStart = radius, topEnd = radius),
- color = MaterialTheme.colorScheme.surfaceContainer,
- ) {
- components?.let { componentsState ->
- Components(
- componentsState,
- Modifier.padding(
- start = padding,
- top = padding,
- end = padding,
- bottom = 20.dp,
- )
- .navigationBarsPadding()
- )
- }
- }
- }
+ with(VolumePanelComposeScope(state)) {
+ components?.let { componentsState ->
+ Components(
+ componentsState,
+ modifier.padding(
+ start = padding,
+ top = padding,
+ end = padding,
+ bottom = 20.dp,
+ )
+ )
}
}
}
@@ -116,7 +79,7 @@
if (isPortrait) Arrangement.spacedBy(padding) else Arrangement.spacedBy(4.dp)
}
Column(
- modifier = modifier.widthIn(max = 800.dp),
+ modifier = modifier,
verticalArrangement = arrangement,
) {
if (isPortrait || isLargeScreen) {
@@ -153,38 +116,3 @@
}
}
}
-
-/**
- * Makes sure volume panel stays symmetrically in the middle of the screen while still avoiding
- * being under the cutouts.
- */
-@Composable
-private fun Modifier.volumePanelPaddings(isPortrait: Boolean): Modifier {
- val cutout = WindowInsets.displayCutout
- return with(LocalDensity.current) {
- val horizontalCutout =
- max(
- cutout.getLeft(density = this, layoutDirection = LocalLayoutDirection.current),
- cutout.getRight(density = this, layoutDirection = LocalLayoutDirection.current)
- )
- val minHorizontalPadding = if (isPortrait) 0.dp else 48.dp
- val horizontalPadding = max(horizontalCutout.toDp(), minHorizontalPadding)
-
- padding(
- start = horizontalPadding,
- top = cutout.getTop(this).toDp(),
- end = horizontalPadding,
- bottom = cutout.getBottom(this).toDp(),
- )
- }
-}
-
-/**
- * For some reason adding clickable modifier onto the VolumePanel affects the traversal order:
- * b/331155283.
- *
- * TODO(b/334870995) revert this to Modifier.clickable
- */
-@Composable
-private fun Modifier.volumePanelClick(onClick: () -> Unit) =
- pointerInput(onClick) { detectTapGestures { onClick() } }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index 0f8f1a2..c96a8ce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -38,6 +38,7 @@
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel.Companion.POPUP_AUTO_HIDE_TIMEOUT_MS
+import com.android.systemui.communal.ui.viewmodel.PopupType
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
@@ -247,7 +248,7 @@
tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
val communalContent by collectLastValue(underTest.communalContent)
- val isPopupOnDismissCtaShowing by collectLastValue(underTest.isPopupOnDismissCtaShowing)
+ val currentPopup by collectLastValue(underTest.currentPopup)
assertThat(communalContent?.size).isEqualTo(1)
assertThat(communalContent?.get(0))
@@ -257,11 +258,11 @@
// hide CTA tile and show the popup
assertThat(communalContent).isEmpty()
- assertThat(isPopupOnDismissCtaShowing).isEqualTo(true)
+ assertThat(currentPopup).isEqualTo(PopupType.CtaTile)
// hide popup after time elapsed
advanceTimeBy(POPUP_AUTO_HIDE_TIMEOUT_MS)
- assertThat(isPopupOnDismissCtaShowing).isEqualTo(false)
+ assertThat(currentPopup).isNull()
}
@Test
@@ -269,14 +270,40 @@
testScope.runTest {
tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
- val isPopupOnDismissCtaShowing by collectLastValue(underTest.isPopupOnDismissCtaShowing)
+ val currentPopup by collectLastValue(underTest.currentPopup)
underTest.onDismissCtaTile()
- assertThat(isPopupOnDismissCtaShowing).isEqualTo(true)
+ assertThat(currentPopup).isEqualTo(PopupType.CtaTile)
// dismiss the popup directly
- underTest.onHidePopupAfterDismissCta()
- assertThat(isPopupOnDismissCtaShowing).isEqualTo(false)
+ underTest.onHidePopup()
+ assertThat(currentPopup).isNull()
+ }
+
+ @Test
+ fun customizeWidgetButton_showsThenHidesAfterTimeout() =
+ testScope.runTest {
+ tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
+ val currentPopup by collectLastValue(underTest.currentPopup)
+
+ assertThat(currentPopup).isNull()
+ underTest.onShowCustomizeWidgetButton()
+ assertThat(currentPopup).isEqualTo(PopupType.CustomizeWidgetButton)
+ advanceTimeBy(POPUP_AUTO_HIDE_TIMEOUT_MS)
+ assertThat(currentPopup).isNull()
+ }
+
+ @Test
+ fun customizeWidgetButton_onDismiss_hidesImmediately() =
+ testScope.runTest {
+ tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
+ val currentPopup by collectLastValue(underTest.currentPopup)
+
+ underTest.onShowCustomizeWidgetButton()
+ assertThat(currentPopup).isEqualTo(PopupType.CustomizeWidgetButton)
+
+ underTest.onHidePopup()
+ assertThat(currentPopup).isNull()
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index 11f9e1c..eef2337 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -17,6 +17,9 @@
import android.content.ComponentName
import android.content.Intent
+import android.os.RemoteException
+import android.platform.test.annotations.EnableFlags
+import android.service.dreams.Flags
import android.service.dreams.IDreamOverlay
import android.service.dreams.IDreamOverlayCallback
import android.service.dreams.IDreamOverlayClient
@@ -44,7 +47,9 @@
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.communal.data.repository.FakeCommunalRepository
import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.complication.ComplicationHostViewController
import com.android.systemui.complication.ComplicationLayoutEngine
@@ -57,12 +62,14 @@
import com.android.systemui.touch.TouchInsetManager
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.whenever
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -70,6 +77,9 @@
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.isNull
+import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -87,6 +97,8 @@
private lateinit var lifecycleRegistry: FakeLifecycleRegistry
+ lateinit var mCommunalInteractor: CommunalInteractor
+
private lateinit var mWindowParams: WindowManager.LayoutParams
@Mock lateinit var mDreamOverlayCallback: IDreamOverlayCallback
@@ -162,6 +174,9 @@
whenever(mComplicationComponent.getComplicationHostViewController())
.thenReturn(mComplicationHostViewController)
whenever(mLifecycleOwner.registry).thenReturn(lifecycleRegistry)
+
+ mCommunalInteractor = Mockito.spy(kosmos.communalInteractor)
+
whenever(mComplicationComponentFactory.create(any(), any(), any(), any()))
.thenReturn(mComplicationComponent)
whenever(mComplicationComponent.getVisibilityController())
@@ -192,7 +207,7 @@
mStateController,
mKeyguardUpdateMonitor,
mScrimManager,
- kosmos.communalInteractor,
+ mCommunalInteractor,
mSystemDialogsCloser,
mUiEventLogger,
mTouchInsetManager,
@@ -605,6 +620,57 @@
.isTrue()
}
+ @Test
+ @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT)
+ @kotlin.Throws(RemoteException::class)
+ fun testTransitionToGlanceableHub() =
+ testScope.runTest {
+ // Inform the overlay service of dream starting. Do not show dream complications.
+ client.startDream(
+ mWindowParams,
+ mDreamOverlayCallback,
+ DREAM_COMPONENT,
+ false /*shouldShowComplication*/
+ )
+ mMainExecutor.runAllReady()
+
+ verify(mDreamOverlayCallback).onRedirectWake(false)
+ clearInvocations(mDreamOverlayCallback)
+ kosmos.setCommunalAvailable(true)
+ mMainExecutor.runAllReady()
+ runCurrent()
+ verify(mDreamOverlayCallback).onRedirectWake(true)
+ client.onWakeRequested()
+ verify(mCommunalInteractor).changeScene(eq(CommunalScenes.Communal), isNull())
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT)
+ @Throws(RemoteException::class)
+ fun testRedirectExit() =
+ testScope.runTest {
+ // Inform the overlay service of dream starting. Do not show dream complications.
+ client.startDream(
+ mWindowParams,
+ mDreamOverlayCallback,
+ DREAM_COMPONENT,
+ false /*shouldShowComplication*/
+ )
+ // Set communal available, verify that overlay callback is informed.
+ kosmos.setCommunalAvailable(true)
+ mMainExecutor.runAllReady()
+ runCurrent()
+ verify(mDreamOverlayCallback).onRedirectWake(true)
+
+ clearInvocations(mDreamOverlayCallback)
+
+ // Set communal unavailable, verify that overlay callback is informed.
+ kosmos.setCommunalAvailable(false)
+ mMainExecutor.runAllReady()
+ runCurrent()
+ verify(mDreamOverlayCallback).onRedirectWake(false)
+ }
+
// Tests that the bouncer closes when DreamOverlayService is told that the dream is coming to
// the front.
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index d2a458c..179ba42 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -35,6 +35,7 @@
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
+import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.qs.FooterActionsController
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
@@ -78,6 +79,8 @@
private val sceneBackInteractor = kosmos.sceneBackInteractor
private val sceneContainerStartable = kosmos.sceneContainerStartable
+ private val mediaDataManager = mock<MediaDataManager>()
+
private lateinit var underTest: QuickSettingsSceneViewModel
@OptIn(ExperimentalCoroutinesApi::class)
@@ -97,6 +100,7 @@
footerActionsViewModelFactory = footerActionsViewModelFactory,
footerActionsController = footerActionsController,
sceneBackInteractor = sceneBackInteractor,
+ mediaDataManager = mediaDataManager,
)
}
@@ -230,4 +234,22 @@
verify(footerActionsController, times(1)).init()
}
+
+ @Test
+ fun hasMedia_mediaVisible() {
+ testScope.runTest {
+ whenever(mediaDataManager.hasAnyMediaOrRecommendation()).thenReturn(true)
+
+ assertThat(underTest.isMediaVisible()).isTrue()
+ }
+ }
+
+ @Test
+ fun doesNotHaveMedia_mediaNotVisible() {
+ testScope.runTest {
+ whenever(mediaDataManager.hasAnyMediaOrRecommendation()).thenReturn(false)
+
+ assertThat(underTest.isMediaVisible()).isFalse()
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index a023033..3408e06 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -25,13 +25,12 @@
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX
import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT
-import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.NotificationContainerBounds
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
-import com.android.systemui.flags.BrokenWithSceneContainer
+import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.andSceneContainer
@@ -51,9 +50,8 @@
import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.mockLargeScreenHeaderHelper
+import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
@@ -116,8 +114,8 @@
get() = kosmos.keyguardRootViewModel
val keyguardTransitionRepository
get() = kosmos.fakeKeyguardTransitionRepository
- val shadeRepository
- get() = kosmos.shadeRepository
+ val shadeTestUtil
+ get() = kosmos.shadeTestUtil
val sharedNotificationContainerInteractor
get() = kosmos.sharedNotificationContainerInteractor
val largeScreenHeaderHelper
@@ -127,7 +125,6 @@
@Before
fun setUp() {
- assertThat(SceneContainerFlag.isEnabled).isEqualTo(SceneContainerFlag.isEnabled)
overrideResource(R.bool.config_use_split_notification_shade, false)
movementFlow = MutableStateFlow(BurnInModel())
whenever(aodBurnInViewModel.movement(any())).thenReturn(movementFlow)
@@ -234,7 +231,8 @@
}
@Test
- @DisableFlags(FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX, FLAG_SCENE_CONTAINER)
+ @DisableFlags(FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX)
+ @DisableSceneContainer
fun validateMarginTopWithLargeScreenHeader_refactorFlagOff_usesResource() =
testScope.runTest {
val headerResourceHeight = 50
@@ -273,7 +271,7 @@
}
@Test
- @DisableFlags(FLAG_SCENE_CONTAINER)
+ @DisableSceneContainer
@EnableFlags(FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX)
fun validateMarginTopWithLargeScreenHeader_refactorFlagOn_usesHelper() =
testScope.runTest {
@@ -313,7 +311,6 @@
}
@Test
- @BrokenWithSceneContainer(bugId = 333132830)
fun glanceableHubAlpha_lockscreenToHub() =
testScope.runTest {
val alpha by collectLastValue(underTest.glanceableHubAlpha)
@@ -357,7 +354,7 @@
// While state is GLANCEABLE_HUB, verify alpha is restored to full if glanceable hub is
// not fully visible.
- shadeRepository.setLockscreenShadeExpansion(0.1f)
+ shadeTestUtil.setLockscreenShadeExpansion(0.1f)
assertThat(alpha).isEqualTo(1f)
}
@@ -463,14 +460,13 @@
}
@Test
- @BrokenWithSceneContainer(bugId = 333132830)
fun isOnLockscreenWithoutShade() =
testScope.runTest {
val isOnLockscreenWithoutShade by collectLastValue(underTest.isOnLockscreenWithoutShade)
// First on AOD
- shadeRepository.setLockscreenShadeExpansion(0f)
- shadeRepository.setQsExpansion(0f)
+ shadeTestUtil.setLockscreenShadeExpansion(0f)
+ shadeTestUtil.setQsExpansion(0f)
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
to = KeyguardState.OCCLUDED,
@@ -482,25 +478,24 @@
showLockscreen()
// While state is LOCKSCREEN, validate variations of both shade and qs expansion
- shadeRepository.setLockscreenShadeExpansion(0.1f)
- shadeRepository.setQsExpansion(0f)
+ shadeTestUtil.setQsExpansion(0f)
+ shadeTestUtil.setLockscreenShadeExpansion(0.1f)
assertThat(isOnLockscreenWithoutShade).isFalse()
- shadeRepository.setLockscreenShadeExpansion(0.1f)
- shadeRepository.setQsExpansion(0.1f)
+ shadeTestUtil.setLockscreenShadeExpansion(0.1f)
+ shadeTestUtil.setShadeAndQsExpansion(0.1f, .9f)
assertThat(isOnLockscreenWithoutShade).isFalse()
- shadeRepository.setLockscreenShadeExpansion(0f)
- shadeRepository.setQsExpansion(0.1f)
+ shadeTestUtil.setLockscreenShadeExpansion(0f)
+ shadeTestUtil.setQsExpansion(0.1f)
assertThat(isOnLockscreenWithoutShade).isFalse()
- shadeRepository.setLockscreenShadeExpansion(0f)
- shadeRepository.setQsExpansion(0f)
+ shadeTestUtil.setQsExpansion(0f)
+ shadeTestUtil.setLockscreenShadeExpansion(0f)
assertThat(isOnLockscreenWithoutShade).isTrue()
}
@Test
- @BrokenWithSceneContainer(bugId = 333132830)
fun isOnGlanceableHubWithoutShade() =
testScope.runTest {
val isOnGlanceableHubWithoutShade by
@@ -519,25 +514,25 @@
assertThat(isOnGlanceableHubWithoutShade).isTrue()
// While state is GLANCEABLE_HUB, validate variations of both shade and qs expansion
- shadeRepository.setLockscreenShadeExpansion(0.1f)
- shadeRepository.setQsExpansion(0f)
+ shadeTestUtil.setQsExpansion(0f)
+ shadeTestUtil.setLockscreenShadeExpansion(0.1f)
assertThat(isOnGlanceableHubWithoutShade).isFalse()
- shadeRepository.setLockscreenShadeExpansion(0.1f)
- shadeRepository.setQsExpansion(0.1f)
+ shadeTestUtil.setLockscreenShadeExpansion(0.1f)
+ shadeTestUtil.setShadeAndQsExpansion(0.1f, .9f)
assertThat(isOnGlanceableHubWithoutShade).isFalse()
- shadeRepository.setLockscreenShadeExpansion(0f)
- shadeRepository.setQsExpansion(0.1f)
+ shadeTestUtil.setLockscreenShadeExpansion(0f)
+ shadeTestUtil.setQsExpansion(0.1f)
assertThat(isOnGlanceableHubWithoutShade).isFalse()
- shadeRepository.setLockscreenShadeExpansion(0f)
- shadeRepository.setQsExpansion(0f)
+ shadeTestUtil.setQsExpansion(0f)
+ shadeTestUtil.setLockscreenShadeExpansion(0f)
assertThat(isOnGlanceableHubWithoutShade).isTrue()
}
@Test
- @DisableFlags(FLAG_SCENE_CONTAINER)
+ @DisableSceneContainer
fun boundsOnLockscreenNotInSplitShade() =
testScope.runTest {
val bounds by collectLastValue(underTest.bounds)
@@ -558,7 +553,8 @@
}
@Test
- @DisableFlags(FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX, FLAG_SCENE_CONTAINER)
+ @DisableFlags(FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX)
+ @DisableSceneContainer
fun boundsOnLockscreenInSplitShade_refactorFlagOff_usesLargeHeaderResource() =
testScope.runTest {
val bounds by collectLastValue(underTest.bounds)
@@ -593,7 +589,7 @@
@Test
@EnableFlags(FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX)
- @DisableFlags(FLAG_SCENE_CONTAINER)
+ @DisableSceneContainer
fun boundsOnLockscreenInSplitShade_refactorFlagOn_usesLargeHeaderHelper() =
testScope.runTest {
val bounds by collectLastValue(underTest.bounds)
@@ -621,7 +617,7 @@
}
@Test
- @DisableFlags(FLAG_SCENE_CONTAINER)
+ @DisableSceneContainer
fun boundsOnShade() =
testScope.runTest {
val bounds by collectLastValue(underTest.bounds)
@@ -637,7 +633,7 @@
}
@Test
- @DisableFlags(FLAG_SCENE_CONTAINER)
+ @DisableSceneContainer
fun boundsOnQS() =
testScope.runTest {
val bounds by collectLastValue(underTest.bounds)
@@ -682,7 +678,6 @@
}
@Test
- @BrokenWithSceneContainer(bugId = 333132830)
fun maxNotificationsOnLockscreen_DoesNotUpdateWhenUserInteracting() =
testScope.runTest {
var notificationCount = 10
@@ -700,26 +695,25 @@
assertThat(maxNotifications).isEqualTo(10)
// Shade expanding... still 10
- shadeRepository.setLockscreenShadeExpansion(0.5f)
+ shadeTestUtil.setLockscreenShadeExpansion(0.5f)
assertThat(maxNotifications).isEqualTo(10)
notificationCount = 25
// When shade is expanding by user interaction
- shadeRepository.setLegacyLockscreenShadeTracking(true)
+ shadeTestUtil.setLockscreenShadeTracking(true)
// Should still be 10, since the user is interacting
assertThat(maxNotifications).isEqualTo(10)
- shadeRepository.setLegacyLockscreenShadeTracking(false)
- shadeRepository.setLockscreenShadeExpansion(0f)
+ shadeTestUtil.setLockscreenShadeTracking(false)
+ shadeTestUtil.setLockscreenShadeExpansion(0f)
// Stopped tracking, show 25
assertThat(maxNotifications).isEqualTo(25)
}
@Test
- @BrokenWithSceneContainer(bugId = 333132830)
fun maxNotificationsOnShade() =
testScope.runTest {
val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> 10 }
@@ -739,7 +733,7 @@
}
@Test
- @DisableFlags(FLAG_SCENE_CONTAINER)
+ @DisableSceneContainer
fun translationYUpdatesOnKeyguardForBurnIn() =
testScope.runTest {
val translationY by collectLastValue(underTest.translationY(BurnInParameters()))
@@ -752,7 +746,7 @@
}
@Test
- @DisableFlags(FLAG_SCENE_CONTAINER)
+ @DisableSceneContainer
fun translationYUpdatesOnKeyguard() =
testScope.runTest {
val translationY by collectLastValue(underTest.translationY(BurnInParameters()))
@@ -764,7 +758,7 @@
configurationRepository.onAnyConfigurationChange()
// legacy expansion means the user is swiping up, usually for the bouncer
- shadeRepository.setLegacyShadeExpansion(0.5f)
+ shadeTestUtil.setShadeExpansion(0.5f)
showLockscreen()
@@ -773,7 +767,7 @@
}
@Test
- @DisableFlags(FLAG_SCENE_CONTAINER)
+ @DisableSceneContainer
fun translationYDoesNotUpdateWhenShadeIsExpanded() =
testScope.runTest {
val translationY by collectLastValue(underTest.translationY(BurnInParameters()))
@@ -786,7 +780,7 @@
// legacy expansion means the user is swiping up, usually for the bouncer but also for
// shade collapsing
- shadeRepository.setLegacyShadeExpansion(0.5f)
+ shadeTestUtil.setShadeExpansion(0.5f)
showLockscreenWithShadeExpanded()
@@ -794,7 +788,7 @@
}
@Test
- @DisableFlags(FLAG_SCENE_CONTAINER)
+ @DisableSceneContainer
fun updateBounds_fromKeyguardRoot() =
testScope.runTest {
val bounds by collectLastValue(underTest.bounds)
@@ -806,7 +800,6 @@
}
@Test
- @BrokenWithSceneContainer(bugId = 333132830)
fun alphaOnFullQsExpansion() =
testScope.runTest {
val viewState = ViewStateAccessor()
@@ -815,13 +808,13 @@
showLockscreenWithQSExpanded()
// Alpha fades out as QS expands
- shadeRepository.setQsExpansion(0.5f)
+ shadeTestUtil.setQsExpansion(0.5f)
assertThat(alpha).isWithin(0.01f).of(0.5f)
- shadeRepository.setQsExpansion(0.9f)
+ shadeTestUtil.setQsExpansion(0.9f)
assertThat(alpha).isWithin(0.01f).of(0.1f)
// Ensure that alpha is set back to 1f when QS is fully expanded
- shadeRepository.setQsExpansion(1f)
+ shadeTestUtil.setQsExpansion(1f)
assertThat(alpha).isEqualTo(1f)
}
@@ -856,7 +849,7 @@
assertThat(alpha).isEqualTo(0f)
// An attempt to override by the shade should be ignored
- shadeRepository.setQsExpansion(0.5f)
+ shadeTestUtil.setQsExpansion(0.5f)
assertThat(alpha).isEqualTo(0f)
}
@@ -891,7 +884,7 @@
assertThat(alpha).isEqualTo(0f)
// An attempt to override by the shade should be ignored
- shadeRepository.setQsExpansion(0.5f)
+ shadeTestUtil.setQsExpansion(0.5f)
assertThat(alpha).isEqualTo(0f)
}
@@ -914,7 +907,6 @@
}
@Test
- @BrokenWithSceneContainer(bugId = 333132830)
fun shadeCollapseFadeIn() =
testScope.runTest {
val fadeIn by collectValues(underTest.shadeCollapseFadeIn)
@@ -961,8 +953,8 @@
}
private suspend fun TestScope.showLockscreen() {
- shadeRepository.setLockscreenShadeExpansion(0f)
- shadeRepository.setQsExpansion(0f)
+ shadeTestUtil.setQsExpansion(0f)
+ shadeTestUtil.setLockscreenShadeExpansion(0f)
runCurrent()
keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
runCurrent()
@@ -974,8 +966,8 @@
}
private suspend fun TestScope.showDream() {
- shadeRepository.setLockscreenShadeExpansion(0f)
- shadeRepository.setQsExpansion(0f)
+ shadeTestUtil.setQsExpansion(0f)
+ shadeTestUtil.setLockscreenShadeExpansion(0f)
runCurrent()
keyguardRepository.setDreaming(true)
runCurrent()
@@ -987,8 +979,8 @@
}
private suspend fun TestScope.showLockscreenWithShadeExpanded() {
- shadeRepository.setLockscreenShadeExpansion(1f)
- shadeRepository.setQsExpansion(0f)
+ shadeTestUtil.setQsExpansion(0f)
+ shadeTestUtil.setLockscreenShadeExpansion(1f)
runCurrent()
keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED)
runCurrent()
@@ -1000,8 +992,8 @@
}
private suspend fun TestScope.showLockscreenWithQSExpanded() {
- shadeRepository.setLockscreenShadeExpansion(0f)
- shadeRepository.setQsExpansion(1f)
+ shadeTestUtil.setLockscreenShadeExpansion(0f)
+ shadeTestUtil.setQsExpansion(1f)
runCurrent()
keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED)
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/EventsTest.java
similarity index 96%
rename from packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/volume/EventsTest.java
index c69f5c8..87e1f86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/EventsTest.java
@@ -34,12 +34,15 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
import java.util.Queue;
+import platform.test.runner.parameterized.Parameter;
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
/**
* Parameterized unit test for Events.logEvent.
*
@@ -51,7 +54,7 @@
* either SysuiTestCase or SysUiBaseFragmentTest.
*
*/
-@RunWith(Parameterized.class)
+@RunWith(ParameterizedAndroidJunit4.class)
@SmallTest
public class EventsTest extends SysuiTestCase {
private FakeMetricsLogger mLegacyLogger;
@@ -66,23 +69,23 @@
}
// Parameters for calling writeEvent with arbitrary args.
- @Parameterized.Parameter
+ @Parameter
public int mTag;
- @Parameterized.Parameter(1)
+ @Parameter(1)
public Object[] mArgs;
// Expect returned string exactly matches.
- @Parameterized.Parameter(2)
+ @Parameter(2)
public String mExpectedMessage;
// Expect these MetricsLogger calls.
- @Parameterized.Parameter(3)
+ @Parameter(3)
public int[] mExpectedMetrics;
// Expect this UiEvent (use null if there isn't one).
- @Parameterized.Parameter(4)
+ @Parameter(4)
public UiEventLogger.UiEventEnum mUiEvent;
@Test
@@ -108,7 +111,10 @@
}
}
- @Parameterized.Parameters(name = "{index}: {2}")
+ /**
+ * Collection of parameters for the test.
+ */
+ @Parameters(name = "{index}: {2}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{Events.EVENT_SETTINGS_CLICK, null,
@@ -217,4 +223,3 @@
});
}
}
-
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/UtilTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/UtilTest.java
similarity index 95%
rename from packages/SystemUI/tests/src/com/android/systemui/volume/UtilTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/volume/UtilTest.java
index 483dc0c..d6c63af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/UtilTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/UtilTest.java
@@ -19,13 +19,16 @@
import android.media.MediaMetadata;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import org.junit.Test;
+import org.junit.runner.RunWith;
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class UtilTest extends SysuiTestCase {
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt
index 910f71e..818c19c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt
@@ -55,6 +55,7 @@
underTest =
VolumePanelViewModel(
testableResources.resources,
+ kosmos.testScope.backgroundScope,
KosmosVolumePanelComponentFactory(kosmos),
kosmos.fakeConfigurationController,
)
diff --git a/packages/SystemUI/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml
index 5d9345b..a89dd7b 100644
--- a/packages/SystemUI/res-product/values-or/strings.xml
+++ b/packages/SystemUI/res-product/values-or/strings.xml
@@ -30,9 +30,9 @@
<string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="2594813176164266847">"ଆପଣ ଫୋନ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ଏହି ଫୋନ୍କୁ ରିସେଟ୍ କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ଏହାର ସମସ୍ତ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="8710104080409538587">"ଆପଣ ଟାବ୍ଲେଟ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଟାବ୍ଲେଟ୍ଟି ରିସେଟ୍ କରିଦିଆଯିବ, ଫଳରେ ଏହାର ସମସ୍ତ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"ଆପଣ ଫୋନ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଫୋନ୍ଟି ରିସେଟ୍ କରିଦିଆଯିବ, ଫଳରେ ଏହାର ସମସ୍ତ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"ଆପଣ ଟାବ୍ଲେଟ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ଏହି ଉପଯୋଗକର୍ତ୍ତା ପ୍ରୋଫାଇଲ୍କୁ କାଢ଼ିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
- <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"ଆପଣ ଫୋନ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ଏହି ଉପଯୋଗକର୍ତ୍ତା ପ୍ରୋଫାଇଲ୍କୁ କାଢ଼ିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
- <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ଆପଣ ଟାବ୍ଲେଟ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଭୁଲ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜର ପ୍ରୋଫାଇଲ୍କୁ କାଢ଼ି ଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"ଆପଣ ଫୋନକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଭୁଲ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜର ପ୍ରୋଫାଇଲକୁ କାଢ଼ି ଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ୟୁଜରଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
<string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"ଆପଣ ଫୋନ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ୍ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
<string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"ଆପଣ ଟାବ୍ଲେଟ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
<string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"ଆପଣ ଫୋନ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
diff --git a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
index 8e3cf4d..91ca69e 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
@@ -47,7 +47,7 @@
android:layout_height="wrap_content"
android:fillViewport="true"
android:fadeScrollbars="false"
- android:paddingBottom="36dp"
+ android:paddingBottom="24dp"
android:paddingHorizontal="24dp"
android:paddingTop="24dp"
app:layout_constrainedHeight="true"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 63c6132..799b88a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -458,8 +458,7 @@
<string name="work_mode_off_title" msgid="5794818421357835873">"Hervat werkapps?"</string>
<string name="work_mode_turn_on" msgid="907813741770247267">"Hervat"</string>
<string name="accessibility_action_label_close_communal_hub" msgid="6790396569621032333">"Maak legstukke op sluitskerm toe"</string>
- <!-- no translation found for accessibility_action_label_edit_widgets (3821868581348322346) -->
- <skip />
+ <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Pasmaak legstukke"</string>
<string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Legstukke op sluitskerm"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Wissel gebruiker"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aftrekkieslys"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliet, swak verbinding"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goeie toestand"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding is beskikbaar"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Werkprofiel"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Pret vir party mense, maar nie vir almal nie"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Stelsel-UI-ontvanger gee jou ekstra maniere om die Android-gebruikerkoppelvlak in te stel en te pasmaak. Hierdie eksperimentele kenmerke kan in toekomstige uitreikings verander, breek of verdwyn. Gaan versigtig voort."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 1c80547..6db4e02 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ሳተላይት፣ ደካማ ግንኙነት"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ሳተላይት፣ ጥሩ ግንኙነት"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ሳተላይት፣ ግንኙነት አለ"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"የስራ መገለጫ"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"ለአንዳንዶች አስደሳች ቢሆንም ለሁሉም አይደለም"</string>
<string name="tuner_warning" msgid="1861736288458481650">"የስርዓት በይነገጽ መቃኛ የAndroid ተጠቃሚ በይነገጹን የሚነካኩበት እና የሚያበጁበት ተጨማሪ መንገዶች ይሰጠዎታል። እነዚህ የሙከራ ባህሪዎች ወደፊት በሚኖሩ ልቀቶች ላይ ሊለወጡ፣ ሊሰበሩ ወይም ሊጠፉ ይችላሉ። ከጥንቃቄ ጋር ወደፊት ይቀጥሉ።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c92a32b..7f89ab49 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"قمر صناعي، الاتصال ضعيف"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"قمر صناعي، الاتصال جيد"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"قمر صناعي، الاتصال متوفّر"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ملف العمل"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"متعة للبعض وليس للجميع"</string>
<string name="tuner_warning" msgid="1861736288458481650">"توفر لك أداة ضبط واجهة مستخدم النظام طرقًا إضافية لتعديل واجهة مستخدم Android وتخصيصها. ويمكن أن تطرأ تغييرات على هذه الميزات التجريبية أو يمكن أن تتعطل هذه الميزات أو تختفي في الإصدارات المستقبلية. عليك متابعة الاستخدام مع توخي الحذر."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index f1291a0..c2dc3b0 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"উপগ্ৰহ, বেয়া সংযোগ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"উপগ্ৰহ, ভাল সংযোগ"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"উপগ্ৰহ, সংযোগ উপলব্ধ"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"কিছুমানৰ বাবে আমোদজনক হয় কিন্তু সকলোৰে বাবে নহয়"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tunerএ আপোনাক Android ব্যৱহাৰকাৰী ইণ্টাৰফেইচ সলনি কৰিবলৈ আৰু নিজৰ উপযোগিতা অনুসৰি ব্যৱহাৰ কৰিবলৈ অতিৰিক্ত সুবিধা প্ৰদান কৰে। এই পৰীক্ষামূলক সুবিধাসমূহ সলনি হ\'ব পাৰে, সেইবোৰে কাম নকৰিব পাৰে বা আগন্তুক সংস্কৰণসমূহত সেইবোৰ অন্তৰ্ভুক্ত কৰা নহ’ব পাৰে। সাৱধানেৰে আগবাঢ়ক।"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index b12d822..853a020 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Peyk, bağlantı zəifdir"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Peyk, bağlantı yaxşıdır"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Peyk, bağlantı var"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"İş profili"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Hamı üçün deyil, bəziləri üçün əyləncəli"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner Android istifadəçi interfeysini dəyişdirmək və fərdiləşdirmək üçün Sizə ekstra yollar təklif edir."</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 221d16c..80cc48f 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Slušni aparati"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Upari novi uređaj"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili nov uređaj"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadatih podešavanja nije uspelo"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite da odblokirate mikrofon uređaja?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite da odblokirate kameru uređaja?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite da odblokirate kameru i mikrofon uređaja?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, veza je loša"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, veza je dobra"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Poslovni profil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Tjuner za korisnički interfejs sistema vam pruža dodatne načine za podešavanje i prilagođavanje Android korisničkog interfejsa. Ove eksperimentalne funkcije mogu da se promene, otkažu ili nestanu u budućim izdanjima. Budite oprezni."</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index d1c4a98..d64ffe8 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спадарожнікавая сувязь, дрэннае падключэнне"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спадарожнікавая сувязь, добрае падключэнне"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спадарожнікавая сувязь, падключэнне даступнае"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Працоўны профіль"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Цікава для некаторых, але не для ўсіх"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Наладка сістэмнага інтэрфейсу карыстальніка дае вам дадатковыя спосабы наладжвання і дапасоўвання карыстальніцкага інтэрфейсу Android. Гэтыя эксперыментальныя функцыі могуць змяніцца, перастаць працаваць або знікнуць у будучых версіях. Карыстайцеся з асцярожнасцю."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 62d3fed..b3321f5 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Сателит, лоша връзка"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, добра връзка"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, налице е връзка"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Потребителски профил в Work"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Забавно – но не за всички"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Тунерът на системния потребителски интерфейс ви предоставя допълнителни възможности за прецизиране и персонализиране на практическата работа с Android. Тези експериментални функции може да се променят, повредят или да изчезнат в бъдещите версии. Действайте внимателно."</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 81e3fc4..5c3d96b 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"স্যাটেলাইট, খারাপ কানেকশন"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"স্যাটেলাইট, ভালো কানেকশন"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"স্যাটেলাইট, কানেকশন উপলভ্য আছে"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"কাজের প্রোফাইল"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"কিছু ব্যক্তির জন্য মজাদার কিন্তু সকলের জন্য নয়"</string>
<string name="tuner_warning" msgid="1861736288458481650">"এই পরীক্ষামূলক বৈশিষ্ট্যগুলি ভবিষ্যতের সংস্করণগুলির মধ্যে পরিবর্তিত, বিভাজিত এবং অদৃশ্য হয়ে যেতে পারে৷ সাবধানতার সাথে এগিয়ে যান৷ সিস্টেম UI টিউনার আপনাকে Android ব্যবহারকারী ইন্টারফেসের সূক্ষ্ম সমন্বয় এবং কাস্টমাইজ করার অতিরিক্ত উপায়গুলি প্রদান করে৷"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 7d66851..f3ffe26 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -235,8 +235,8 @@
<string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Obavještenja sa sjenčenjem."</string>
<string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brze postavke."</string>
<string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Brze postavke i lokacija za obavještenja."</string>
- <string name="accessibility_desc_lock_screen" msgid="409034672704273634">"Zaključavanje ekrana"</string>
- <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan ekran radnog profila"</string>
+ <string name="accessibility_desc_lock_screen" msgid="409034672704273634">"Zaključani ekran"</string>
+ <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključani ekran radnog profila"</string>
<string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"potpuna tišina"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"samo alarmi"</string>
@@ -643,7 +643,7 @@
<string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ažuriranje"</string>
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključajte da koristite"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Došlo je do problema prilikom preuzimanja vaših kartica. Pokušajte ponovo kasnije"</string>
- <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Postavke zaključavanja ekrana"</string>
+ <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Postavke zaključanog ekrana"</string>
<string name="qr_code_scanner_title" msgid="1938155688725760702">"Skener QR koda"</string>
<string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Ažuriranje"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Radni profil"</string>
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slaba veza"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Radni profil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Podešavač za korisnički interfejs sistema vam omogućava dodatne načine da podesite i prilagodite Androidov interfejs. Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string>
@@ -775,7 +779,7 @@
<string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvaranje liste aplikacija"</string>
<string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvaranje postavki"</string>
<string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvaranje Asistenta"</string>
- <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključavanje ekrana"</string>
+ <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključani ekran"</string>
<string name="group_system_quick_memo" msgid="3764560265935722903">"Pisanje bilješke"</string>
<string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Multitasking"</string>
<string name="system_multitasking_rhs" msgid="8714224917276297810">"Korištenje podijeljenog ekrana s trenutnom aplikacijom na desnoj strani"</string>
@@ -1275,8 +1279,8 @@
<string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređite na radni profil"</string>
<string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalirajte poslovnu aplikaciju za telefon"</string>
<string name="call_from_work_profile_close" msgid="5830072964434474143">"Otkaži"</string>
- <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključavanje ekrana"</string>
- <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da prilagodite zaključavanje ekrana"</string>
+ <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključani ekran"</string>
+ <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da prilagodite zaključani ekran"</string>
<string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi mreža nije dostupna"</string>
<string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
<string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera i mikrofon su blokirani"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 87af353..341dca5 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Audiòfons"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Vincula un dispositiu nou"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fes clic per vincular un dispositiu nou"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"No s\'ha pogut actualitzar el valor predefinit"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vols desbloquejar el micròfon del dispositiu?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vols desbloquejar la càmera del dispositiu?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vols desbloquejar la càmera i el micròfon del dispositiu?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satèl·lit, connexió deficient"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satèl·lit, bona connexió"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satèl·lit, connexió disponible"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de treball"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diversió per a uns quants, però no per a tothom"</string>
<string name="tuner_warning" msgid="1861736288458481650">"El Personalitzador d\'interfície d\'usuari presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 102768f..ad5a76ac 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, špatné připojení"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobré připojení"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, připojení je k dispozici"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Pracovní profil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Zábava, která není pro každého"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Nástroj na ladění uživatelského rozhraní systému vám nabízí další způsoby, jak si vyladit a přizpůsobit uživatelské rozhraní Android. Tyto experimentální funkce mohou v dalších verzích chybět, nefungovat nebo být změněny. Postupujte proto prosím opatrně."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index d3138ab..f65364f 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellit – dårlig forbindelse"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit – god forbindelse"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit – forbindelsen er tilgængelig"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Arbejdsprofil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Sjovt for nogle, men ikke for alle"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner giver dig flere muligheder for at justere og tilpasse Android-brugerfladen. Disse eksperimentelle funktioner kan ændres, gå i stykker eller forsvinde i fremtidige udgivelser. Vær forsigtig, hvis du fortsætter."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 03d04a6..3161b86 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellit, Verbindung schlecht"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, Verbindung gut"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, Verbindung verfügbar"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Arbeitsprofil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Für einige ein Vergnügen, aber nicht für alle"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Mit System UI Tuner erhältst du zusätzliche Möglichkeiten, die Android-Benutzeroberfläche anzupassen. Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 89092ad..33dc496 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Δορυφορική, κακή σύνδεση"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Δορυφορική, καλή σύνδεση"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Δορυφορική, διαθέσιμη σύνδεση"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Προφίλ εργασίας"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Διασκέδαση για ορισμένους, αλλά όχι για όλους"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Το System UI Tuner σάς προσφέρει επιπλέον τρόπους για να τροποποιήσετε και να προσαρμόσετε τη διεπαφή χρήστη Android. Αυτές οι πειραματικές λειτουργίες ενδέχεται να τροποποιηθούν, να παρουσιάσουν σφάλματα ή να καταργηθούν σε μελλοντικές εκδόσεις. Συνεχίστε με προσοχή."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 459de64..e0786ce 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 4879850..8b71d4b 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -654,6 +654,8 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
+ <string name="satellite_connected_carrier_text" msgid="7942466244369263272">"Connected to satellite"</string>
+ <string name="satellite_not_connected_carrier_text" msgid="3471375076594005077">"Not connected to satellite"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customize the Android user interface. These experimental features may change, break, or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 459de64..e0786ce 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 459de64..e0786ce 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index a2340bd..f32b774 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -654,6 +654,8 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
+ <string name="satellite_connected_carrier_text" msgid="7942466244369263272">"Connected to satellite"</string>
+ <string name="satellite_not_connected_carrier_text" msgid="3471375076594005077">"Not connected to satellite"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customize the Android user interface. These experimental features may change, break, or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 202bd93..3b6f249 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, conexión inestable"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diversión para algunos, pero no para todos"</string>
<string name="tuner_warning" msgid="1861736288458481650">"El sintonizador de IU del sistema te brinda más formas para editar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, dejar de funcionar o no incluirse en futuras versiones. Procede con precaución."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 88fab2d..42d403d 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, mala conexión"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diversión solo para algunos"</string>
<string name="tuner_warning" msgid="1861736288458481650">"El configurador de UI del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 1b4cea7..f3c75a4 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Kuuldeseadmed"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Uue seadme sidumine"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Uue seadme sidumiseks klõpsake"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Eelseadistust ei saanud värskendada"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kas tühistada seadme mikrofoni blokeerimine?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kas tühistada seadme kaamera blokeerimine?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kas tühistada seadme kaamera ja mikrofoni blokeerimine?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliit, kehv ühendus"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliit, hea ühendus"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliit, ühendus on saadaval"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Tööprofiil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Kõik ei pruugi sellest rõõmu tunda"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Süsteemi kasutajaliidese tuuner pakub täiendavaid võimalusi Androidi kasutajaliidese muutmiseks ja kohandamiseks. Need katselised funktsioonid võivad muutuda, rikki minna või tulevastest versioonidest kaduda. Olge jätkamisel ettevaatlik."</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index b69ef30..da885b7 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelitea, konexio ahula"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelitea, konexio ona"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelitea, konexioa erabilgarri"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Laneko profila"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Dibertsioa batzuentzat, baina ez guztientzat"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Sistemaren erabiltzaile-interfazearen konfiguratzaileak Android erabiltzaile-interfazea moldatzeko eta pertsonalizatzeko modu gehiago eskaintzen dizkizu. Baliteke eginbide esperimental horiek hurrengo kaleratzeetan aldatuta, etenda edo desagertuta egotea. Kontuz erabili."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 94fb12f..b63ec78 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ماهواره، اتصال ضعیف است"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ماهواره، اتصال خوب است"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ماهواره، اتصال دردسترس است"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"نمایه کاری"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"برای بعضی افراد سرگرمکننده است اما نه برای همه"</string>
<string name="tuner_warning" msgid="1861736288458481650">"«تنظیمکننده واسط کاربری سیستم» روشهای بیشتری برای تنظیم دقیق و سفارشی کردن واسط کاربری Android در اختیار شما قرار میدهد. ممکن است این ویژگیهای آزمایشی تغییر کنند، خراب شوند یا در نسخههای آینده جود نداشته باشند. با احتیاط ادامه دهید."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index a7754b0..21df7c7 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Kuulolaitteet"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Muodosta uusi laitepari"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Muodosta uusi laitepari klikkaamalla"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Esiasetusta ei voitu muuttaa"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kumotaanko laitteen mikrofonin esto?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kumotaanko laitteen kameran esto?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kumotaanko laitteen kameran ja mikrofonin esto?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliitti, huono yhteys"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliitti, hyvä yhteys"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliitti, yhteys saatavilla"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Työprofiili"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Ei sovellu kaikkien käyttöön"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner antaa lisämahdollisuuksia Android-käyttöliittymän muokkaamiseen. Nämä kokeelliset ominaisuudet voivat muuttua, lakata toimimasta tai kadota milloin tahansa. Jatka omalla vastuullasi."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5bacaaa..850f977 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Connexion satellite faible"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite accessible"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil professionnel"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Divertissant pour certains, mais pas pour tous"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur d\'Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index a4a039f1..0df8988 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Appareils auditifs"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Associer un nouvel appareil"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquer pour associer un nouvel appareil"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour les préréglages"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le micro de l\'appareil ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer la caméra de l\'appareil ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le micro de l\'appareil ?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Mauvaise connexion satellite"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite disponible"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil professionnel"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Divertissant pour certains, mais pas pour tous"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index e2b1e53..10e8601 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, mala conexión"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa conexión"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión dispoñible"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de traballo"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diversión só para algúns"</string>
<string name="tuner_warning" msgid="1861736288458481650">"O configurador da IU do sistema ofréceche formas adicionais de modificar e personalizar a interface de usuario de Android. Estas funcións experimentais poden cambiar, interromperse ou desaparecer en futuras versións. Continúa con precaución."</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 2883cc5..ebfe6f7 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"સૅટલાઇટ, નબળું કનેક્શન"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"સૅટલાઇટ, સારું કનેક્શન"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"સૅટલાઇટ, કનેક્શન ઉપલબ્ધ છે"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ઑફિસની પ્રોફાઇલ"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"કેટલાક માટે મજા પરંતુ બધા માટે નહીં"</string>
<string name="tuner_warning" msgid="1861736288458481650">"સિસ્ટમ UI ટ્યૂનર તમને Android વપરાશકર્તા ઇન્ટરફેસને ટ્વીક અને કસ્ટમાઇઝ કરવાની વધારાની રીતો આપે છે. ભાવિ રીલિઝેસમાં આ પ્રાયોગિક સુવિધાઓ બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. સાવધાની સાથે આગળ વધો."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f30957d..ea50302 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"कान की मशीनें"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"नया डिवाइस जोड़ें"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नया डिवाइस जोड़ने के लिए क्लिक करें"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट नहीं किया जा सका"</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>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"सैटलाइट कनेक्शन खराब है"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सैटलाइट कनेक्शन अच्छा है"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सैटलाइट कनेक्शन उपलब्ध है"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"वर्क प्रोफ़ाइल"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"कुछ के लिए मज़ेदार लेकिन सबके लिए नहीं"</string>
<string name="tuner_warning" msgid="1861736288458481650">"सिस्टम यूज़र इंटरफ़ेस (यूआई) ट्यूनर, आपको Android यूज़र इंटरफ़ेस में सुधार लाने और उसे अपनी पसंद के हिसाब से बदलने के कुछ और तरीके देता है. प्रयोग के तौर पर इस्तेमाल हो रहीं ये सुविधाएं आगे चल कर रिलीज़ की जा सकती हैं, रोकी जा सकती हैं या दिखाई देना बंद हो सकती हैं. सावधानी से आगे बढ़ें."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index bada67e..b1849c5 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slaba veza"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Poslovni profil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Ugađanje korisničkog sučelja sustava pruža vam dodatne načine za prilagodbu korisničkog sučelja Androida. Te se eksperimentalne značajke mogu promijeniti, prekinuti ili nestati u budućim izdanjima. Nastavite uz oprez."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index d216fa4..ddae886 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Hallókészülékek"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Új eszköz párosítása"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kattintson új eszköz párosításához"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nem sikerült frissíteni a beállításkészletet"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Feloldja az eszköz mikrofonjának letiltását?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Feloldja az eszköz kamerájának letiltását?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Feloldja az eszköz kamerájának és mikrofonjának letiltását?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Műhold, gyenge kapcsolat"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Műhold, jó kapcsolat"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Műhold, van rendelkezésre álló kapcsolat"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Munkaprofil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Egyeseknek tetszik, másoknak nem"</string>
<string name="tuner_warning" msgid="1861736288458481650">"A Kezelőfelület-hangoló az Android felhasználói felületének szerkesztéséhez és testreszabásához nyújt további megoldásokat. Ezek a kísérleti funkciók változhatnak vagy megsérülhetnek a későbbi kiadásokban, illetve eltűnhetnek azokból. Körültekintően járjon el."</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 034ac1a..717732d 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Արբանյակային թույլ կապ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Արբանյակային լավ կապ"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Հասանելի է արբանյակային կապ"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Աշխատանքային պրոֆիլ"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Զվարճանք մեկ՝ որոշակի մարդու համար"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Համակարգի ՕՄ-ի կարգավորիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտատիրոջ միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index d428ef8..d5e353a 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, koneksi buruk"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, koneksi baik"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, koneksi tersedia"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil kerja"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Tidak semua orang menganggapnya baik"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Penyetel Antarmuka Pengguna Sistem memberikan cara tambahan untuk mengubah dan menyesuaikan antarmuka pengguna Android. Fitur eksperimental ini dapat berubah, rusak, atau menghilang dalam rilis di masa mendatang. Lanjutkan dengan hati-hati."</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 4b97299..2087907 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Heyrnartæki"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Para nýtt tæki"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Smelltu til að para nýtt tæki"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tókst ekki að uppfæra forstillingu"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Opna fyrir hljóðnema tækisins?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Opna fyrir myndavél tækisins?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Opna fyrir myndavél og hljóðnema tækisins?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Gervihnöttur, léleg tenging"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Gervihnöttur, góð tenging"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Gervihnöttur, tenging tiltæk"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Vinnusnið"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Þetta er ekki allra"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Fínstillingar kerfisviðmóts gera þér kleift að fínstilla og sérsníða notendaviðmót Android. Þessir tilraunaeiginleikar geta breyst, bilað eða horfið í síðari útgáfum. Gakktu því hægt um gleðinnar dyr."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 30bdfae..32f72fd 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellitare, connessione debole"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitare, connessione buona"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitare, connessione disponibile"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Profilo di lavoro"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Il divertimento riservato a pochi eletti"</string>
<string name="tuner_warning" msgid="1861736288458481650">"L\'Ottimizzatore UI di sistema mette a disposizione altri metodi per modificare e personalizzare l\'interfaccia utente di Android. Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index bc1d91f..13f2e50 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"לוויין, חיבור באיכות ירודה"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"לוויין, חיבור באיכות טובה"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"לוויין, יש חיבור זמין"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"פרופיל עבודה"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"מהנה בשביל חלק מהאנשים, אבל לא בשביל כולם"</string>
<string name="tuner_warning" msgid="1861736288458481650">"התכונה System UI Tuner מספקת לך דרכים נוספות להתאים אישית את ממשק המשתמש של Android. התכונות הניסיוניות האלה עשויות להשתנות, לא לעבוד כראוי או להיעלם בגרסאות עתידיות. יש להמשיך בזהירות."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b587f40..b31c01c 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"衛生、接続不安定"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛生、接続状態良好"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛生、接続利用可能"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"仕事用プロファイル"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"一部の方のみお楽しみいただける限定公開ツール"</string>
<string name="tuner_warning" msgid="1861736288458481650">"システムUI調整ツールでは、Androidユーザーインターフェースの調整やカスタマイズを行えます。これらの試験運用機能は今後のリリースで変更となったり、中止となったり、削除されたりする可能性がありますのでご注意ください。"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index ff11d85..654acef 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"სუსტი სატელიტური კავშირი"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"კარგი სატელიტური კავშირი"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ხელმისაწვდომია სატელიტური კავშირი"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"სამსახურის პროფილი"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"ზოგისთვის გასართობია, მაგრამ არა ყველასთვის"</string>
<string name="tuner_warning" msgid="1861736288458481650">"სისტემის UI ტუნერი გაძლევთ დამატებით გზებს Android-ის სამომხმარებლო ინტერფეისის პარამეტრების დაყენებისთვის. ეს ექსპერიმენტული მახასიათებლები შეიძლება შეიცვალოს, შეწყდეს ან გაქრეს მომავალ ვერსიებში. სიფრთხილით გააგრძელეთ."</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 995a796..0fda9f1 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Жерсерік, байланыс нашар."</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Жерсерік, байланыс жақсы."</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Жерсерік, байланыс бар."</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Жұмыс профилі"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Кейбіреулерге қызық, бірақ барлығына емес"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Жүйелік пайдаланушылық интерфейс тюнері Android пайдаланушылық интерфейсін реттеудің қосымша жолдарын береді. Бұл эксперименттік мүмкіндіктер болашақ шығарылымдарда өзгеруі, бұзылуы немесе жоғалуы мүмкін. Сақтықпен жалғастырыңыз."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index adcd3d6..262d87b 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ផ្កាយរណប ការតភ្ជាប់ខ្សោយ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ផ្កាយរណប មានការតភ្ជាប់ល្អ"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ផ្កាយរណប អាចតភ្ជាប់បាន"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"កម្រងព័ត៌មានការងារ"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"ល្អសម្រាប់អ្នកប្រើមួយចំនួន តែមិនសម្រាប់គ្រប់គ្នាទេ"</string>
<string name="tuner_warning" msgid="1861736288458481650">"កម្មវិធីសម្រួល UI ប្រព័ន្ធផ្តល់ជូនអ្នកនូវមធ្យោបាយបន្ថែមទៀតដើម្បីកែសម្រួល និងប្តូរចំណុចប្រទាក់អ្នកប្រើ Android តាមបំណង។ លក្ខណៈពិសេសសាកល្បងនេះអាចនឹងផ្លាស់ប្តូរ បំបែក ឬបាត់បង់បន្ទាប់ពីការចេញផ្សាយនាពេលអនាគត។ សូមបន្តដោយប្រុងប្រយ័ត្ន។"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index ca22ba1..14644cf 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"ಹಿಯರಿಂಗ್ ಸಾಧನಗಳು"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"ಹೊಸ ಸಾಧನವನ್ನು ಪೇರ್ ಮಾಡಿ"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"ಪ್ರಿಸೆಟ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</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>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಕಳಪೆಯಾಗಿದೆ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಉತ್ತಮವಾಗಿದೆ"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಲಭ್ಯವಿದೆ"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"ಕೆಲವರಿಗೆ ಮೋಜು ಆಗಿದೆ ಎಲ್ಲರಿಗೆ ಇಲ್ಲ"</string>
<string name="tuner_warning" msgid="1861736288458481650">"ಸಿಸ್ಟಂ UI ಟ್ಯೂನರ್ ನಿಮಗೆ Android ಬಳಕೆದಾರ ಅಂತರಸಂಪರ್ಕವನ್ನು ಸರಿಪಡಿಸಲು ಮತ್ತು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಹೆಚ್ಚುವರಿ ಮಾರ್ಗಗಳನ್ನು ನೀಡುತ್ತದೆ. ಈ ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯಗಳು ಭವಿಷ್ಯದ ಬಿಡುಗಡೆಗಳಲ್ಲಿ ಬದಲಾಗಬಹುದು, ವಿರಾಮವಾಗಬಹುದು ಅಥವಾ ಕಾಣಿಸಿಕೊಳ್ಳದಿರಬಹುದು. ಎಚ್ಚರಿಕೆಯಿಂದ ಮುಂದುವರಿಯಿರಿ."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 4e7c4d0..94cddf0 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"위성, 연결 상태 나쁨"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"위성, 연결 상태 양호"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"위성, 연결 가능"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"직장 프로필"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"마음에 들지 않을 수도 있음"</string>
<string name="tuner_warning" msgid="1861736288458481650">"시스템 UI 튜너를 사용하면 Android 사용자 인터페이스를 변경 및 맞춤설정할 수 있습니다. 이러한 실험실 기능은 향후 출시 버전에서는 변경되거나 다운되거나 사라질 수 있습니다. 신중하게 진행하시기 바랍니다."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 1d005fb..1561ac3 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спутник, байланыш начар"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутник, байланыш жакшы"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спутник, байланыш бар"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Жумуш профили"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Баарына эле жага бербейт"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner Android колдонуучу интерфейсин жөнгө салып жана ыңгайлаштыруунун кошумча ыкмаларын сунуштайт. Бул сынамык функциялар кийинки чыгарылыштарда өзгөрүлүп, бузулуп же жоголуп кетиши мүмкүн. Абайлап колдонуңуз."</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index f95bb8e..0370454 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ດາວທຽມ, ການເຊື່ອມຕໍ່ບໍ່ດີ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ດາວທຽມ, ການເຊື່ອມຕໍ່ດີ"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ດາວທຽມ, ການເຊື່ອມຕໍ່ທີ່ພ້ອມນຳໃຊ້"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"ມ່ວນຊື່ນສຳລັບບາງຄົນ ແຕ່ບໍ່ແມ່ນສຳລັບທຸກຄົນ"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner ໃຫ້ທ່ານມີວິທີພິເສດຕື່ມອີກໃນການປັບປ່ຽນ ແລະຕົບແຕ່ງສ່ວນຕໍ່ປະສານຜູ້ໃຊ້ຂອງ Android. ຄຸນສົມບັດທົດລອງໃຊ້ເຫຼົ່ານີ້ອາດຈະປ່ຽນແປງ, ຢຸດເຊົາ ຫຼືຫາຍໄປໃນການວາງຈຳໜ່າຍໃນອະນາຄົດ. ຈົ່ງດຳເນີນຕໍ່ດ້ວຍຄວາມລະມັດລະວັງ."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 040294f..088a9fc 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Palydovas, prastas ryšys"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Palydovas, geras ryšys"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Palydovas, pasiekiamas ryšys"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Darbo profilis"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Smagu, bet ne visada"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Sistemos naudotojo sąsajos derinimo priemonė suteikia papildomų galimybių pagerinti ir tinkinti „Android“ naudotojo sąsają. Šios eksperimentinės funkcijos gali pasikeisti, nutrūkti ar išnykti iš būsimų laidų. Tęskite atsargiai."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index da58f33..09f0050 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelīts, vājš savienojums"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelīts, labs savienojums"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelīts, ir pieejams savienojums"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Darba profils"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Jautri dažiem, bet ne visiem"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Sistēmas saskarnes regulators sniedz papildu veidus, kā mainīt un pielāgot Android lietotāja saskarni. Nākamajās versijās šīs eksperimentālās funkcijas var tikt mainītas, bojātas vai to darbība var tikt pārtraukta. Turpinot esiet uzmanīgs."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 2faf243..abac1ad 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Слаба сателитска врска"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Добра сателитска врска"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Достапна е сателитска врска"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Работен профил"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Забава за некои, но не за сите"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 2fd4411..5bf98b5 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"സാറ്റലൈറ്റ്, മോശം കണക്ഷൻ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"സാറ്റലൈറ്റ്, മികച്ച കണക്ഷൻ"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"സാറ്റലൈറ്റ്, കണക്ഷൻ ലഭ്യമാണ്"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"ചിലർക്ക് വിനോദം, എന്നാൽ എല്ലാവർക്കുമില്ല"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Android ഉപയോക്തൃ ഇന്റർഫേസ് ആവശ്യമുള്ള രീതിയിൽ മാറ്റുന്നതിനും ഇഷ്ടാനുസൃതമാക്കുന്നതിനും സിസ്റ്റം UI ട്യൂണർ നിങ്ങൾക്ക് അധിക വഴികൾ നൽകുന്നു. ഭാവി റിലീസുകളിൽ ഈ പരീക്ഷണാത്മക ഫീച്ചറുകൾ മാറ്റുകയോ നിർത്തുകയോ അപ്രത്യക്ഷമാവുകയോ ചെയ്തേക്കാം. ശ്രദ്ധയോടെ മുന്നോട്ടുപോകുക."</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 94cdf4c..608492a 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Хиймэл дагуул, холболт муу байна"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хиймэл дагуул, холболт сайн байна"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Хиймэл дагуул, холболт боломжтой"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Ажлын профайл"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Зарим хүнд хөгжилтэй байж болох ч бүх хүнд тийм биш"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Системийн UI Tохируулагч нь Android хэрэглэгчийн интерфэйсийг тааруулах, өөрчлөх нэмэлт аргыг зааж өгөх болно. Эдгээр туршилтын тохиргоо нь цаашид өөрчлөгдөх, эвдрэх, алга болох магадлалтай. Үйлдлийг болгоомжтой хийнэ үү."</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index dd53db5..e83cc4e 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"सॅटेलाइट, खराब कनेक्शन"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सॅटेलाइट, चांगले कनेक्शन"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सॅटेलाइट, कनेक्शन उपलब्ध"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"कार्य प्रोफाईल"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"सर्वांसाठी नाही तर काहींसाठी मजेदार असू शकते"</string>
<string name="tuner_warning" msgid="1861736288458481650">"सिस्टम UI ट्युनर आपल्याला Android यूझर इंटरफेस ट्विक आणि कस्टमाइझ करण्याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्यातील रिलीज मध्ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरू ठेवा."</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 6b858a4..ad0c440 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, sambungan yang lemah"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, sambungan yang baik"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, sambungan tersedia"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil kerja"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Menarik untuk sesetengah orang tetapi bukan untuk semua"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Penala UI Sistem memberi anda cara tambahan untuk mengolah dan menyesuaikan antara muka Android. Ciri eksperimen ini boleh berubah, rosak atau hilang dalam keluaran masa hadapan. Teruskan dengan berhati-hati."</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 2472d1f..078bfd7 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု မကောင်းပါ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ကောင်းသည်"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ရနိုင်သည်"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"အလုပ် ပရိုဖိုင်"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"အချို့သူများ အတွက် ပျော်စရာ ဖြစ်ပေမဲ့ အားလုံး အတွက် မဟုတ်ပါ"</string>
<string name="tuner_warning" msgid="1861736288458481650">"စနစ် UI Tuner က သင့်အတွက် Android အသုံးပြုသူ အင်တာဖေ့စ်ကို ပြောင်းရန်နှင့် စိတ်ကြိုက်ပြုလုပ်ရန် နည်းလမ်း အပိုများကို သင့်အတွက် စီစဉ်ပေးသည်။ အနာဂတ်ဗားရှင်းများတွင် ဤစမ်းသပ်အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ပျက်စီး သို့မဟုတ် ပျောက်ကွယ်သွားနိုင်သည်။ သတိဖြင့် ရှေ့ဆက်ပါ။"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 5bc2fe5..2634bd3 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellitt – dårlig tilkobling"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitt – god tilkobling"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitt – tilkobling tilgjengelig"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Work-profil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Gøy for noen – ikke for alle"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Med System UI Tuner har du flere måter å justere og tilpasse Android-brukergrensesnittet på. Disse eksperimentelle funksjonene kan endres, avbrytes eller fjernes i fremtidige utgivelser. Fortsett med forbehold."</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index f52466c..7f81a5f 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"स्याटलाइट, खराब कनेक्सन"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"स्याटलाइट, राम्रो कनेक्सन"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"स्याटलाइट, कनेक्सन उपलब्ध छ"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"कार्य प्रोफाइल"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"केहीका लागि रमाइलो हुन्छ तर सबैका लागि होइन"</string>
<string name="tuner_warning" msgid="1861736288458481650">"सिस्टम UI ट्युनरले तपाईँलाई Android प्रयोगकर्ता इन्टरफेस आफू अनुकूल गर्न र ट्विक गर्न थप तरिकाहरू प्रदान गर्छ। यी प्रयोगात्मक सुविधाहरू भावी विमोचनमा परिवर्तन हुन, बिग्रिन वा हराउन सक्ने छन्। सावधानीपूर्वक अगाडि बढ्नुहोस्।"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 7a37aa0..78566b8 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -656,6 +656,8 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliet, slechte verbinding"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goede verbinding"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding beschikbaar"</string>
+ <string name="satellite_connected_carrier_text" msgid="7942466244369263272">"Verbonden met satelliet"</string>
+ <string name="satellite_not_connected_carrier_text" msgid="3471375076594005077">"Niet verbonden met satelliet"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Werkprofiel"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Leuk voor sommige gebruikers, maar niet voor iedereen"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Met Systeem-UI-tuner beschikt u over extra manieren om de Android-gebruikersinterface aan te passen. Deze experimentele functies kunnen veranderen, vastlopen of verdwijnen in toekomstige releases. Ga voorzichtig verder."</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 7e8ee6f..03c7cf5 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ସାଟେଲାଇଟ, ଦୁର୍ବଳ କନେକ୍ସନ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ସାଟେଲାଇଟ, ଭଲ କନେକ୍ସନ"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ସାଟେଲାଇଟ, କନେକ୍ସନ ଉପଲବ୍ଧ"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ୱର୍କ ପ୍ରୋଫାଇଲ୍"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"କେତେକଙ୍କ ପାଇଁ ମଜାଦାର, କିନ୍ତୁ ସମସ୍ତଙ୍କ ପାଇଁ ନୁହେଁ"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Android ୟୁଜର୍ ଇଣ୍ଟରଫେସ୍ ବଦଳାଇବାକୁ ତଥା ନିଜ ପସନ୍ଦ ଅନୁଯାୟୀ କରିବାକୁ ସିଷ୍ଟମ୍ UI ଟ୍ୟୁନର୍ ଆପଣଙ୍କୁ ଅତିରିକ୍ତ ଉପାୟ ପ୍ରଦାନ କରେ। ଏହି ପରୀକ୍ଷାମୂଳକ ସୁବିଧାମାନ ବଦଳିପାରେ, ଭାଙ୍ଗିପାରେ କିମ୍ବା ଭବିଷ୍ୟତର ରିଲିଜ୍ଗୁଡ଼ିକରେ ନଦେଖାଯାଇପାରେ। ସତର୍କତାର ସହ ଆଗକୁ ବଢ଼ନ୍ତୁ।"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index df823cf..6b88f29 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਖਰਾਬ ਹੈ"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਵਧੀਆ ਹੈ"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਉਪਲਬਧ ਹੈ"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"ਕੁਝ ਵਾਸਤੇ ਤਾਂ ਮਜ਼ੇਦਾਰ ਹੈ ਲੇਕਿਨ ਸਾਰਿਆਂ ਵਾਸਤੇ ਨਹੀਂ"</string>
<string name="tuner_warning" msgid="1861736288458481650">"ਸਿਸਟਮ UI ਟਿਊਨਰ ਤੁਹਾਨੂੰ Android ਵਰਤੋਂਕਾਰ ਇੰਟਰਫ਼ੇਸ ਤਬਦੀਲ ਕਰਨ ਅਤੇ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਵਾਧੂ ਤਰੀਕੇ ਦਿੰਦਾ ਹੈ। ਇਹ ਪ੍ਰਯੋਗਾਤਮਿਕ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਭਵਿੱਖ ਦੀ ਰੀਲੀਜ਼ ਵਿੱਚ ਬਦਲ ਸਕਦੀਆਂ ਹਨ, ਟੁੱਟ ਸਕਦੀਆਂ ਹਨ, ਜਾਂ ਅਲੋਪ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਸਾਵਧਾਨੀ ਨਾਲ ਅੱਗੇ ਵੱਧੋ।"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index f6468af..d10d5f8 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Urządzenia słuchowe"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Sparuj nowe urządzenie"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknij, aby sparować nowe urządzenie"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nie udało się zaktualizować gotowego ustawienia"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokować mikrofon urządzenia?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokować aparat urządzenia?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokować aparat i mikrofon urządzenia?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelita – połączenie słabe"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelita – połączenie dobre"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelita – połączenie dostępne"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil służbowy"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Dobra zabawa, ale nie dla każdego"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Kalibrator System UI udostępnia dodatkowe sposoby dostrajania i dostosowywania interfejsu Androida. Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index a1c72dc..d0f70ed 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, conexão ruim"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
<string name="tuner_warning" msgid="1861736288458481650">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index eadb5e54..7889e0b 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -656,6 +656,8 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, ligação fraca"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa ligação"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, ligação disponível"</string>
+ <string name="satellite_connected_carrier_text" msgid="7942466244369263272">"Ligação de satélite estabelecida"</string>
+ <string name="satellite_not_connected_carrier_text" msgid="3471375076594005077">"Não tem uma ligação de satélite estabelecida"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
<string name="tuner_warning" msgid="1861736288458481650">"O Sintonizador da interface do sistema disponibiliza-lhe formas adicionais ajustar e personalizar a interface do utilizador do Android. Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a1c72dc..d0f70ed 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, conexão ruim"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
<string name="tuner_warning" msgid="1861736288458481650">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index e53b4a4..8e4b752 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, conexiune slabă"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, conexiune bună"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, conexiune disponibilă"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil de serviciu"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Distractiv pentru unii, dar nu pentru toată lumea"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner oferă modalități suplimentare de a ajusta și a personaliza interfața de utilizare Android. Aceste funcții experimentale pot să se schimbe, să se blocheze sau să dispară din versiunile viitoare. Continuă cu prudență."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 8f6d7a8..d8d038e 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спутниковая связь, плохое качество соединения"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутниковая связь, хорошее качество соединения"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступно соединение по спутниковой связи"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Рабочий профиль"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Внимание!"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner позволяет настраивать интерфейс устройства Android по вашему вкусу. В будущем эта экспериментальная функция может измениться, перестать работать или исчезнуть."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index afb5755..5082174 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"චන්ද්රිකාව, දුර්වල සම්බන්ධතාවය"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"චන්ද්රිකාව, හොඳ සම්බන්ධතාවයක්"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"චන්ද්රිකාව, සම්බන්ධතාවය තිබේ"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"කාර්යාල පැතිකඩ"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"සමහරක් දේවල් වලට විනෝදයි, නමුත් සියල්ලටම නොවේ"</string>
<string name="tuner_warning" msgid="1861736288458481650">"පද්ධති UI සුසරකය ඔබට Android පරිශීලක අතුරු මුහුණත වෙනස් කිරීමට හෝ අභිරුචිකරණය කිරීමට අමතර ක්රම ලබා දේ. මෙම පර්යේෂණාත්මක අංග ඉදිරි නිකුත් වීම් වල වෙනස් වීමට, වැඩ නොකිරීමට, හෝ නැතිවීමට හැක. ප්රවේශමෙන් ඉදිරියට යන්න."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 453dd44..ffc9f27 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slabá kvalita pripojenia"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobrá kvalita pripojenia"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, pripojenie je k dispozícii"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Pracovný profil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Pri používaní tuneru postupujte opatrne"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Tuner používateľského rozhrania systému poskytujte ďalšie spôsoby ladenia a prispôsobenia používateľského rozhrania Android. Tieto experimentálne funkcie sa môžu v budúcich verziách zmeniť, ich poskytovanie môže byť prerušené alebo môžu byť odstránené. Pokračujte opatrne."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 27c376a..515286c 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slaba povezava"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra povezava"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, povezava je na voljo"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Delovni profil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Zabavno za nekatere, a ne za vse"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Uglaševalnik uporabniškega vmesnika sistema vam omogoča dodatne načine za spreminjanje in prilagajanje uporabniškega vmesnika Android. Te poskusne funkcije lahko v prihodnjih izdajah kadar koli izginejo, se spremenijo ali pokvarijo. Bodite previdni."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 071eda7..99e5a7b 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Sateliti. Lidhje e dobët"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sateliti. Lidhje e mirë"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sateliti. Ofrohet lidhje"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Profili i punës"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Argëtim për disa, por jo për të gjithë!"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit të jep mënyra shtesë për të tërhequr dhe personalizuar ndërfaqen Android të përdoruesit. Këto funksione eksperimentale mund të ndryshojnë, prishen ose zhduken në versionet e ardhshme. Vazhdo me kujdes."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 233e516..e96d493 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Слушни апарати"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Упари нови уређај"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликните да бисте упарили нов уређај"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ажурирање задатих подешавања није успело"</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>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Сателит, веза је лоша"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, веза је добра"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, веза је доступна"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Пословни профил"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Забава за неке, али не за све"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Тјунер за кориснички интерфејс система вам пружа додатне начине за подешавање и прилагођавање Android корисничког интерфејса. Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 579f526..7a5fa65 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellit, dålig anslutning"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, bra anslutning"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, anslutning tillgänglig"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Jobbprofil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Kul för vissa, inte för alla"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Du kan använda inställningarna för systemgränssnitt för att justera användargränssnittet i Android. Dessa experimentfunktioner kan när som helst ändras, sluta fungera eller försvinna. Använd med försiktighet."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index bc7b016..9dae421 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Vifaa vya kusikilizia"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Unganisha kifaa kipya"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Bofya ili uunganishe kifaa kipya"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Imeshindwa kusasisha mipangilio iliyowekwa mapema"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Ungependa kuwacha kuzuia maikrofoni ya kifaa?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Ungependa kuacha kuzuia kamera ya kifaa?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Ungependa kuwacha kuzuia kamera na maikrofoni ya kifaa?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Setilaiti, muunganisho hafifu"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Setilaiti, muunganisho thabiti"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Setilaiti, muunganisho unapatikana"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Wasifu wa kazini"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Kinafurahisha kwa baadhi ya watu lakini si wote"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Kirekebishi cha kiolesura cha mfumo kinakupa njia zaidi za kugeuza na kubadilisha kiolesura cha Android ili kikufae. Vipengele hivi vya majaribio vinaweza kubadilika, kuharibika au kupotea katika matoleo ya siku zijazo. Endelea kwa uangalifu."</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index b2c83dc..b418396 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"சாட்டிலைட், மோசமான இணைப்பு"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"சாட்டிலைட், நிலையான இணைப்பு"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"சாட்டிலைட், இணைப்பு கிடைக்கிறது"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"பணிக் கணக்கு"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"சில வேடிக்கையாக இருந்தாலும் கவனம் தேவை"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner, Android பயனர் இடைமுகத்தை மாற்றவும் தனிப்பயனாக்கவும் கூடுதல் வழிகளை வழங்குகிறது. இந்தப் பரிசோதனைக்குரிய அம்சங்கள் எதிர்கால வெளியீடுகளில் மாற்றப்படலாம், இடைநிறுத்தப்படலாம் அல்லது தோன்றாமல் போகலாம். கவனத்துடன் தொடரவும்."</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 5cd1341..a0a29d0 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"శాటిలైట్, కనెక్షన్ సరిగా లేదు"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"శాటిలైట్, కనెక్షన్ బాగుంది"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"శాటిలైట్, కనెక్షన్ అందుబాటులో ఉంది"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ఆఫీస్ ప్రొఫైల్"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"కొందరికి సరదాగా ఉంటుంది కానీ అందరికీ అలాగే ఉండదు"</string>
<string name="tuner_warning" msgid="1861736288458481650">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్ఫేస్ను మెరుగుపరచడానికి మరియు అనుకూలంగా మార్చడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 544844d..0ef447e 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ดาวเทียม, การเชื่อมต่อไม่ดี"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ดาวเทียม, การเชื่อมต่อดี"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ดาวเทียม, การเชื่อมต่อที่พร้อมใช้งาน"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"โปรไฟล์งาน"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"เพลิดเพลินกับบางส่วนแต่ไม่ใช่ทั้งหมด"</string>
<string name="tuner_warning" msgid="1861736288458481650">"ตัวรับสัญญาณ UI ระบบช่วยให้คุณมีวิธีพิเศษในการปรับแต่งและกำหนดค่าส่วนติดต่อผู้ใช้ Android ฟีเจอร์รุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 13e4bf8..975820a 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, mahina ang koneksyon"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, malakas ang koneksyon"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, may koneksyon"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Profile sa trabaho"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Masaya para sa ilan ngunit hindi para sa lahat"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Nagbibigay sa iyo ang Tuner ng System UI ng mga karagdagang paraan upang baguhin at i-customize ang user interface ng Android. Ang mga pang-eksperimentong feature na ito ay maaaring magbago, masira o mawala sa mga pagpapalabas sa hinaharap. Magpatuloy nang may pag-iingat."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 30b6ce4..5b10259 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Uydu, bağlantı zayıf"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Uydu, bağlantı güçlü"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Uydu, bağlantı mevcut"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"İş profili"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Bazıları için eğlenceliyken diğerleri için olmayabilir"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Sistem Kullanıcı Arayüzü Ayarlayıcı, Android kullanıcı arayüzünde değişiklikler yapmanız ve arayüzü özelleştirmeniz için ekstra yollar sağlar. Bu deneysel özellikler değişebilir, bozulabilir veya gelecekteki sürümlerde yer almayabilir. Dikkatli bir şekilde devam edin."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index e1d768e..071313f 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Погане з’єднання із супутником"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хороше з’єднання із супутником"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступне з’єднання із супутником"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Робочий профіль"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Це цікаво, але будьте обачні"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner пропонує нові способи налаштувати та персоналізувати інтерфейс користувача Android. Ці експериментальні функції можуть змінюватися, не працювати чи зникати в майбутніх версіях. Будьте обачні."</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 16b40bf..e1b1fa4 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"سیٹلائٹ، کنکشن خراب ہے"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"سیٹلائٹ، کنکشن اچھا ہے"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"سیٹلائٹ، کنکشن دستیاب ہے"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"دفتری پروفائل"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"کچھ کیلئے دلچسپ لیکن سبھی کیلئے نہیں"</string>
<string name="tuner_warning" msgid="1861736288458481650">"سسٹم UI ٹیونر Android صارف انٹر فیس میں ردوبدل کرنے اور اسے حسب ضرورت بنانے کیلئے آپ کو اضافی طریقے دیتا ہے۔ یہ تجرباتی خصوصیات مستقبل کی ریلیزز میں تبدیل ہو سکتی، رک سکتی یا غائب ہو سکتی ہیں۔ احتیاط کے ساتھ آگے بڑھیں۔"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 76694df..27145a6 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -371,8 +371,7 @@
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Eshitish qurilmalari"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Yangi qurilmani ulash"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yangi qurilmani ulash uchun bosing"</string>
- <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
- <skip />
+ <string name="hearing_devices_presets_error" msgid="350363093458408536">"Andoza yangilanmadi"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Qurilma mikrofoni blokdan chiqarilsinmi?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Qurilma kamerasi blokdan chiqarilsinmi?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Qurilma kamerasi va mikrofoni blokdan chiqarilsinmi?"</string>
@@ -656,6 +655,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Sputnik, aloqa sifati past"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sputnik, aloqa sifati yaxshi"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sputnik, aloqa mavjud"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Ish profili"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Diqqat!"</string>
<string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner yordamida siz Android foydalanuvchi interfeysini tuzatish va o‘zingizga moslashtirishingiz mumkin. Ushbu tajribaviy funksiyalar o‘zgarishi, buzilishi yoki keyingi versiyalarda olib tashlanishi mumkin. Ehtiyot bo‘lib davom eting."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 41066f9..84447fa 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Kết nối vệ tinh kém"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Kết nối vệ tinh tốt"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Hiện có kết nối vệ tinh"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Hồ sơ công việc"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Thú vị đối với một số người nhưng không phải tất cả"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Bộ điều hướng giao diện người dùng hệ thống cung cấp thêm cho bạn những cách chỉnh sửa và tùy chỉnh giao diện người dùng Android. Những tính năng thử nghiệm này có thể thay đổi, hỏng hoặc biến mất trong các phiên bản tương lai. Hãy thận trọng khi tiếp tục."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 60a46d60..eb928f0 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"卫星,连接质量不佳"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"卫星,连接质量良好"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"卫星,可连接"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"工作资料"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"并不适合所有用户"</string>
<string name="tuner_warning" msgid="1861736288458481650">"系统界面调节工具可让您以更多方式调整及定制 Android 界面。在日后推出的版本中,这些实验性功能可能会变更、失效或消失。操作时请务必谨慎。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 995129e..4ec1b58 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"衛星,連線質素唔好"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線質素好"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可以連線"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"工作設定檔"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"這只是測試版本,並不包含完整功能"</string>
<string name="tuner_warning" msgid="1861736288458481650">"使用者介面調諧器讓你以更多方法修改和自訂 Android 使用者介面。但請小心,這些實驗功能可能會在日後發佈時更改、分拆或消失。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index d18f828..52a1917 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"衛星,連線品質不佳"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線品質良好"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可連線"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"工作資料夾"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"有趣與否,見仁見智"</string>
<string name="tuner_warning" msgid="1861736288458481650">"系統使用者介面調整精靈可讓你透過其他方式,調整及自訂 Android 使用者介面。這些實驗性功能隨著版本更新可能會變更、損壞或消失,執行時請務必謹慎。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index a5caa3d..c96be0e 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -656,6 +656,10 @@
<string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Isathelayithi, uxhumano olungalungile"</string>
<string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Isethelayithi, uxhumano oluhle"</string>
<string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Isethelayithi, uxhumano luyatholakala"</string>
+ <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+ <skip />
+ <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+ <skip />
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Iphrofayela yomsebenzi"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Kuyajabulisa kwabanye kodwa hhayi bonke"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Isishuni se-UI sesistimu sikunika izindlela ezingeziwe zokuhlobisa nokwenza ngezifiso isixhumanisi sokubona se-Android. Lezi zici zesilingo zingashintsha, zephuke, noma zinyamalale ekukhishweni kwangakusasa. Qhubeka ngokuqaphela."</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1b2362d..a7a6d5b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -616,7 +616,7 @@
<dimen name="volume_panel_slice_vertical_padding">8dp</dimen>
<dimen name="volume_panel_slice_horizontal_padding">24dp</dimen>
- <dimen name="volume_panel_corner_radius">28dp</dimen>
+ <dimen name="bottom_sheet_corner_radius">28dp</dimen>
<!-- Size of each item in the ringer selector drawer. -->
<dimen name="volume_ringer_drawer_item_size">42dp</dimen>
@@ -1094,9 +1094,9 @@
<dimen name="remote_input_history_extra_height">60dp</dimen>
<!-- Biometric Dialog values -->
- <dimen name="biometric_dialog_face_icon_size">54dp</dimen>
- <dimen name="biometric_dialog_fingerprint_icon_width">80dp</dimen>
- <dimen name="biometric_dialog_fingerprint_icon_height">80dp</dimen>
+ <dimen name="biometric_dialog_face_icon_size">68dp</dimen>
+ <dimen name="biometric_dialog_fingerprint_icon_width">100dp</dimen>
+ <dimen name="biometric_dialog_fingerprint_icon_height">100dp</dimen>
<dimen name="biometric_dialog_button_negative_max_width">160dp</dimen>
<dimen name="biometric_dialog_button_positive_max_width">136dp</dimen>
<dimen name="biometric_dialog_corner_size">28dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 3d57111..042c4af 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -537,6 +537,12 @@
<item name="android:buttonBarButtonStyle">@style/Widget.Dialog.Button.Large</item>
</style>
+ <style name="Theme.SystemUI.BottomSheet" parent="Theme.SystemUI.Dialog">
+ <!-- default dialog background has insets -->
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowAnimationStyle">@style/Animation.Design.BottomSheetDialog</item>
+ </style>
+
<style name="AlertDialogStyle" parent="@androidprv:style/AlertDialog.DeviceDefault">
<item name="android:layout">@layout/alert_dialog_systemui</item>
</style>
@@ -1012,23 +1018,11 @@
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
- <style name="Theme.VolumePanelActivity" parent="@android:style/Theme.DeviceDefault.DayNight">
- <item name="android:windowFullscreen">true</item>
- <item name="android:windowContentOverlay">@null</item>
- <item name="android:windowActionBar">false</item>
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowIsTranslucent">true</item>
- <item name="android:windowBackground">@android:color/transparent</item>
- <item name="android:backgroundDimEnabled">true</item>
- <item name="android:windowCloseOnTouchOutside">true</item>
- <item name="android:windowAnimationStyle">@null</item>
- </style>
-
<style name="Widget.SliceView.VolumePanel">
<item name="hideHeaderRow">true</item>
</style>
- <style name="Theme.VolumePanelActivity.Popup" parent="@style/Theme.SystemUI.Dialog">
+ <style name="Theme.VolumePanel.Popup" parent="@style/Theme.SystemUI.Dialog">
<item name="android:dialogCornerRadius">44dp</item>
<item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainerHigh
</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 519622e..167ab90 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -30,6 +30,8 @@
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_PERMANENT;
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_TIMED;
import static android.hardware.biometrics.BiometricConstants.LockoutMode;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
import static android.hardware.biometrics.BiometricSourceType.FACE;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
@@ -1238,9 +1240,9 @@
boolean cameraPrivacyEnabled = mSensorPrivacyManager.isSensorPrivacyEnabled(
SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE, SensorPrivacyManager.Sensors.CAMERA);
- final boolean isHwUnavailable = msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE;
+ final boolean isHwUnavailable = msgId == FACE_ERROR_HW_UNAVAILABLE;
- if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
+ if (msgId == FACE_ERROR_LOCKOUT_PERMANENT) {
if (getFaceAuthInteractor() != null && getFaceAuthInteractor().isFaceAuthStrong()) {
updateFingerprintListeningState(BIOMETRIC_ACTION_STOP);
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
index b8ff0c0..99be762 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
@@ -112,6 +112,7 @@
const val COLOR_INVERSION_TILE_SPEC = "inversion"
const val FONT_SCALING_TILE_SPEC = "font_scaling"
const val REDUCE_BRIGHTNESS_TILE_SPEC = "reduce_brightness"
+ const val ONE_HANDED_TILE_SPEC = "onehanded"
@Provides
@IntoMap
@@ -241,5 +242,19 @@
mapper,
)
else StubQSTileViewModel
+
+ @Provides
+ @IntoMap
+ @StringKey(ONE_HANDED_TILE_SPEC)
+ fun provideOneHandedTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(ONE_HANDED_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = com.android.internal.R.drawable.ic_qs_one_handed_mode,
+ labelRes = R.string.quick_settings_onehanded_label,
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java b/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
index e7e12ba..227e4db 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
@@ -19,6 +19,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static com.android.systemui.shared.Flags.bouncerAreaExclusion;
+import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.graphics.Rect;
import android.graphics.Region;
@@ -37,7 +38,9 @@
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
+import com.android.systemui.Flags;
import com.android.systemui.ambient.touch.dagger.InputSessionComponent;
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
@@ -69,6 +72,9 @@
public String TAG = "DreamOverlayTouchMonitor";
private final Executor mMainExecutor;
private final Executor mBackgroundExecutor;
+
+ private final ConfigurationInteractor mConfigurationInteractor;
+
private final Lifecycle mLifecycle;
private Rect mExclusionRect = null;
@@ -82,6 +88,8 @@
}
};
+ private Consumer<Rect> mMaxBoundsConsumer = rect -> mMaxBounds = rect;
+
/**
* Adds a new {@link TouchSessionImpl} to participate in receiving future touches and gestures.
@@ -262,6 +270,7 @@
*/
private void startMonitoring() {
stopMonitoring(true);
+
if (bouncerAreaExclusion()) {
mBackgroundExecutor.execute(() -> {
try {
@@ -340,8 +349,13 @@
if (!handler.isEnabled()) {
continue;
}
- final Rect maxBounds = mDisplayHelper.getMaxBounds(ev.getDisplayId(),
- TYPE_APPLICATION_OVERLAY);
+
+ final Rect maxBounds =
+ Flags.ambientTouchMonitorListenToDisplayChanges()
+ ? mMaxBounds
+ : mDisplayHelper.getMaxBounds(ev.getDisplayId(),
+ TYPE_APPLICATION_OVERLAY);
+
final Region initiationRegion = Region.obtain();
Rect exclusionRect = null;
if (bouncerAreaExclusion()) {
@@ -478,6 +492,8 @@
private final int mDisplayId;
private final IWindowManager mWindowManagerService;
+ private Rect mMaxBounds;
+
/**
* Designated constructor for {@link TouchMonitor}
@@ -500,6 +516,7 @@
Lifecycle lifecycle,
InputSessionComponent.Factory inputSessionFactory,
DisplayHelper displayHelper,
+ ConfigurationInteractor configurationInteractor,
Set<TouchHandler> handlers,
IWindowManager windowManagerService,
@DisplayId int displayId) {
@@ -511,6 +528,7 @@
mLifecycle = lifecycle;
mDisplayHelper = displayHelper;
mWindowManagerService = windowManagerService;
+ mConfigurationInteractor = configurationInteractor;
}
/**
@@ -518,6 +536,9 @@
*/
public void init() {
mLifecycle.addObserver(mLifecycleObserver);
+ if (Flags.ambientTouchMonitorListenToDisplayChanges()) {
+ collectFlow(mLifecycle, mConfigurationInteractor.getMaxBounds(), mMaxBoundsConsumer);
+ }
}
private void isolate(Set<TouchSessionImpl> sessions) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index ea5c5da..1c17beb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -230,9 +230,13 @@
@Override
public void onUseDeviceCredential() {
mConfig.mCallback.onDeviceCredentialPressed(getRequestId());
- mHandler.postDelayed(() -> {
+ if (constraintBp()) {
addCredentialView(false /* animatePanel */, true /* animateContents */);
- }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS);
+ } else {
+ mHandler.postDelayed(() -> {
+ addCredentialView(false /* animatePanel */, true /* animateContents */);
+ }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS);
+ }
// TODO(b/313469218): Remove Config
mConfig.mPromptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 072fe47..a211147 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -87,7 +87,9 @@
*
* TODO(b/288175072): May be able to remove this once constraint layout is implemented
*/
- view.visibility = View.INVISIBLE
+ if (!constraintBp()) {
+ view.visibility = View.INVISIBLE
+ }
val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!!
val textColorError =
@@ -102,6 +104,12 @@
val descriptionView = view.requireViewById<TextView>(R.id.description)
val customizedViewContainer =
view.requireViewById<LinearLayout>(R.id.customized_view_container)
+ val udfpsGuidanceView =
+ if (constraintBp()) {
+ view.requireViewById<View>(R.id.panel)
+ } else {
+ backgroundView
+ }
// set selected to enable marquee unless a screen reader is enabled
logoView.isSelected =
@@ -226,8 +234,8 @@
}
lifecycleScope.launch {
- viewModel.showBpWithoutIconForCredential.collect {
- if (!it) {
+ viewModel.showBpWithoutIconForCredential.collect { showWithoutIcon ->
+ if (!showWithoutIcon) {
PromptIconViewBinder.bind(
iconView,
iconOverlayView,
@@ -428,7 +436,7 @@
}
// Talkback directional guidance
- backgroundView.setOnHoverListener { _, event ->
+ udfpsGuidanceView.setOnHoverListener { _, event ->
launch {
viewModel.onAnnounceAccessibilityHint(
event,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index f380746..d1ad783 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -20,6 +20,7 @@
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.graphics.Outline
+import android.graphics.Rect
import android.transition.AutoTransition
import android.transition.TransitionManager
import android.util.TypedValue
@@ -36,7 +37,6 @@
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.Guideline
import androidx.core.animation.addListener
-import androidx.core.view.doOnAttach
import androidx.core.view.doOnLayout
import androidx.core.view.isGone
import androidx.lifecycle.lifecycleScope
@@ -106,6 +106,52 @@
)
.toInt()
+ var currentSize: PromptSize? = null
+ var currentPosition: PromptPosition = PromptPosition.Bottom
+ panelView.outlineProvider =
+ object : ViewOutlineProvider() {
+ override fun getOutline(view: View, outline: Outline) {
+ when (currentPosition) {
+ PromptPosition.Right -> {
+ outline.setRoundRect(
+ 0,
+ 0,
+ view.width + cornerRadiusPx,
+ view.height,
+ cornerRadiusPx.toFloat()
+ )
+ }
+ PromptPosition.Left -> {
+ outline.setRoundRect(
+ -cornerRadiusPx,
+ 0,
+ view.width,
+ view.height,
+ cornerRadiusPx.toFloat()
+ )
+ }
+ PromptPosition.Top -> {
+ outline.setRoundRect(
+ 0,
+ -cornerRadiusPx,
+ view.width,
+ view.height,
+ cornerRadiusPx.toFloat()
+ )
+ }
+ PromptPosition.Bottom -> {
+ outline.setRoundRect(
+ 0,
+ 0,
+ view.width,
+ view.height + cornerRadiusPx,
+ cornerRadiusPx.toFloat()
+ )
+ }
+ }
+ }
+ }
+
// ConstraintSets for animating between prompt sizes
val mediumConstraintSet = ConstraintSet()
mediumConstraintSet.clone(view as ConstraintLayout)
@@ -115,7 +161,9 @@
val largeConstraintSet = ConstraintSet()
largeConstraintSet.clone(mediumConstraintSet)
- largeConstraintSet.constrainMaxWidth(R.id.panel, view.width)
+ largeConstraintSet.constrainMaxWidth(R.id.panel, 0)
+ largeConstraintSet.setGuidelineBegin(R.id.leftGuideline, 0)
+ largeConstraintSet.setGuidelineEnd(R.id.rightGuideline, 0)
// TODO: Investigate better way to handle 180 rotations
val flipConstraintSet = ConstraintSet()
@@ -138,65 +186,134 @@
}
}
- fun roundCorners(size: PromptSize, position: PromptPosition) {
- var left = 0
- var top = 0
- var right = 0
- var bottom = 0
- when (size) {
- PromptSize.SMALL,
- PromptSize.MEDIUM ->
- when (position) {
- PromptPosition.Right -> {
- left = 0
- top = 0
- right = view.width + cornerRadiusPx
- bottom = view.height
+ view.repeatWhenAttached {
+ lifecycleScope.launch {
+ viewModel.iconPosition.collect { position ->
+ if (position != Rect()) {
+ val iconParams =
+ iconHolderView.layoutParams as ConstraintLayout.LayoutParams
+
+ if (position.left != 0) {
+ iconParams.endToEnd = ConstraintSet.UNSET
+ iconParams.leftMargin = position.left
+ mediumConstraintSet.clear(
+ R.id.biometric_icon,
+ ConstraintSet.END
+ )
+ mediumConstraintSet.connect(
+ R.id.biometric_icon,
+ ConstraintSet.START,
+ ConstraintSet.PARENT_ID,
+ ConstraintSet.START
+ )
+ mediumConstraintSet.setMargin(
+ R.id.biometric_icon,
+ ConstraintSet.START,
+ position.left
+ )
+ smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.END)
+ smallConstraintSet.connect(
+ R.id.biometric_icon,
+ ConstraintSet.START,
+ ConstraintSet.PARENT_ID,
+ ConstraintSet.START
+ )
+ smallConstraintSet.setMargin(
+ R.id.biometric_icon,
+ ConstraintSet.START,
+ position.left
+ )
}
- PromptPosition.Left -> {
- left = -cornerRadiusPx
- top = 0
- right = view.width
- bottom = view.height
+ if (position.top != 0) {
+ iconParams.bottomToBottom = ConstraintSet.UNSET
+ iconParams.topMargin = position.top
+ mediumConstraintSet.clear(
+ R.id.biometric_icon,
+ ConstraintSet.BOTTOM
+ )
+ mediumConstraintSet.setMargin(
+ R.id.biometric_icon,
+ ConstraintSet.TOP,
+ position.top
+ )
+ smallConstraintSet.clear(
+ R.id.biometric_icon,
+ ConstraintSet.BOTTOM
+ )
+ smallConstraintSet.setMargin(
+ R.id.biometric_icon,
+ ConstraintSet.TOP,
+ position.top
+ )
}
- PromptPosition.Top -> {
- left = 0
- top = -cornerRadiusPx
- right = panelView.width
- bottom = view.height
+ if (position.right != 0) {
+ iconParams.startToStart = ConstraintSet.UNSET
+ iconParams.rightMargin = position.right
+ mediumConstraintSet.clear(
+ R.id.biometric_icon,
+ ConstraintSet.START
+ )
+ mediumConstraintSet.connect(
+ R.id.biometric_icon,
+ ConstraintSet.END,
+ ConstraintSet.PARENT_ID,
+ ConstraintSet.END
+ )
+ mediumConstraintSet.setMargin(
+ R.id.biometric_icon,
+ ConstraintSet.END,
+ position.right
+ )
+ smallConstraintSet.clear(
+ R.id.biometric_icon,
+ ConstraintSet.START
+ )
+ smallConstraintSet.connect(
+ R.id.biometric_icon,
+ ConstraintSet.END,
+ ConstraintSet.PARENT_ID,
+ ConstraintSet.END
+ )
+ smallConstraintSet.setMargin(
+ R.id.biometric_icon,
+ ConstraintSet.END,
+ position.right
+ )
}
- PromptPosition.Bottom -> {
- left = 0
- top = 0
- right = panelView.width
- bottom = view.height + cornerRadiusPx
+ if (position.bottom != 0) {
+ iconParams.topToTop = ConstraintSet.UNSET
+ iconParams.bottomMargin = position.bottom
+ mediumConstraintSet.clear(
+ R.id.biometric_icon,
+ ConstraintSet.TOP
+ )
+ mediumConstraintSet.setMargin(
+ R.id.biometric_icon,
+ ConstraintSet.BOTTOM,
+ position.bottom
+ )
+ smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.TOP)
+ smallConstraintSet.setMargin(
+ R.id.biometric_icon,
+ ConstraintSet.BOTTOM,
+ position.bottom
+ )
}
+ iconHolderView.layoutParams = iconParams
}
- PromptSize.LARGE -> {
- left = 0
- top = 0
- right = view.width
- bottom = view.height
}
}
-
- // Round the panel outline
- panelView.outlineProvider =
- object : ViewOutlineProvider() {
- override fun getOutline(view: View, outline: Outline) {
- outline.setRoundRect(
- left,
- top,
- right,
- bottom,
- cornerRadiusPx.toFloat()
- )
- }
+ lifecycleScope.launch {
+ viewModel.iconSize.collect { iconSize ->
+ iconHolderView.layoutParams.width = iconSize.first
+ iconHolderView.layoutParams.height = iconSize.second
+ mediumConstraintSet.constrainWidth(R.id.biometric_icon, iconSize.first)
+ mediumConstraintSet.constrainHeight(
+ R.id.biometric_icon,
+ iconSize.second
+ )
}
- }
-
- view.repeatWhenAttached {
- var currentSize: PromptSize? = null
+ }
lifecycleScope.launch {
viewModel.guidelineBounds.collect { bounds ->
@@ -249,87 +366,77 @@
lifecycleScope.launch {
combine(viewModel.position, viewModel.size, ::Pair).collect {
(position, size) ->
- view.doOnAttach {
- setVisibilities(size)
+ setVisibilities(size)
- if (position.isLeft) {
- if (size.isSmall) {
- flipConstraintSet.clone(smallConstraintSet)
- } else {
- flipConstraintSet.clone(mediumConstraintSet)
- }
-
- // Move all content to other panel
- flipConstraintSet.connect(
- R.id.scrollView,
- ConstraintSet.START,
- R.id.midGuideline,
- ConstraintSet.START
- )
- flipConstraintSet.connect(
- R.id.scrollView,
- ConstraintSet.END,
- R.id.rightGuideline,
- ConstraintSet.END
- )
+ if (position.isLeft) {
+ if (size.isSmall) {
+ flipConstraintSet.clone(smallConstraintSet)
+ } else {
+ flipConstraintSet.clone(mediumConstraintSet)
}
- roundCorners(size, position)
-
- when {
- size.isSmall -> {
- if (position.isLeft) {
- flipConstraintSet.applyTo(view)
- } else {
- smallConstraintSet.applyTo(view)
- }
- }
- size.isMedium && currentSize.isSmall -> {
- val autoTransition = AutoTransition()
- autoTransition.setDuration(
- ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong()
- )
-
- TransitionManager.beginDelayedTransition(
- view,
- autoTransition
- )
-
- if (position.isLeft) {
- flipConstraintSet.applyTo(view)
- } else {
- mediumConstraintSet.applyTo(view)
- }
- }
- size.isMedium -> {
- if (position.isLeft) {
- flipConstraintSet.applyTo(view)
- } else {
- mediumConstraintSet.applyTo(view)
- }
- }
- size.isLarge -> {
- val autoTransition = AutoTransition()
- autoTransition.setDuration(
- ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong()
- )
-
- TransitionManager.beginDelayedTransition(
- view,
- autoTransition
- )
- largeConstraintSet.applyTo(view)
- }
- }
-
- currentSize = size
- view.visibility = View.VISIBLE
- viewModel.setIsIconViewLoaded(false)
- notifyAccessibilityChanged()
-
- view.invalidate()
- view.requestLayout()
+ // Move all content to other panel
+ flipConstraintSet.connect(
+ R.id.scrollView,
+ ConstraintSet.START,
+ R.id.midGuideline,
+ ConstraintSet.START
+ )
+ flipConstraintSet.connect(
+ R.id.scrollView,
+ ConstraintSet.END,
+ R.id.rightGuideline,
+ ConstraintSet.END
+ )
}
+
+ when {
+ size.isSmall -> {
+ if (position.isLeft) {
+ flipConstraintSet.applyTo(view)
+ } else {
+ smallConstraintSet.applyTo(view)
+ }
+ }
+ size.isMedium && currentSize.isSmall -> {
+ val autoTransition = AutoTransition()
+ autoTransition.setDuration(
+ ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong()
+ )
+
+ TransitionManager.beginDelayedTransition(view, autoTransition)
+
+ if (position.isLeft) {
+ flipConstraintSet.applyTo(view)
+ } else {
+ mediumConstraintSet.applyTo(view)
+ }
+ }
+ size.isMedium -> {
+ if (position.isLeft) {
+ flipConstraintSet.applyTo(view)
+ } else {
+ mediumConstraintSet.applyTo(view)
+ }
+ }
+ size.isLarge && currentSize.isMedium -> {
+ val autoTransition = AutoTransition()
+ autoTransition.setDuration(
+ ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong()
+ )
+
+ TransitionManager.beginDelayedTransition(view, autoTransition)
+ largeConstraintSet.applyTo(view)
+ }
+ }
+
+ currentSize = size
+ currentPosition = position
+ notifyAccessibilityChanged()
+
+ panelView.invalidateOutline()
+ view.invalidate()
+ view.requestLayout()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
index d9d3715..9e836c3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
@@ -17,12 +17,9 @@
package com.android.systemui.biometrics.ui.binder
-import android.graphics.Rect
import android.graphics.drawable.Animatable2
import android.graphics.drawable.AnimatedVectorDrawable
import android.graphics.drawable.Drawable
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.airbnb.lottie.LottieAnimationView
@@ -77,83 +74,60 @@
}
}
- launch {
- var lottieOnCompositionLoadedListener: LottieOnCompositionLoadedListener? = null
+ if (!constraintBp()) {
+ launch {
+ var lottieOnCompositionLoadedListener: LottieOnCompositionLoadedListener? =
+ null
- combine(viewModel.activeAuthType, viewModel.iconSize, ::Pair).collect {
- (activeAuthType, iconSize) ->
- // Every time after bp shows, [isIconViewLoaded] is set to false in
- // [BiometricViewSizeBinder]. Then when biometric prompt view is redrew
- // (when size or activeAuthType changes), we need to update
- // [isIconViewLoaded] here to keep it correct.
- when (activeAuthType) {
- AuthType.Fingerprint,
- AuthType.Coex -> {
- /**
- * View is only set visible in BiometricViewSizeBinder once
- * PromptSize is determined that accounts for iconView size, to
- * prevent prompt resizing being visible to the user.
- *
- * TODO(b/288175072): May be able to remove this once constraint
- * layout is implemented
- */
- if (lottieOnCompositionLoadedListener != null) {
- iconView.removeLottieOnCompositionLoadedListener(
+ combine(viewModel.activeAuthType, viewModel.iconSize, ::Pair).collect {
+ (activeAuthType, iconSize) ->
+ // Every time after bp shows, [isIconViewLoaded] is set to false in
+ // [BiometricViewSizeBinder]. Then when biometric prompt view is redrew
+ // (when size or activeAuthType changes), we need to update
+ // [isIconViewLoaded] here to keep it correct.
+ when (activeAuthType) {
+ AuthType.Fingerprint,
+ AuthType.Coex -> {
+ /**
+ * View is only set visible in BiometricViewSizeBinder once
+ * PromptSize is determined that accounts for iconView size, to
+ * prevent prompt resizing being visible to the user.
+ *
+ * TODO(b/288175072): May be able to remove this once constraint
+ * layout is implemented
+ */
+ if (lottieOnCompositionLoadedListener != null) {
+ iconView.removeLottieOnCompositionLoadedListener(
+ lottieOnCompositionLoadedListener!!
+ )
+ }
+ lottieOnCompositionLoadedListener =
+ LottieOnCompositionLoadedListener {
+ promptViewModel.setIsIconViewLoaded(true)
+ }
+ iconView.addLottieOnCompositionLoadedListener(
lottieOnCompositionLoadedListener!!
)
}
- lottieOnCompositionLoadedListener =
- LottieOnCompositionLoadedListener {
- promptViewModel.setIsIconViewLoaded(true)
- }
- iconView.addLottieOnCompositionLoadedListener(
- lottieOnCompositionLoadedListener!!
- )
+ AuthType.Face -> {
+ /**
+ * Set to true by default since face icon is a drawable, which
+ * doesn't have a LottieOnCompositionLoadedListener equivalent.
+ *
+ * TODO(b/318569643): To be updated once face assets are updated
+ * from drawables
+ */
+ promptViewModel.setIsIconViewLoaded(true)
+ }
}
- AuthType.Face -> {
- /**
- * Set to true by default since face icon is a drawable, which
- * doesn't have a LottieOnCompositionLoadedListener equivalent.
- *
- * TODO(b/318569643): To be updated once face assets are updated
- * from drawables
- */
- promptViewModel.setIsIconViewLoaded(true)
- }
- }
- if (iconViewLayoutParamSizeOverride == null) {
- iconView.layoutParams.width = iconSize.first
- iconView.layoutParams.height = iconSize.second
+ if (iconViewLayoutParamSizeOverride == null) {
+ iconView.layoutParams.width = iconSize.first
+ iconView.layoutParams.height = iconSize.second
- iconOverlayView.layoutParams.width = iconSize.first
- iconOverlayView.layoutParams.height = iconSize.second
- }
- }
- }
-
- launch {
- viewModel.iconPosition.collect { position ->
- if (constraintBp() && position != Rect()) {
- val iconParams = iconView.layoutParams as ConstraintLayout.LayoutParams
-
- if (position.left != 0) {
- iconParams.endToEnd = ConstraintSet.UNSET
- iconParams.leftMargin = position.left
+ iconOverlayView.layoutParams.width = iconSize.first
+ iconOverlayView.layoutParams.height = iconSize.second
}
- if (position.top != 0) {
- iconParams.bottomToBottom = ConstraintSet.UNSET
- iconParams.topMargin = position.top
- }
- if (position.right != 0) {
- iconParams.startToStart = ConstraintSet.UNSET
- iconParams.rightMargin = position.right
- }
- if (position.bottom != 0) {
- iconParams.topToTop = ConstraintSet.UNSET
- iconParams.bottomMargin = position.bottom
- }
- iconView.layoutParams = iconParams
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
index 8dbed5f..bde3e99 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
@@ -66,10 +66,9 @@
*/
val activeAuthType: Flow<AuthType> =
combine(
- promptViewModel.size,
promptViewModel.modalities.distinctUntilChanged(),
promptViewModel.faceMode.distinctUntilChanged()
- ) { _, modalities, faceMode ->
+ ) { modalities, faceMode ->
if (modalities.hasFaceAndFingerprint && !faceMode) {
AuthType.Coex
} else if (modalities.hasFaceOnly || faceMode) {
@@ -103,68 +102,6 @@
}
.distinctUntilChanged()
- val iconPosition: Flow<Rect> =
- combine(
- udfpsSensorBounds,
- promptViewModel.size,
- promptViewModel.position,
- promptViewModel.modalities
- ) { sensorBounds, size, position, modalities ->
- when (position) {
- PromptPosition.Bottom ->
- if (size.isSmall) {
- Rect(0, 0, 0, promptViewModel.portraitSmallBottomPadding)
- } else if (size.isMedium && modalities.hasUdfps) {
- Rect(0, 0, 0, sensorBounds.bottom)
- } else if (size.isMedium) {
- Rect(0, 0, 0, promptViewModel.portraitMediumBottomPadding)
- } else {
- // Large screen
- Rect(0, 0, 0, promptViewModel.portraitLargeScreenBottomPadding)
- }
- PromptPosition.Right ->
- if (size.isSmall || modalities.hasFaceOnly) {
- Rect(
- 0,
- 0,
- promptViewModel.landscapeSmallHorizontalPadding,
- promptViewModel.landscapeSmallBottomPadding
- )
- } else if (size.isMedium && modalities.hasUdfps) {
- Rect(0, 0, sensorBounds.right, sensorBounds.bottom)
- } else {
- // SFPS
- Rect(
- 0,
- 0,
- promptViewModel.landscapeMediumHorizontalPadding,
- promptViewModel.landscapeMediumBottomPadding
- )
- }
- PromptPosition.Left ->
- if (size.isSmall || modalities.hasFaceOnly) {
- Rect(
- promptViewModel.landscapeSmallHorizontalPadding,
- 0,
- 0,
- promptViewModel.landscapeSmallBottomPadding
- )
- } else if (size.isMedium && modalities.hasUdfps) {
- Rect(sensorBounds.left, 0, 0, sensorBounds.bottom)
- } else {
- // SFPS
- Rect(
- promptViewModel.landscapeMediumHorizontalPadding,
- 0,
- 0,
- promptViewModel.landscapeMediumBottomPadding
- )
- }
- PromptPosition.Top -> Rect()
- }
- }
- .distinctUntilChanged()
-
/** Whether an error message is currently being shown. */
val showingError = promptViewModel.showingError
@@ -215,8 +152,8 @@
combine(
promptViewModel.position,
activeAuthType,
- promptViewModel.fingerprintSensorWidth,
- promptViewModel.fingerprintSensorHeight,
+ promptViewModel.legacyFingerprintSensorWidth,
+ promptViewModel.legacyFingerprintSensorHeight,
) { _, activeAuthType, fingerprintSensorWidth, fingerprintSensorHeight ->
if (activeAuthType == AuthType.Face) {
Pair(promptViewModel.faceIconWidth, promptViewModel.faceIconHeight)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index 4e9acbd..2104f3e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -27,6 +27,7 @@
import android.hardware.biometrics.Flags.customBiometricPrompt
import android.hardware.biometrics.PromptContentView
import android.util.Log
+import android.util.RotationUtils
import android.view.HapticFeedbackConstants
import android.view.MotionEvent
import com.android.systemui.Flags.bpTalkback
@@ -120,7 +121,28 @@
R.dimen.biometric_prompt_landscape_medium_horizontal_padding
)
- val fingerprintSensorWidth: Flow<Int> =
+ private val udfpsSensorBounds: Flow<Rect> =
+ combine(
+ udfpsOverlayInteractor.udfpsOverlayParams,
+ displayStateInteractor.currentRotation
+ ) { params, rotation ->
+ val rotatedBounds = Rect(params.sensorBounds)
+ RotationUtils.rotateBounds(
+ rotatedBounds,
+ params.naturalDisplayWidth,
+ params.naturalDisplayHeight,
+ rotation.ordinal
+ )
+ Rect(
+ rotatedBounds.left,
+ rotatedBounds.top,
+ params.logicalDisplayWidth - rotatedBounds.right,
+ params.logicalDisplayHeight - rotatedBounds.bottom
+ )
+ }
+ .distinctUntilChanged()
+
+ val legacyFingerprintSensorWidth: Flow<Int> =
combine(modalities, udfpsOverlayInteractor.udfpsOverlayParams) { modalities, overlayParams
->
if (modalities.hasUdfps) {
@@ -130,7 +152,7 @@
}
}
- val fingerprintSensorHeight: Flow<Int> =
+ val legacyFingerprintSensorHeight: Flow<Int> =
combine(modalities, udfpsOverlayInteractor.udfpsOverlayParams) { modalities, overlayParams
->
if (modalities.hasUdfps) {
@@ -140,6 +162,12 @@
}
}
+ val fingerprintSensorWidth: Int =
+ udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds.width()
+
+ val fingerprintSensorHeight: Int =
+ udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds.height()
+
private val _accessibilityHint = MutableSharedFlow<String>()
/** Hint for talkback directional guidance */
@@ -276,40 +304,54 @@
R.dimen.biometric_prompt_medium_mid_guideline_padding
)
- /**
- * Rect for positioning prompt guidelines (left, top, right, mid)
- *
- * Negative values are used to signify that guideline measuring should be flipped, measuring
- * from opposite side of the screen
- */
- val guidelineBounds: Flow<Rect> =
- combine(size, position, modalities) { size, position, modalities ->
- if (position.isBottom) {
- Rect(0, 0, 0, 0)
- } else if (position.isRight) {
- if (size.isSmall) {
- Rect(-smallHorizontalGuidelinePadding, 0, 0, 0)
- } else if (modalities.hasUdfps) {
- Rect(udfpsHorizontalGuidelinePadding, 0, 0, udfpsMidGuidelinePadding)
- } else if (modalities.isEmpty) {
- // TODO: Temporary fix until no biometric landscape layout is added
- Rect(-mediumHorizontalGuidelinePadding, 0, 0, 6)
- } else {
- Rect(-mediumHorizontalGuidelinePadding, 0, 0, mediumMidGuidelinePadding)
- }
- } else if (position.isLeft) {
- if (size.isSmall) {
- Rect(0, 0, -smallHorizontalGuidelinePadding, 0)
- } else if (modalities.hasUdfps) {
- Rect(0, 0, udfpsHorizontalGuidelinePadding, -udfpsMidGuidelinePadding)
- } else if (modalities.isEmpty) {
- // TODO: Temporary fix until no biometric landscape layout is added
- Rect(0, 0, -mediumHorizontalGuidelinePadding, -6)
- } else {
- Rect(0, 0, -mediumHorizontalGuidelinePadding, -mediumMidGuidelinePadding)
- }
- } else {
- Rect()
+ /** Rect for positioning biometric icon */
+ val iconPosition: Flow<Rect> =
+ combine(udfpsSensorBounds, size, position, modalities) {
+ sensorBounds,
+ size,
+ position,
+ modalities ->
+ when (position) {
+ PromptPosition.Bottom ->
+ if (size.isSmall) {
+ Rect(0, 0, 0, portraitSmallBottomPadding)
+ } else if (size.isMedium && modalities.hasUdfps) {
+ Rect(0, 0, 0, sensorBounds.bottom)
+ } else if (size.isMedium) {
+ Rect(0, 0, 0, portraitMediumBottomPadding)
+ } else {
+ // Large screen
+ Rect(0, 0, 0, portraitLargeScreenBottomPadding)
+ }
+ PromptPosition.Right ->
+ if (size.isSmall || modalities.hasFaceOnly) {
+ Rect(0, 0, landscapeSmallHorizontalPadding, landscapeSmallBottomPadding)
+ } else if (size.isMedium && modalities.hasUdfps) {
+ Rect(0, 0, sensorBounds.right, sensorBounds.bottom)
+ } else {
+ // SFPS
+ Rect(
+ 0,
+ 0,
+ landscapeMediumHorizontalPadding,
+ landscapeMediumBottomPadding
+ )
+ }
+ PromptPosition.Left ->
+ if (size.isSmall || modalities.hasFaceOnly) {
+ Rect(landscapeSmallHorizontalPadding, 0, 0, landscapeSmallBottomPadding)
+ } else if (size.isMedium && modalities.hasUdfps) {
+ Rect(sensorBounds.left, 0, 0, sensorBounds.bottom)
+ } else {
+ // SFPS
+ Rect(
+ landscapeMediumHorizontalPadding,
+ 0,
+ 0,
+ landscapeMediumBottomPadding
+ )
+ }
+ PromptPosition.Top -> Rect()
}
}
.distinctUntilChanged()
@@ -373,6 +415,62 @@
_isIconViewLoaded.value = iconViewLoaded
}
+ /** The size of the biometric icon */
+ val iconSize: Flow<Pair<Int, Int>> =
+ combine(iconViewModel.activeAuthType, modalities) { activeAuthType, modalities ->
+ if (activeAuthType == PromptIconViewModel.AuthType.Face) {
+ Pair(faceIconWidth, faceIconHeight)
+ } else {
+ if (modalities.hasUdfps) {
+ Pair(fingerprintSensorWidth, fingerprintSensorHeight)
+ } else {
+ Pair(fingerprintIconWidth, fingerprintIconHeight)
+ }
+ }
+ }
+
+ /**
+ * Rect for positioning prompt guidelines (left, top, right, mid)
+ *
+ * Negative values are used to signify that guideline measuring should be flipped, measuring
+ * from opposite side of the screen
+ */
+ val guidelineBounds: Flow<Rect> =
+ combine(iconPosition, size, position, modalities) { _, size, position, modalities ->
+ when (position) {
+ PromptPosition.Bottom -> Rect(0, 0, 0, 0)
+ PromptPosition.Right ->
+ if (size.isSmall) {
+ Rect(-smallHorizontalGuidelinePadding, 0, 0, 0)
+ } else if (modalities.hasUdfps) {
+ Rect(udfpsHorizontalGuidelinePadding, 0, 0, udfpsMidGuidelinePadding)
+ } else if (modalities.isEmpty) {
+ // TODO: Temporary fix until no biometric landscape layout is added
+ Rect(-mediumHorizontalGuidelinePadding, 0, 0, 6)
+ } else {
+ Rect(-mediumHorizontalGuidelinePadding, 0, 0, mediumMidGuidelinePadding)
+ }
+ PromptPosition.Left ->
+ if (size.isSmall) {
+ Rect(0, 0, -smallHorizontalGuidelinePadding, 0)
+ } else if (modalities.hasUdfps) {
+ Rect(0, 0, udfpsHorizontalGuidelinePadding, -udfpsMidGuidelinePadding)
+ } else if (modalities.isEmpty) {
+ // TODO: Temporary fix until no biometric landscape layout is added
+ Rect(0, 0, -mediumHorizontalGuidelinePadding, -6)
+ } else {
+ Rect(
+ 0,
+ 0,
+ -mediumHorizontalGuidelinePadding,
+ -mediumMidGuidelinePadding
+ )
+ }
+ PromptPosition.Top -> Rect()
+ }
+ }
+ .distinctUntilChanged()
+
/** Padding for prompt UI elements */
val promptPadding: Flow<Rect> =
combine(size, displayStateInteractor.currentRotation) { size, rotation ->
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt b/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt
index 638af58..e0e1971 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt
@@ -48,6 +48,12 @@
}
}
+ /** Returns the unadjusted screen size. */
+ val maxBounds: Flow<Rect> =
+ repository.configurationValues
+ .map { Rect(it.windowConfiguration.maxBounds) }
+ .distinctUntilChanged()
+
/**
* Returns screen size adjusted to rotation, so returned screen sizes are stable across all
* rotations, could be useful if you need to react to screen resize (e.g. fold/unfold on
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
index 4ac43bc..511bdc4 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
@@ -88,14 +88,14 @@
/** Whether in edit mode for the communal hub. */
open val isEditMode = false
- /** Whether the popup message triggered by dismissing the CTA tile is showing. */
- open val isPopupOnDismissCtaShowing: Flow<Boolean> = flowOf(false)
+ /** Whether the type of popup currently showing */
+ open val currentPopup: Flow<PopupType?> = flowOf(null)
/** Whether the communal hub is empty with no widget available. */
open val isEmptyState: Flow<Boolean> = flowOf(false)
- /** Hide the popup message triggered by dismissing the CTA tile. */
- open fun onHidePopupAfterDismissCta() {}
+ /** Called as the UI request to dismiss the any displaying popup */
+ open fun onHidePopup() {}
/** Called as the UI requests deleting a widget. */
open fun onDeleteWidget(id: Int) {}
@@ -127,6 +127,9 @@
/** Called as the user cancels dragging a widget to reorder. */
open fun onReorderWidgetCancel() {}
+ /** Called as the user request to show the customize widget button. */
+ open fun onShowCustomizeWidgetButton() {}
+
/** Set the key of the currently selected item */
fun setSelectedKey(key: String?) {
_selectedKey.value = key
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index f13b5759..9dacf8c 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -90,9 +90,8 @@
.distinctUntilChanged()
.onEach { logger.d("isEmptyState: $it") }
- private val _isPopupOnDismissCtaShowing: MutableStateFlow<Boolean> = MutableStateFlow(false)
- override val isPopupOnDismissCtaShowing: Flow<Boolean> =
- _isPopupOnDismissCtaShowing.asStateFlow()
+ private val _currentPopup: MutableStateFlow<PopupType?> = MutableStateFlow(null)
+ override val currentPopup: Flow<PopupType?> = _currentPopup.asStateFlow()
private val _isEnableWidgetDialogShowing: MutableStateFlow<Boolean> = MutableStateFlow(false)
val isEnableWidgetDialogShowing: Flow<Boolean> = _isEnableWidgetDialogShowing.asStateFlow()
@@ -124,14 +123,16 @@
override fun onDismissCtaTile() {
scope.launch {
communalInteractor.dismissCtaTile()
- setPopupOnDismissCtaVisibility(true)
- schedulePopupHiding()
+ setCurrentPopupType(PopupType.CtaTile)
}
}
- override fun onHidePopupAfterDismissCta() {
- cancelDelayedPopupHiding()
- setPopupOnDismissCtaVisibility(false)
+ override fun onShowCustomizeWidgetButton() {
+ setCurrentPopupType(PopupType.CustomizeWidgetButton)
+ }
+
+ override fun onHidePopup() {
+ setCurrentPopupType(null)
}
override fun onOpenEnableWidgetDialog() {
@@ -168,25 +169,22 @@
_isEnableWorkProfileDialogShowing.value = isVisible
}
- private fun setPopupOnDismissCtaVisibility(isVisible: Boolean) {
- _isPopupOnDismissCtaShowing.value = isVisible
+ private fun setCurrentPopupType(popupType: PopupType?) {
+ _currentPopup.value = popupType
+ delayedHideCurrentPopupJob?.cancel()
+
+ if (popupType != null) {
+ delayedHideCurrentPopupJob =
+ scope.launch {
+ delay(POPUP_AUTO_HIDE_TIMEOUT_MS)
+ setCurrentPopupType(null)
+ }
+ } else {
+ delayedHideCurrentPopupJob = null
+ }
}
- private var delayedHidePopupJob: Job? = null
-
- private fun schedulePopupHiding() {
- cancelDelayedPopupHiding()
- delayedHidePopupJob =
- scope.launch {
- delay(POPUP_AUTO_HIDE_TIMEOUT_MS)
- onHidePopupAfterDismissCta()
- }
- }
-
- private fun cancelDelayedPopupHiding() {
- delayedHidePopupJob?.cancel()
- delayedHidePopupJob = null
- }
+ private var delayedHideCurrentPopupJob: Job? = null
/** Whether we can transition to a new scene based on a user gesture. */
fun canChangeScene(): Boolean {
@@ -197,3 +195,8 @@
const val POPUP_AUTO_HIDE_TIMEOUT_MS = 12000L
}
}
+
+sealed class PopupType {
+ object CtaTile : PopupType()
+ object CustomizeWidgetButton : PopupType()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
index 2af49aa..db7ffc1 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
@@ -20,8 +20,6 @@
import android.content.pm.PackageManager
import com.android.systemui.controls.ControlsMetricsLogger
import com.android.systemui.controls.ControlsMetricsLoggerImpl
-import com.android.systemui.controls.settings.ControlsSettingsRepository
-import com.android.systemui.controls.settings.ControlsSettingsRepositoryImpl
import com.android.systemui.controls.controller.ControlsBindingController
import com.android.systemui.controls.controller.ControlsBindingControllerImpl
import com.android.systemui.controls.controller.ControlsController
@@ -40,14 +38,20 @@
import com.android.systemui.controls.panels.SelectedComponentRepositoryImpl
import com.android.systemui.controls.settings.ControlsSettingsDialogManager
import com.android.systemui.controls.settings.ControlsSettingsDialogManagerImpl
+import com.android.systemui.controls.settings.ControlsSettingsRepository
+import com.android.systemui.controls.settings.ControlsSettingsRepositoryImpl
import com.android.systemui.controls.ui.ControlActionCoordinator
import com.android.systemui.controls.ui.ControlActionCoordinatorImpl
import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.controls.ui.ControlsUiControllerImpl
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.DeviceControlsTile
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
import dagger.Binds
import dagger.BindsOptionalOf
import dagger.Module
@@ -75,6 +79,22 @@
fun providesControlsFeatureEnabled(pm: PackageManager): Boolean {
return pm.hasSystemFeature(PackageManager.FEATURE_CONTROLS)
}
+
+ const val DEVICE_CONTROLS_SPEC = "controls"
+
+ @Provides
+ @IntoMap
+ @StringKey(DEVICE_CONTROLS_SPEC)
+ fun provideDeviceControlsTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(DEVICE_CONTROLS_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = com.android.systemui.res.R.drawable.controls_icon,
+ labelRes = com.android.systemui.res.R.string.quick_controls_title
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
}
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt
index 98deda09..ffe392a 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt
@@ -16,6 +16,7 @@
package com.android.systemui.deviceentry.domain.interactor
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_START
import android.hardware.face.FaceManager
import com.android.systemui.biometrics.FaceHelpMessageDeferralFactory
import com.android.systemui.dagger.SysUISingleton
@@ -86,7 +87,7 @@
}
}
.collect {
- if (it.acquiredInfo == FaceManager.FACE_ACQUIRED_START) {
+ if (it.acquiredInfo == FACE_ACQUIRED_START) {
faceHelpMessageDeferral.reset()
}
faceHelpMessageDeferral.processFrame(it.acquiredInfo)
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/FaceAuthenticationModels.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/FaceAuthenticationModels.kt
index 5f1667a..3365340 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/FaceAuthenticationModels.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/FaceAuthenticationModels.kt
@@ -16,6 +16,12 @@
package com.android.systemui.deviceentry.shared.model
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_CANCELED
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS
import android.hardware.face.FaceManager
import android.os.SystemClock.elapsedRealtime
@@ -62,24 +68,22 @@
* Method that checks if [msgId] is a lockout error. A lockout error means that face
* authentication is locked out.
*/
- fun isLockoutError() =
- msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT || msgId == FaceManager.FACE_ERROR_LOCKOUT
+ fun isLockoutError() = msgId == FACE_ERROR_LOCKOUT_PERMANENT || msgId == FACE_ERROR_LOCKOUT
/**
* Method that checks if [msgId] is a cancellation error. This means that face authentication
* was cancelled before it completed.
*/
- fun isCancellationError() = msgId == FaceManager.FACE_ERROR_CANCELED
+ fun isCancellationError() = msgId == FACE_ERROR_CANCELED
- fun isUnableToProcessError() = msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS
+ fun isUnableToProcessError() = msgId == FACE_ERROR_UNABLE_TO_PROCESS
/** Method that checks if [msgId] is a hardware error. */
fun isHardwareError() =
- msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE ||
- msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS
+ msgId == FACE_ERROR_HW_UNAVAILABLE || msgId == FACE_ERROR_UNABLE_TO_PROCESS
/** Method that checks if [msgId] is a timeout error. */
- fun isTimeoutError() = msgId == FaceManager.FACE_ERROR_TIMEOUT
+ fun isTimeoutError() = msgId == FACE_ERROR_TIMEOUT
companion object {
/**
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index c618e92..aa7a7da 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -16,6 +16,8 @@
package com.android.systemui.dreams;
+import static android.service.dreams.Flags.dreamWakeRedirect;
+
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_WINDOW_TITLE;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_TOUCH_INSET_MANAGER;
import static com.android.systemui.dreams.dagger.DreamModule.HOME_CONTROL_PANEL_DREAM_COMPONENT;
@@ -149,6 +151,14 @@
private final CommunalInteractor mCommunalInteractor;
+ private boolean mCommunalAvailable;
+
+ final Consumer<Boolean> mIsCommunalAvailableCallback =
+ isAvailable -> {
+ mCommunalAvailable = isAvailable;
+ updateRedirectWakeup();
+ };
+
private final SystemDialogsCloser mSystemDialogsCloser;
private final KeyguardUpdateMonitorCallback mKeyguardCallback =
@@ -287,6 +297,8 @@
mExecutor.execute(() -> setLifecycleStateLocked(Lifecycle.State.CREATED));
+ collectFlow(getLifecycle(), mCommunalInteractor.isCommunalAvailable(),
+ mIsCommunalAvailableCallback);
collectFlow(getLifecycle(), communalInteractor.isCommunalVisible(),
mCommunalVisibleConsumer);
collectFlow(getLifecycle(), keyguardInteractor.primaryBouncerShowing,
@@ -374,6 +386,16 @@
mDreamOverlayCallbackController.onStartDream();
mStarted = true;
+
+ updateRedirectWakeup();
+ }
+
+ private void updateRedirectWakeup() {
+ if (!mStarted || !dreamWakeRedirect()) {
+ return;
+ }
+
+ redirectWake(mCommunalAvailable);
}
@Override
@@ -381,6 +403,11 @@
resetCurrentDreamOverlayLocked();
}
+ @Override
+ public void onWakeRequested() {
+ mCommunalInteractor.changeScene(CommunalScenes.Communal, null);
+ }
+
private Lifecycle.State getLifecycleStateLocked() {
return mLifecycleRegistry.getCurrentState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index 516b8c5..b0d134f 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -36,6 +36,11 @@
import com.android.systemui.dreams.homecontrols.DreamActivityProvider;
import com.android.systemui.dreams.homecontrols.DreamActivityProviderImpl;
import com.android.systemui.dreams.homecontrols.HomeControlsDreamService;
+import com.android.systemui.qs.QsEventLogger;
+import com.android.systemui.qs.pipeline.shared.TileSpec;
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig;
+import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy;
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig;
import com.android.systemui.res.R;
import com.android.systemui.touch.TouchInsetManager;
@@ -44,6 +49,7 @@
import dagger.Provides;
import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;
+import dagger.multibindings.StringKey;
import java.util.Optional;
import java.util.concurrent.Executor;
@@ -70,6 +76,7 @@
String DREAM_SUPPORTED = "dream_supported";
String DREAM_OVERLAY_WINDOW_TITLE = "dream_overlay_window_title";
String HOME_CONTROL_PANEL_DREAM_COMPONENT = "home_control_panel_dream_component";
+ String DREAM_TILE_SPEC = "dream";
/**
* Provides the dream component
@@ -178,6 +185,23 @@
return resources.getString(R.string.app_label);
}
+ /** Provides config for the dream tile */
+ @Provides
+ @IntoMap
+ @StringKey(DREAM_TILE_SPEC)
+ static QSTileConfig provideDreamTileConfig(QsEventLogger uiEventLogger) {
+ TileSpec tileSpec = TileSpec.create(DREAM_TILE_SPEC);
+ return new QSTileConfig(tileSpec,
+ new QSTileUIConfig.Resource(
+ R.drawable.ic_qs_screen_saver,
+ R.string.quick_settings_screensaver_label),
+ uiEventLogger.getNewInstanceId(),
+ tileSpec.getSpec(),
+ QSTilePolicy.NoRestrictions.INSTANCE
+ );
+ }
+
+
/** Provides activity for dream service */
@Binds
DreamActivityProvider bindActivityProvider(DreamActivityProviderImpl impl);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
index 0bc60c4..7c29b39 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
@@ -21,6 +21,7 @@
import android.animation.ValueAnimator
import android.graphics.Rect
import android.transition.Transition
+import android.transition.TransitionListenerAdapter
import android.transition.TransitionSet
import android.transition.TransitionValues
import android.util.Log
@@ -169,6 +170,18 @@
return@OnPreDrawListener true
}
+ this@VisibilityBoundsTransition.addListener(
+ object : TransitionListenerAdapter() {
+ override fun onTransitionStart(t: Transition) {
+ toView.viewTreeObserver.addOnPreDrawListener(predrawCallback)
+ }
+
+ override fun onTransitionEnd(t: Transition) {
+ toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback)
+ }
+ }
+ )
+
val listener =
object : AnimatorListenerAdapter() {
override fun onAnimationStart(anim: Animator) {
@@ -178,26 +191,11 @@
override fun onAnimationEnd(anim: Animator) {
assignAnimValues("end", 1f, toVis)
if (sendToBack) toView.translationZ = 0f
- toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback)
- }
-
- override fun onAnimationPause(anim: Animator) {
- toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback)
- }
-
- override fun onAnimationResume(anim: Animator) {
- toView.viewTreeObserver.addOnPreDrawListener(predrawCallback)
}
}
- anim.duration = duration
- anim.startDelay = startDelay
- anim.interpolator = interpolator
anim.addListener(listener)
- anim.addPauseListener(listener)
-
assignAnimValues("init", 0f, fromVis)
- toView.viewTreeObserver.addOnPreDrawListener(predrawCallback)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
index df3a974..9719c02 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
@@ -16,24 +16,64 @@
package com.android.systemui.media.controls.data.repository
+import android.content.Context
import com.android.internal.logging.InstanceId
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.media.controls.data.model.MediaSortKeyModel
import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
+import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.time.SystemClock
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import java.util.Locale
import java.util.TreeMap
import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
/** A repository that holds the state of filtered media data on the device. */
@SysUISingleton
-class MediaFilterRepository @Inject constructor(private val systemClock: SystemClock) {
+class MediaFilterRepository
+@Inject
+constructor(
+ @Application applicationContext: Context,
+ private val systemClock: SystemClock,
+ private val configurationController: ConfigurationController,
+) {
+
+ val onAnyMediaConfigurationChange: Flow<Unit> = conflatedCallbackFlow {
+ val callback =
+ object : ConfigurationController.ConfigurationListener {
+ override fun onDensityOrFontScaleChanged() {
+ trySend(Unit)
+ }
+
+ override fun onThemeChanged() {
+ trySend(Unit)
+ }
+
+ override fun onUiModeChanged() {
+ trySend(Unit)
+ }
+
+ override fun onLocaleListChanged() {
+ if (locale != applicationContext.resources.configuration.locales.get(0)) {
+ locale = applicationContext.resources.configuration.locales.get(0)
+ trySend(Unit)
+ }
+ }
+ }
+ configurationController.addCallback(callback)
+ trySend(Unit)
+ awaitClose { configurationController.removeCallback(callback) }
+ }
/** Instance id of media control that recommendations card reactivated. */
private val _reactivatedId: MutableStateFlow<InstanceId?> = MutableStateFlow(null)
@@ -76,6 +116,7 @@
val isMediaFromRec: StateFlow<Boolean> = _isMediaFromRec.asStateFlow()
private var mediaFromRecPackageName: String? = null
+ private var locale: Locale = applicationContext.resources.configuration.locales.get(0)
fun addMediaEntry(key: String, data: MediaData) {
val entries = LinkedHashMap<String, MediaData>(_allUserEntries.value)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
index 13f934e..33c0b19 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
@@ -157,7 +157,7 @@
// Set up links back into the pipeline for listeners that need to send events upstream.
mediaTimeoutListener.timeoutCallback = { key: String, timedOut: Boolean ->
- setInactive(key, timedOut)
+ mediaDataProcessor.setInactive(key, timedOut)
}
mediaTimeoutListener.stateCallback = { key: String, state: PlaybackState ->
mediaDataProcessor.updateState(key, state)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
index c0bb628..9f2d132 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
@@ -83,6 +83,8 @@
.pairwiseBy(initialValue = false) { wasPlaying, isPlaying -> !wasPlaying && isPlaying }
.distinctUntilChanged()
+ val onAnyMediaConfigurationChange: Flow<Unit> = repository.onAnyMediaConfigurationChange
+
fun removeMediaControl(
token: MediaSession.Token?,
instanceId: InstanceId,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
index dea5810..dd6b264 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
@@ -65,6 +65,8 @@
.distinctUntilChanged()
.stateIn(applicationScope, SharingStarted.WhileSubscribed(), false)
+ val onAnyMediaConfigurationChange: Flow<Unit> = repository.onAnyMediaConfigurationChange
+
fun removeMediaRecommendations(key: String, dismissIntent: Intent?, delayMs: Long) {
mediaDataProcessor.dismissSmartspaceRecommendation(key, delayMs)
if (dismissIntent == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
index 8dd3379..73fb558 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
@@ -100,7 +100,7 @@
}
}
- private suspend fun bindMediaCard(
+ suspend fun bindMediaCard(
viewHolder: MediaViewHolder,
viewController: MediaViewController,
viewModel: MediaPlayerViewModel,
@@ -333,7 +333,7 @@
}
}
}
- updateSeekBarVisibility(viewController.expandedLayout, isSeekBarEnabled = false)
+ updateSeekBarVisibility(viewController.expandedLayout, viewController.isSeekBarEnabled)
}
private fun bindButtonCommon(
@@ -472,6 +472,7 @@
if (viewModel.shouldAddGradient) 333 else 80
)
}
+ ?: albumView.setImageDrawable(artwork)
}
viewController.isArtworkBound = viewModel.shouldAddGradient
viewController.prevArtwork = artwork
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
index fe13da6..bd4d435 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
@@ -68,7 +68,7 @@
}
}
- private fun bindRecsCard(
+ fun bindRecsCard(
viewHolder: RecommendationViewHolder,
viewModel: MediaRecsCardViewModel,
mediaViewController: MediaViewController,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
index d2dd289..0478178 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
@@ -35,6 +35,7 @@
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
+import androidx.recyclerview.widget.DiffUtil
import com.android.app.tracing.traceSection
import com.android.internal.logging.InstanceId
import com.android.keyguard.KeyguardUpdateMonitor
@@ -53,12 +54,18 @@
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
+import com.android.systemui.media.controls.ui.binder.MediaControlViewBinder
+import com.android.systemui.media.controls.ui.binder.MediaRecommendationsViewBinder
import com.android.systemui.media.controls.ui.controller.MediaControlPanel.SMARTSPACE_CARD_DISMISS_EVENT
+import com.android.systemui.media.controls.ui.util.MediaViewModelCallback
+import com.android.systemui.media.controls.ui.util.MediaViewModelListUpdateCallback
import com.android.systemui.media.controls.ui.view.MediaCarouselScrollHandler
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.controls.ui.view.MediaScrollView
import com.android.systemui.media.controls.ui.view.MediaViewHolder
import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
+import com.android.systemui.media.controls.ui.viewmodel.MediaCarouselViewModel
+import com.android.systemui.media.controls.ui.viewmodel.MediaCommonViewModel
import com.android.systemui.media.controls.util.MediaFlags
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.media.controls.util.SmallHash
@@ -118,12 +125,13 @@
private val mediaHostStatesManager: MediaHostStatesManager,
private val activityStarter: ActivityStarter,
private val systemClock: SystemClock,
+ @Main private val mainDispatcher: CoroutineDispatcher,
@Main executor: DelayableExecutor,
@Background private val bgExecutor: Executor,
@Background private val backgroundDispatcher: CoroutineDispatcher,
private val mediaManager: MediaDataManager,
configurationController: ConfigurationController,
- falsingManager: FalsingManager,
+ private val falsingManager: FalsingManager,
dumpManager: DumpManager,
private val logger: MediaUiEventLogger,
private val debugLogger: MediaCarouselControllerLogger,
@@ -132,6 +140,8 @@
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val globalSettings: GlobalSettings,
private val secureSettings: SecureSettings,
+ private val mediaCarouselViewModel: MediaCarouselViewModel,
+ private val mediaViewControllerFactory: Provider<MediaViewController>,
) : Dumpable {
/** The current width of the carousel */
var currentCarouselWidth: Int = 0
@@ -182,7 +192,6 @@
private set
private val mediaContent: ViewGroup
@VisibleForTesting var pageIndicator: PageIndicator
- private val visualStabilityCallback: OnReorderingAllowedListener
private var needsReordering: Boolean = false
private var keysNeedRemoval = mutableSetOf<String>()
var shouldScrollToKey: Boolean = false
@@ -201,7 +210,11 @@
private val animationScaleObserver: ContentObserver =
object : ContentObserver(null) {
override fun onChange(selfChange: Boolean) {
- MediaPlayerData.players().forEach { it.updateAnimatorDurationScale() }
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+ MediaPlayerData.players().forEach { it.updateAnimatorDurationScale() }
+ } else {
+ controllerByViewModel.values.forEach { it.updateAnimatorDurationScale() }
+ }
}
}
@@ -297,6 +310,9 @@
private var widthInSceneContainerPx = 0
private var heightInSceneContainerPx = 0
+ private val controllerByViewModel = mutableMapOf<MediaCommonViewModel, MediaViewController>()
+ private val commonViewModels = mutableListOf<MediaCommonViewModel>()
+
init {
dumpManager.registerDumpable(TAG, this)
mediaFrame = inflateMediaCarousel()
@@ -320,7 +336,48 @@
inflateSettingsButton()
mediaContent = mediaCarousel.requireViewById(R.id.media_carousel)
configurationController.addCallback(configListener)
- visualStabilityCallback = OnReorderingAllowedListener {
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+ setUpListeners()
+ }
+ mediaFrame.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
+ // The pageIndicator is not laid out yet when we get the current state update,
+ // Lets make sure we have the right dimensions
+ updatePageIndicatorLocation()
+ }
+ mediaHostStatesManager.addCallback(
+ object : MediaHostStatesManager.Callback {
+ override fun onHostStateChanged(
+ @MediaLocation location: Int,
+ mediaHostState: MediaHostState
+ ) {
+ updateUserVisibility()
+ if (location == desiredLocation) {
+ onDesiredLocationChanged(desiredLocation, mediaHostState, animate = false)
+ }
+ }
+ }
+ )
+ keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
+ mediaCarousel.repeatWhenAttached {
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ listenForAnyStateToGoneKeyguardTransition(this)
+ listenForAnyStateToLockscreenTransition(this)
+ listenForLockscreenSettingChanges(this)
+
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) return@repeatOnLifecycle
+ listenForMediaItemsChanges(this)
+ }
+ }
+
+ // Notifies all active players about animation scale changes.
+ globalSettings.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
+ animationScaleObserver
+ )
+ }
+
+ private fun setUpListeners() {
+ val visualStabilityCallback = OnReorderingAllowedListener {
if (needsReordering) {
needsReordering = false
reorderAllPlayers(previousVisiblePlayerKey = null)
@@ -530,35 +587,6 @@
}
}
)
- mediaFrame.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
- // The pageIndicator is not laid out yet when we get the current state update,
- // Lets make sure we have the right dimensions
- updatePageIndicatorLocation()
- }
- mediaHostStatesManager.addCallback(
- object : MediaHostStatesManager.Callback {
- override fun onHostStateChanged(location: Int, mediaHostState: MediaHostState) {
- updateUserVisibility()
- if (location == desiredLocation) {
- onDesiredLocationChanged(desiredLocation, mediaHostState, animate = false)
- }
- }
- }
- )
- keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
- mediaCarousel.repeatWhenAttached {
- repeatOnLifecycle(Lifecycle.State.STARTED) {
- listenForAnyStateToGoneKeyguardTransition(this)
- listenForAnyStateToLockscreenTransition(this)
- listenForLockscreenSettingChanges(this)
- }
- }
-
- // Notifies all active players about animation scale changes.
- globalSettings.registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
- animationScaleObserver
- )
}
private fun inflateSettingsButton() {
@@ -642,6 +670,125 @@
}
}
+ private fun listenForMediaItemsChanges(scope: CoroutineScope): Job {
+ return scope.launch {
+ mediaCarouselViewModel.mediaItems.collectLatest {
+ val diffUtilCallback = MediaViewModelCallback(commonViewModels, it)
+ val listUpdateCallback =
+ MediaViewModelListUpdateCallback(
+ old = commonViewModels,
+ new = it,
+ onAdded = this@MediaCarouselController::onAdded,
+ onUpdated = this@MediaCarouselController::onUpdated,
+ onRemoved = this@MediaCarouselController::onRemoved,
+ onMoved = this@MediaCarouselController::onMoved,
+ )
+ DiffUtil.calculateDiff(diffUtilCallback).dispatchUpdatesTo(listUpdateCallback)
+ setNewViewModelsList(it)
+ }
+ }
+ }
+
+ private fun onAdded(commonViewModel: MediaCommonViewModel, position: Int) {
+ val viewController = mediaViewControllerFactory.get()
+ viewController.sizeChangedListener = this::updateCarouselDimensions
+ val lp =
+ LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ when (commonViewModel) {
+ is MediaCommonViewModel.MediaControl -> {
+ val viewHolder = MediaViewHolder.create(LayoutInflater.from(context), mediaContent)
+ if (mediaFlags.isSceneContainerEnabled()) {
+ viewController.widthInSceneContainerPx = widthInSceneContainerPx
+ viewController.heightInSceneContainerPx = heightInSceneContainerPx
+ }
+ viewController.attachPlayer(viewHolder)
+ viewController.mediaViewHolder.player.layoutParams = lp
+ MediaControlViewBinder.bind(
+ viewHolder,
+ commonViewModel.controlViewModel,
+ viewController,
+ falsingManager,
+ backgroundDispatcher,
+ mainDispatcher,
+ mediaFlags
+ )
+ mediaContent.addView(viewHolder.player, position)
+ }
+ is MediaCommonViewModel.MediaRecommendations -> {
+ val viewHolder =
+ RecommendationViewHolder.create(LayoutInflater.from(context), mediaContent)
+ viewController.attachRecommendations(viewHolder)
+ viewController.recommendationViewHolder.recommendations.layoutParams = lp
+ MediaRecommendationsViewBinder.bind(
+ viewHolder,
+ commonViewModel.recsViewModel,
+ viewController,
+ falsingManager,
+ )
+ mediaContent.addView(viewHolder.recommendations, position)
+ }
+ }
+ viewController.setListening(mediaCarouselScrollHandler.visibleToUser && currentlyExpanded)
+ updateViewControllerToState(viewController, noAnimation = true)
+ updatePageIndicator()
+ mediaCarouselScrollHandler.onPlayersChanged()
+ mediaFrame.requiresRemeasuring = true
+ commonViewModel.onAdded(commonViewModel)
+ controllerByViewModel[commonViewModel] = viewController
+ }
+
+ private fun onUpdated(commonViewModel: MediaCommonViewModel) {
+ commonViewModel.onUpdated(commonViewModel)
+ updatePageIndicator()
+ mediaCarouselScrollHandler.onPlayersChanged()
+ }
+
+ private fun onRemoved(commonViewModel: MediaCommonViewModel) {
+ controllerByViewModel.remove(commonViewModel)?.let {
+ when (commonViewModel) {
+ is MediaCommonViewModel.MediaControl -> {
+ mediaCarouselScrollHandler.onPrePlayerRemoved(it.mediaViewHolder.player)
+ mediaContent.removeView(it.mediaViewHolder.player)
+ }
+ is MediaCommonViewModel.MediaRecommendations -> {
+ mediaContent.removeView(it.recommendationViewHolder.recommendations)
+ }
+ }
+ it.onDestroy()
+ mediaCarouselScrollHandler.onPlayersChanged()
+ updatePageIndicator()
+ commonViewModel.onRemoved(true)
+ }
+ }
+
+ private fun onMoved(commonViewModel: MediaCommonViewModel, from: Int, to: Int) {
+ controllerByViewModel[commonViewModel]?.let {
+ mediaContent.removeViewAt(from)
+ when (commonViewModel) {
+ is MediaCommonViewModel.MediaControl -> {
+ mediaContent.addView(it.mediaViewHolder.player, to)
+ }
+ is MediaCommonViewModel.MediaRecommendations -> {
+ mediaContent.addView(it.recommendationViewHolder.recommendations, to)
+ }
+ }
+ }
+ updatePageIndicator()
+ mediaCarouselScrollHandler.onPlayersChanged()
+ }
+
+ private fun setNewViewModelsList(viewModels: List<MediaCommonViewModel>) {
+ commonViewModels.clear()
+ commonViewModels.addAll(viewModels)
+
+ // Ensure we only show the needed UMOs in media carousel.
+ val viewSet = viewModels.toHashSet()
+ controllerByViewModel.filter { !viewSet.contains(it.key) }.forEach { onRemoved(it.key) }
+ }
+
private suspend fun getMediaLockScreenSetting(): Boolean {
return withContext(backgroundDispatcher) {
secureSettings.getBoolForUser(
@@ -758,7 +905,7 @@
isSsReactivated,
debugLogger
)
- updatePlayerToState(newPlayer.mediaViewController, noAnimation = true)
+ updateViewControllerToState(newPlayer.mediaViewController, noAnimation = true)
// Media data added from a recommendation card should starts playing.
if (
(shouldScrollToKey && data.isPlaying == true) ||
@@ -856,7 +1003,7 @@
systemClock,
debugLogger,
)
- updatePlayerToState(newRecs.mediaViewController, noAnimation = true)
+ updateViewControllerToState(newRecs.mediaViewController, noAnimation = true)
reorderAllPlayers(curVisibleMediaKey)
updatePageIndicator()
mediaFrame.requiresRemeasuring = true
@@ -905,6 +1052,10 @@
}
private fun updatePlayers(recreateMedia: Boolean) {
+ if (mediaFlags.isMediaControlsRefactorEnabled()) {
+ updateMediaPlayers(recreateMedia)
+ return
+ }
pageIndicator.tintList =
ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
val previousVisibleKey =
@@ -940,6 +1091,28 @@
}
}
+ private fun updateMediaPlayers(recreateMedia: Boolean) {
+ pageIndicator.tintList =
+ ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+ if (recreateMedia) {
+ mediaContent.removeAllViews()
+ commonViewModels.forEach { viewModel ->
+ when (viewModel) {
+ is MediaCommonViewModel.MediaControl -> {
+ controllerByViewModel[viewModel]?.mediaViewHolder?.let {
+ mediaContent.addView(it.player)
+ }
+ }
+ is MediaCommonViewModel.MediaRecommendations -> {
+ controllerByViewModel[viewModel]?.recommendationViewHolder?.let {
+ mediaContent.addView(it.recommendations)
+ }
+ }
+ }
+ }
+ }
+ }
+
private fun updatePageIndicator() {
val numPages = mediaContent.getChildCount()
pageIndicator.setNumPages(numPages)
@@ -979,8 +1152,14 @@
currentStartLocation = startLocation
currentEndLocation = endLocation
currentTransitionProgress = progress
- for (mediaPlayer in MediaPlayerData.players()) {
- updatePlayerToState(mediaPlayer.mediaViewController, immediately)
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+ for (mediaPlayer in MediaPlayerData.players()) {
+ updateViewControllerToState(mediaPlayer.mediaViewController, immediately)
+ }
+ } else {
+ controllerByViewModel.values.forEach {
+ updateViewControllerToState(it, immediately)
+ }
}
maybeResetSettingsCog()
updatePageIndicatorAlpha()
@@ -1035,8 +1214,14 @@
/** Update listening to seekbar. */
private fun updateSeekbarListening(visibleToUser: Boolean) {
- for (player in MediaPlayerData.players()) {
- player.setListening(visibleToUser && currentlyExpanded)
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+ for (player in MediaPlayerData.players()) {
+ player.setListening(visibleToUser && currentlyExpanded)
+ }
+ } else {
+ controllerByViewModel.values.forEach {
+ it.setListening(visibleToUser && currentlyExpanded)
+ }
}
}
@@ -1044,12 +1229,22 @@
private fun updateCarouselDimensions() {
var width = 0
var height = 0
- for (mediaPlayer in MediaPlayerData.players()) {
- val controller = mediaPlayer.mediaViewController
- // When transitioning the view to gone, the view gets smaller, but the translation
- // Doesn't, let's add the translation
- width = Math.max(width, controller.currentWidth + controller.translationX.toInt())
- height = Math.max(height, controller.currentHeight + controller.translationY.toInt())
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+ for (mediaPlayer in MediaPlayerData.players()) {
+ val controller = mediaPlayer.mediaViewController
+ // When transitioning the view to gone, the view gets smaller, but the translation
+ // Doesn't, let's add the translation
+ width = Math.max(width, controller.currentWidth + controller.translationX.toInt())
+ height =
+ Math.max(height, controller.currentHeight + controller.translationY.toInt())
+ }
+ } else {
+ controllerByViewModel.values.forEach {
+ // When transitioning the view to gone, the view gets smaller, but the translation
+ // Doesn't, let's add the translation
+ width = Math.max(width, it.currentWidth + it.translationX.toInt())
+ height = Math.max(height, it.currentHeight + it.translationY.toInt())
+ }
}
if (width != currentCarouselWidth || height != currentCarouselHeight) {
currentCarouselWidth = width
@@ -1080,7 +1275,10 @@
}
}
- private fun updatePlayerToState(viewController: MediaViewController, noAnimation: Boolean) {
+ private fun updateViewControllerToState(
+ viewController: MediaViewController,
+ noAnimation: Boolean
+ ) {
viewController.setCurrentState(
startLocation = currentStartLocation,
endLocation = currentEndLocation,
@@ -1123,18 +1321,31 @@
!mediaManager.hasActiveMediaOrRecommendation() &&
desiredHostState.showsOnlyActiveMedia
- for (mediaPlayer in MediaPlayerData.players()) {
- if (animate) {
- mediaPlayer.mediaViewController.animatePendingStateChange(
- duration = duration,
- delay = startDelay
- )
- }
- if (shouldCloseGuts && mediaPlayer.mediaViewController.isGutsVisible) {
- mediaPlayer.closeGuts(!animate)
- }
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+ for (mediaPlayer in MediaPlayerData.players()) {
+ if (animate) {
+ mediaPlayer.mediaViewController.animatePendingStateChange(
+ duration = duration,
+ delay = startDelay
+ )
+ }
+ if (shouldCloseGuts && mediaPlayer.mediaViewController.isGutsVisible) {
+ mediaPlayer.closeGuts(!animate)
+ }
- mediaPlayer.mediaViewController.onLocationPreChange(desiredLocation)
+ mediaPlayer.mediaViewController.onLocationPreChange(desiredLocation)
+ }
+ } else {
+ controllerByViewModel.values.forEach { controller ->
+ if (animate) {
+ controller.animatePendingStateChange(duration, startDelay)
+ }
+ if (shouldCloseGuts && controller.isGutsVisible) {
+ controller.closeGuts(!animate)
+ }
+
+ controller.onLocationPreChange(desiredLocation)
+ }
}
mediaCarouselScrollHandler.showsSettingsButton = !it.showsOnlyActiveMedia
mediaCarouselScrollHandler.falsingProtectionNeeded = it.falsingProtectionNeeded
@@ -1150,7 +1361,11 @@
}
fun closeGuts(immediate: Boolean = true) {
- MediaPlayerData.players().forEach { it.closeGuts(immediate) }
+ if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+ MediaPlayerData.players().forEach { it.closeGuts(immediate) }
+ } else {
+ controllerByViewModel.values.forEach { it.closeGuts(immediate) }
+ }
}
/** Update the size of the carousel, remeasuring it if necessary. */
@@ -1288,6 +1503,10 @@
}
private fun onSwipeToDismiss() {
+ if (mediaFlags.isMediaControlsRefactorEnabled()) {
+ mediaCarouselViewModel.onSwipeToDismiss()
+ return
+ }
MediaPlayerData.players().forEachIndexed { index, it ->
if (it.mIsImpressed) {
logSmartspaceCardReported(
@@ -1319,6 +1538,7 @@
println("dataKeys: ${MediaPlayerData.dataKeys()}")
println("orderedPlayerSortKeys: ${MediaPlayerData.playerKeys()}")
println("visiblePlayerSortKeys: ${MediaPlayerData.visiblePlayerKeys()}")
+ println("commonViewModels: $commonViewModels")
println("smartspaceMediaData: ${MediaPlayerData.smartspaceMediaData}")
println("shouldPrioritizeSs: ${MediaPlayerData.shouldPrioritizeSs}")
println("current size: $currentCarouselWidth x $currentCarouselHeight")
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
index 5188132..96a8239 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
@@ -31,6 +31,7 @@
import com.android.systemui.util.Utils
import com.android.systemui.util.kotlin.pairwiseBy
import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import java.util.concurrent.Executor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@@ -50,6 +51,7 @@
@Application private val applicationScope: CoroutineScope,
@Application private val applicationContext: Context,
@Background private val backgroundDispatcher: CoroutineDispatcher,
+ @Background private val backgroundExecutor: Executor,
private val visualStabilityProvider: VisualStabilityProvider,
private val interactor: MediaCarouselInteractor,
private val controlInteractorFactory: MediaControlInteractorFactory,
@@ -142,9 +144,9 @@
private fun createMediaControlViewModel(instanceId: InstanceId): MediaControlViewModel {
return MediaControlViewModel(
- applicationScope = applicationScope,
applicationContext = applicationContext,
backgroundDispatcher = backgroundDispatcher,
+ backgroundExecutor = backgroundExecutor,
interactor = controlInteractorFactory.create(instanceId),
logger = logger,
)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
index 52e49d6..bc364c3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
@@ -41,21 +41,21 @@
import com.android.systemui.monet.Style
import com.android.systemui.res.R
import com.android.systemui.util.kotlin.sample
+import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
/** Models UI state and handles user input for a media control. */
class MediaControlViewModel(
@Application private val applicationContext: Context,
- @Application private val applicationScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
+ @Background private val backgroundExecutor: Executor,
private val interactor: MediaControlInteractor,
private val logger: MediaUiEventLogger,
) {
@@ -72,9 +72,15 @@
.distinctUntilChanged()
)
+ @OptIn(ExperimentalCoroutinesApi::class)
val player: Flow<MediaPlayerViewModel?> =
- combine(playTurbulenceNoise, interactor.mediaControl) { playTurbulenceNoise, mediaControl ->
- mediaControl?.let { toViewModel(it, playTurbulenceNoise) }
+ interactor.onAnyMediaConfigurationChange
+ .flatMapLatest {
+ combine(playTurbulenceNoise, interactor.mediaControl) {
+ playTurbulenceNoise,
+ mediaControl ->
+ mediaControl?.let { toViewModel(it, playTurbulenceNoise) }
+ }
}
.distinctUntilChanged()
.flowOn(backgroundDispatcher)
@@ -161,12 +167,10 @@
if (model.isResume && model.resumeProgress != null) {
seekBarViewModel.updateStaticProgress(model.resumeProgress)
} else {
- applicationScope.launch {
- withContext(backgroundDispatcher) {
- seekBarViewModel.updateController(
- model.token?.let { MediaController(applicationContext, it) }
- )
- }
+ backgroundExecutor.execute {
+ seekBarViewModel.updateController(
+ model.token?.let { MediaController(applicationContext, it) }
+ )
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
index 5cd9804..52c4bc5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
@@ -50,8 +50,10 @@
import com.android.systemui.res.R
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
@@ -67,9 +69,12 @@
private val logger: MediaUiEventLogger,
) {
+ @OptIn(ExperimentalCoroutinesApi::class)
val mediaRecsCard: Flow<MediaRecsCardViewModel?> =
- interactor.recommendations
- .map { recsCard -> toRecsViewModel(recsCard) }
+ interactor.onAnyMediaConfigurationChange
+ .flatMapLatest {
+ interactor.recommendations.map { recsCard -> toRecsViewModel(recsCard) }
+ }
.distinctUntilChanged()
.flowOn(backgroundDispatcher)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
index 22b3f35..cef1e69 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
@@ -33,19 +33,12 @@
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.android.systemui.classifier.Classifier.MEDIA_SEEKBAR
-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.media.controls.util.MediaFlags
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.util.concurrency.RepeatableExecutor
import javax.inject.Inject
import kotlin.math.abs
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
private const val POSITION_UPDATE_INTERVAL_MILLIS = 100L
private const val MIN_FLING_VELOCITY_SCALE_FACTOR = 10
@@ -88,11 +81,8 @@
class SeekBarViewModel
@Inject
constructor(
- @Application private val applicationScope: CoroutineScope,
- @Main private val mainDispatcher: CoroutineDispatcher,
@Background private val bgExecutor: RepeatableExecutor,
private val falsingManager: FalsingManager,
- private val mediaFlags: MediaFlags,
) {
private var _data =
Progress(
@@ -118,19 +108,9 @@
private var controller: MediaController? = null
set(value) {
if (field?.sessionToken != value?.sessionToken) {
- if (!mediaFlags.isMediaControlsRefactorEnabled()) {
- field?.unregisterCallback(callback)
- value?.registerCallback(callback)
- field = value
- } else {
- applicationScope.launch {
- withContext(mainDispatcher) {
- field?.unregisterCallback(callback)
- value?.registerCallback(callback)
- field = value
- }
- }
- }
+ field?.unregisterCallback(callback)
+ value?.registerCallback(callback)
+ field = value
}
}
private var playbackState: PlaybackState? = null
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 48f432e..6cc4dcb 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -254,6 +254,7 @@
window.setAttributes(lp);
window.setContentView(mDialogView);
window.setTitle(mContext.getString(R.string.media_output_dialog_accessibility_title));
+ window.setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
mHeaderTitle = mDialogView.requireViewById(R.id.header_title);
mHeaderSubtitle = mDialogView.requireViewById(R.id.header_subtitle);
diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
index d40112f..3907a72 100644
--- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
@@ -16,10 +16,16 @@
package com.android.systemui.qrcodescanner.dagger
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.QRCodeScannerTile
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.res.R
import dagger.Binds
import dagger.Module
+import dagger.Provides
import dagger.multibindings.IntoMap
import dagger.multibindings.StringKey
@@ -31,4 +37,22 @@
@IntoMap
@StringKey(QRCodeScannerTile.TILE_SPEC)
fun bindQRCodeScannerTile(qrCodeScannerTile: QRCodeScannerTile): QSTileImpl<*>
+
+ companion object {
+ const val QR_CODE_SCANNER_TILE_SPEC = "qr_code_scanner"
+
+ @Provides
+ @IntoMap
+ @StringKey(QR_CODE_SCANNER_TILE_SPEC)
+ fun provideQRCodeScannerTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(QR_CODE_SCANNER_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.ic_qr_code_scanner,
+ labelRes = R.string.qr_code_scanner_title,
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
index 4a8e33a..2e52845 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
@@ -60,6 +60,7 @@
companion object {
/** Create a [TileSpec] from the string [spec]. */
+ @JvmStatic
fun create(spec: String): TileSpec {
return if (TextUtils.isEmpty(spec)) {
Invalid
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
index 22146ce..257c4d5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
@@ -29,6 +29,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.qs.FooterActionsController
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.ui.adapter.QSSceneAdapter
@@ -62,6 +63,7 @@
private val footerActionsViewModelFactory: FooterActionsViewModel.Factory,
private val footerActionsController: FooterActionsController,
sceneBackInteractor: SceneBackInteractor,
+ val mediaDataManager: MediaDataManager,
) {
private val backScene: StateFlow<SceneKey> =
sceneBackInteractor.backScene
@@ -141,4 +143,9 @@
}
return footerActionsViewModelFactory.create(lifecycleOwner)
}
+
+ fun isMediaVisible(): Boolean {
+ // TODO(b/328207006): use new pipeline to handle updates while visible
+ return mediaDataManager.hasAnyMediaOrRecommendation()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
index d67cf4d..26af9a7 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
@@ -16,10 +16,16 @@
package com.android.systemui.recordissue
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.RecordIssueTile
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.res.R
import dagger.Binds
import dagger.Module
+import dagger.Provides
import dagger.multibindings.IntoMap
import dagger.multibindings.StringKey
@@ -30,4 +36,23 @@
@IntoMap
@StringKey(RecordIssueTile.TILE_SPEC)
fun bindRecordIssueTile(recordIssueTile: RecordIssueTile): QSTileImpl<*>
+
+ companion object {
+
+ const val RECORD_ISSUE_TILE_SPEC = "record_issue"
+
+ @Provides
+ @IntoMap
+ @StringKey(RECORD_ISSUE_TILE_SPEC)
+ fun provideRecordIssueTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(RECORD_ISSUE_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.qs_record_issue_icon_off,
+ labelRes = R.string.qs_record_issue_label
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotAnimationController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotAnimationController.kt
index 3f4f74b..2e4473e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotAnimationController.kt
@@ -155,6 +155,12 @@
val previewAnimator = AnimatorSet()
previewAnimator.play(previewXAndScaleAnimator).with(previewYAnimator)
+ previewAnimator.doOnEnd {
+ screenshotPreview.scaleX = 1f
+ screenshotPreview.scaleY = 1f
+ screenshotPreview.x = endPos.x - screenshotPreview.width / 2f
+ screenshotPreview.y = endPos.y - screenshotPreview.height / 2f
+ }
previewAnimator.doOnStart { screenshotPreview.visibility = View.VISIBLE }
return previewAnimator
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
index e3d2f7d..4b6dd8d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
@@ -199,7 +199,7 @@
for (int i = 0; i < SIM_SLOTS; i++) {
mInfos[i] = new CellSignalState(
- true,
+ false,
R.drawable.ic_shade_no_calling_sms,
context.getText(AccessibilityContentDescriptions.NO_CALLING).toString(),
"",
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 09985f8..7983db1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -21,6 +21,7 @@
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_MANAGEMENT_DISCLOSURE;
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_NAMED_MANAGEMENT_DISCLOSURE;
import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT;
import static android.hardware.biometrics.BiometricSourceType.FACE;
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
import static android.view.View.GONE;
@@ -60,7 +61,6 @@
import android.content.res.Resources;
import android.graphics.Color;
import android.hardware.biometrics.BiometricSourceType;
-import android.hardware.face.FaceManager;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Looper;
@@ -1404,7 +1404,7 @@
mKeyguardLogger.logBiometricMessage("KIC suppressingFaceError", msgId, errString);
return;
}
- if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
+ if (msgId == FACE_ERROR_TIMEOUT) {
handleFaceAuthTimeoutError(deferredFaceMessage);
} else if (mIndicationHelper.isFaceLockoutErrorMsg(msgId)) {
handleFaceLockoutError(errString);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
index 7a7cb7d..c7952b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
@@ -95,6 +95,9 @@
const val AIRPLANE_MODE_TILE_SPEC = "airplane"
const val DATA_SAVER_TILE_SPEC = "saver"
const val INTERNET_TILE_SPEC = "internet"
+ const val HOTSPOT_TILE_SPEC = "hotspot"
+ const val CAST_TILE_SPEC = "cast"
+ const val BLUETOOTH_TILE_SPEC = "bt"
/** Inject InternetTile or InternetTileNewImpl into tileMap in QSModule */
@Provides
@@ -204,5 +207,47 @@
stateInteractor,
mapper,
)
+
+ @Provides
+ @IntoMap
+ @StringKey(HOTSPOT_TILE_SPEC)
+ fun provideHotspotTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(HOTSPOT_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.ic_hotspot,
+ labelRes = R.string.quick_settings_hotspot_label,
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
+
+ @Provides
+ @IntoMap
+ @StringKey(CAST_TILE_SPEC)
+ fun provideCastTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(CAST_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.ic_cast,
+ labelRes = R.string.quick_settings_cast_title,
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
+
+ @Provides
+ @IntoMap
+ @StringKey(BLUETOOTH_TILE_SPEC)
+ fun provideBluetoothTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(BLUETOOTH_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.qs_bluetooth_icon_off,
+ labelRes = R.string.quick_settings_bluetooth_label,
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
}
}
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 2fdd2c6..6b5642a 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
@@ -35,12 +35,13 @@
// view-model (which, at the time of this writing, does not yet exist).
suspend fun bindColor(view: StatusBarIconView, color: Flow<Int>) {
- // Don't change the icon color if an app icon experiment is enabled.
- if (!android.app.Flags.notificationsUseAppIcon()) {
- color.collectTracingEach("SBIV#bindColor") { color ->
+ 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
- view.setDecorColor(color)
}
+ // Continue changing the overflow dot color
+ view.setDecorColor(color)
}
}
@@ -57,15 +58,16 @@
iconColors: Flow<NotificationIconColors>,
contrastColorUtil: ContrastColorUtil,
) {
- // Don't change the icon color if an app icon experiment is enabled.
- if (!android.app.Flags.notificationsUseAppIcon()) {
- iconColors.collectTracingEach("SBIV#bindIconColors") { colors ->
+ 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
- view.setDecorColor(colors.tint)
}
+ // Continue changing the overflow dot color
+ view.setDecorColor(colors.tint)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index de0f247..57504b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -2399,12 +2399,13 @@
private void updateContentHeight() {
final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
final int shelfIntrinsicHeight = mShelf != null ? mShelf.getIntrinsicHeight() : 0;
+ final int footerIntrinsicHeight = mFooterView != null ? mFooterView.getIntrinsicHeight() : 0;
final float height =
(int) scrimTopPadding + (int) mNotificationStackSizeCalculator.computeHeight(
/* notificationStackScrollLayout= */ this, mMaxDisplayedNotifications,
shelfIntrinsicHeight);
mIntrinsicContentHeight = height;
- mScrollViewFields.sendStackHeight(height);
+ mScrollViewFields.sendStackHeight(height + footerIntrinsicHeight);
// The topPadding can be bigger than the regular padding when qs is expanded, in that
// state the maxPanelHeight and the contentHeight should be bigger
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ComponentSystemUIDialog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ComponentSystemUIDialog.kt
index f3a4f0e..fe5a02b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ComponentSystemUIDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ComponentSystemUIDialog.kt
@@ -24,7 +24,6 @@
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
-import androidx.annotation.GravityInt
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
@@ -57,7 +56,7 @@
sysUiState: SysUiState,
broadcastDispatcher: BroadcastDispatcher,
dialogTransitionAnimator: DialogTransitionAnimator,
- @GravityInt private val dialogGravity: Int?,
+ delegate: DialogDelegate<SystemUIDialog>,
) :
SystemUIDialog(
context,
@@ -66,7 +65,8 @@
dialogManager,
sysUiState,
broadcastDispatcher,
- dialogTransitionAnimator
+ dialogTransitionAnimator,
+ delegate,
),
LifecycleOwner,
SavedStateRegistryOwner,
@@ -92,7 +92,6 @@
@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- dialogGravity?.let { window?.setGravity(it) }
onBackPressedDispatcher.setOnBackInvokedDispatcher(onBackInvokedDispatcher)
savedStateRegistryController.performRestore(savedInstanceState)
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DialogDelegate.kt
index b56baee..25d1f05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DialogDelegate.kt
@@ -45,4 +45,8 @@
/** Called as part of [ViewRootImpl.ConfigChangedCallback.onConfigurationChanged]. */
fun onConfigurationChanged(dialog: T, configuration: Configuration) {}
+
+ fun getWidth(dialog: T): Int = SystemUIDialog.getDefaultDialogWidth(dialog)
+
+ fun getHeight(dialog: T): Int = SystemUIDialog.getDefaultDialogHeight()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 2a921dc..c74dde5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -80,7 +80,8 @@
private final Context mContext;
private final DialogDelegate<SystemUIDialog> mDelegate;
- @Nullable private final DismissReceiver mDismissReceiver;
+ @Nullable
+ private final DismissReceiver mDismissReceiver;
private final Handler mHandler = new Handler();
private final SystemUIDialogManager mDialogManager;
private final SysUiState mSysUiState;
@@ -94,7 +95,7 @@
/**
* @deprecated Don't subclass SystemUIDialog. Please subclass {@link Delegate} and pass it to
- * {@link Factory#create(Delegate)} to create a custom dialog.
+ * {@link Factory#create(Delegate)} to create a custom dialog.
*/
@Deprecated
public SystemUIDialog(Context context) {
@@ -137,20 +138,24 @@
mDialogTransitionAnimator = dialogTransitionAnimator;
}
- /** Creates a new instance of {@link SystemUIDialog} with no customized behavior.
+ /**
+ * Creates a new instance of {@link SystemUIDialog} with no customized behavior.
*
* When you just need a dialog, call this.
*/
public SystemUIDialog create() {
- return create(new DialogDelegate<>(){}, mContext, DEFAULT_THEME);
+ return create(new DialogDelegate<>() {
+ }, mContext, DEFAULT_THEME);
}
- /** Creates a new instance of {@link SystemUIDialog} with no customized behavior.
+ /**
+ * Creates a new instance of {@link SystemUIDialog} with no customized behavior.
*
* When you just need a dialog created with a specific {@link Context}, call this.
*/
public SystemUIDialog create(Context context) {
- return create(new DialogDelegate<>(){}, context, DEFAULT_THEME);
+ return create(new DialogDelegate<>() {
+ }, context, DEFAULT_THEME);
}
/**
@@ -162,6 +167,7 @@
public SystemUIDialog create(Delegate delegate, Context context) {
return create(delegate, context, DEFAULT_THEME);
}
+
public SystemUIDialog create(Delegate delegate, Context context, @StyleRes int theme) {
return create((DialogDelegate<SystemUIDialog>) delegate, context, theme);
}
@@ -200,7 +206,8 @@
sysUiState,
broadcastDispatcher,
dialogTransitionAnimator,
- new DialogDelegate<>(){});
+ new DialogDelegate<>() {
+ });
}
public SystemUIDialog(
@@ -305,7 +312,7 @@
* the device configuration changes, and the result will be used to resize this dialog window.
*/
protected int getWidth() {
- return getDefaultDialogWidth(this);
+ return mDelegate.getWidth(this);
}
/**
@@ -313,7 +320,7 @@
* the device configuration changes, and the result will be used to resize this dialog window.
*/
protected int getHeight() {
- return getDefaultDialogHeight();
+ return mDelegate.getHeight(this);
}
@Override
@@ -496,7 +503,7 @@
* <strong>Note:</strong> Don't call dialog.setOnDismissListener() after
* calling this because it causes a leak of BroadcastReceiver.
*
- * @param dialog The dialog to be associated with the listener.
+ * @param dialog The dialog to be associated with the listener.
* @param dismissAction An action to run when the dialog is dismissed.
*/
public static void registerDismissListener(Dialog dialog, @Nullable Runnable dismissAction) {
@@ -519,7 +526,7 @@
dialog.getWindow().setLayout(getDefaultDialogWidth(dialog), getDefaultDialogHeight());
}
- private static int getDefaultDialogWidth(Dialog dialog) {
+ static int getDefaultDialogWidth(Dialog dialog) {
Context context = dialog.getContext();
int flagValue = SystemProperties.getInt(FLAG_TABLET_DIALOG_WIDTH, 0);
if (flagValue == -1) {
@@ -570,12 +577,13 @@
return insets.left + insets.right;
}
- private static int getDefaultDialogHeight() {
+ static int getDefaultDialogHeight() {
return ViewGroup.LayoutParams.WRAP_CONTENT;
}
private static class DismissReceiver extends BroadcastReceiver {
private static final IntentFilter INTENT_FILTER = new IntentFilter();
+
static {
INTENT_FILTER.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
INTENT_FILTER.addAction(Intent.ACTION_SCREEN_OFF);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogFactory.kt
index 1edd4d1..9ecb212 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogFactory.kt
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.phone
import android.content.Context
-import androidx.annotation.GravityInt
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Application
@@ -44,14 +43,12 @@
* @param context the [Context] in which the dialog will be constructed.
* @param dismissOnDeviceLock whether the dialog should be automatically dismissed when the
* device is locked (true by default).
- * @param dialogGravity is one of the [android.view.Gravity] and determines dialog position on
- * the screen.
*/
fun create(
context: Context = this.applicationContext,
theme: Int = SystemUIDialog.DEFAULT_THEME,
dismissOnDeviceLock: Boolean = SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK,
- @GravityInt dialogGravity: Int? = null,
+ dialogDelegate: DialogDelegate<SystemUIDialog> = object : DialogDelegate<SystemUIDialog> {},
): ComponentSystemUIDialog {
Assert.isMainThread()
@@ -63,7 +60,7 @@
sysUiState,
broadcastDispatcher,
dialogTransitionAnimator,
- dialogGravity,
+ dialogDelegate,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
index 4f702d7..d4b2dbf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
@@ -102,6 +102,15 @@
)
}
+ fun logOnCarrierRoamingNtnModeChanged(active: Boolean) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ { bool1 = active },
+ { "onCarrierRoamingNtnModeChanged: $bool1" }
+ )
+ }
+
fun logOnDisplayInfoChanged(displayInfo: TelephonyDisplayInfo, subId: Int) {
buffer.log(
TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index b3885d2..6803a9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -142,21 +142,33 @@
val callback =
object :
TelephonyCallback(),
- TelephonyCallback.ServiceStateListener,
- TelephonyCallback.SignalStrengthsListener,
- TelephonyCallback.DataConnectionStateListener,
- TelephonyCallback.DataActivityListener,
TelephonyCallback.CarrierNetworkListener,
+ TelephonyCallback.CarrierRoamingNtnModeListener,
+ TelephonyCallback.DataActivityListener,
+ TelephonyCallback.DataConnectionStateListener,
+ TelephonyCallback.DataEnabledListener,
TelephonyCallback.DisplayInfoListener,
- TelephonyCallback.DataEnabledListener {
- override fun onServiceStateChanged(serviceState: ServiceState) {
- logger.logOnServiceStateChanged(serviceState, subId)
- trySend(CallbackEvent.OnServiceStateChanged(serviceState))
+ TelephonyCallback.ServiceStateListener,
+ TelephonyCallback.SignalStrengthsListener {
+
+ override fun onCarrierNetworkChange(active: Boolean) {
+ logger.logOnCarrierNetworkChange(active, subId)
+ trySend(CallbackEvent.OnCarrierNetworkChange(active))
}
- override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
- logger.logOnSignalStrengthsChanged(signalStrength, subId)
- trySend(CallbackEvent.OnSignalStrengthChanged(signalStrength))
+ override fun onCarrierRoamingNtnModeChanged(active: Boolean) {
+ logger.logOnCarrierRoamingNtnModeChanged(active)
+ trySend(CallbackEvent.OnCarrierRoamingNtnModeChanged(active))
+ }
+
+ override fun onDataActivity(direction: Int) {
+ logger.logOnDataActivity(direction, subId)
+ trySend(CallbackEvent.OnDataActivity(direction))
+ }
+
+ override fun onDataEnabledChanged(enabled: Boolean, reason: Int) {
+ logger.logOnDataEnabledChanged(enabled, subId)
+ trySend(CallbackEvent.OnDataEnabledChanged(enabled))
}
override fun onDataConnectionStateChanged(
@@ -167,16 +179,6 @@
trySend(CallbackEvent.OnDataConnectionStateChanged(dataState))
}
- override fun onDataActivity(direction: Int) {
- logger.logOnDataActivity(direction, subId)
- trySend(CallbackEvent.OnDataActivity(direction))
- }
-
- override fun onCarrierNetworkChange(active: Boolean) {
- logger.logOnCarrierNetworkChange(active, subId)
- trySend(CallbackEvent.OnCarrierNetworkChange(active))
- }
-
override fun onDisplayInfoChanged(
telephonyDisplayInfo: TelephonyDisplayInfo
) {
@@ -184,9 +186,14 @@
trySend(CallbackEvent.OnDisplayInfoChanged(telephonyDisplayInfo))
}
- override fun onDataEnabledChanged(enabled: Boolean, reason: Int) {
- logger.logOnDataEnabledChanged(enabled, subId)
- trySend(CallbackEvent.OnDataEnabledChanged(enabled))
+ override fun onServiceStateChanged(serviceState: ServiceState) {
+ logger.logOnServiceStateChanged(serviceState, subId)
+ trySend(CallbackEvent.OnServiceStateChanged(serviceState))
+ }
+
+ override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
+ logger.logOnSignalStrengthsChanged(signalStrength, subId)
+ trySend(CallbackEvent.OnSignalStrengthChanged(signalStrength))
}
}
telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback)
@@ -229,8 +236,8 @@
override val isNonTerrestrial =
callbackEvents
- .mapNotNull { it.onServiceStateChanged }
- .map { it.serviceState.isUsingNonTerrestrialNetwork }
+ .mapNotNull { it.onCarrierRoamingNtnModeChanged }
+ .map { it.active }
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
override val isGsm =
@@ -502,6 +509,8 @@
sealed interface CallbackEvent {
data class OnCarrierNetworkChange(val active: Boolean) : CallbackEvent
+ data class OnCarrierRoamingNtnModeChanged(val active: Boolean) : CallbackEvent
+
data class OnDataActivity(val direction: Int) : CallbackEvent
data class OnDataConnectionStateChanged(val dataState: Int) : CallbackEvent
@@ -522,6 +531,7 @@
data class TelephonyCallbackState(
val onDataActivity: CallbackEvent.OnDataActivity? = null,
val onCarrierNetworkChange: CallbackEvent.OnCarrierNetworkChange? = null,
+ val onCarrierRoamingNtnModeChanged: CallbackEvent.OnCarrierRoamingNtnModeChanged? = null,
val onDataConnectionStateChanged: CallbackEvent.OnDataConnectionStateChanged? = null,
val onDataEnabledChanged: CallbackEvent.OnDataEnabledChanged? = null,
val onDisplayInfoChanged: CallbackEvent.OnDisplayInfoChanged? = null,
@@ -531,6 +541,9 @@
fun applyEvent(event: CallbackEvent): TelephonyCallbackState {
return when (event) {
is CallbackEvent.OnCarrierNetworkChange -> copy(onCarrierNetworkChange = event)
+ is CallbackEvent.OnCarrierRoamingNtnModeChanged -> {
+ copy(onCarrierRoamingNtnModeChanged = event)
+ }
is CallbackEvent.OnDataActivity -> copy(onDataActivity = event)
is CallbackEvent.OnDataConnectionStateChanged ->
copy(onDataConnectionStateChanged = event)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
index db4e605d..08f973b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
@@ -88,6 +88,7 @@
const val WORK_MODE_TILE_SPEC = "work"
const val CAMERA_TOGGLE_TILE_SPEC = "cameratoggle"
const val MIC_TOGGLE_TILE_SPEC = "mictoggle"
+ const val DND_TILE_SPEC = "dnd"
/** Inject flashlight config */
@Provides
@@ -136,10 +137,7 @@
instanceId = uiEventLogger.getNewInstanceId(),
policy =
QSTilePolicy.Restricted(
- listOf(
- DISALLOW_SHARE_LOCATION,
- DISALLOW_CONFIG_LOCATION
- )
+ listOf(DISALLOW_SHARE_LOCATION, DISALLOW_CONFIG_LOCATION)
)
)
@@ -321,6 +319,21 @@
stateInteractor.create(MICROPHONE),
mapper.create(SensorPrivacyTileResources.MicrophonePrivacyTileResources),
)
+
+ /** Inject microphone toggle config */
+ @Provides
+ @IntoMap
+ @StringKey(DND_TILE_SPEC)
+ fun provideDndTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+ QSTileConfig(
+ tileSpec = TileSpec.create(DND_TILE_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.qs_dnd_icon_off,
+ labelRes = R.string.quick_settings_dnd_label,
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ )
}
/** Inject FlashlightTile into tileMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractor.kt
index 382bc03..9339651 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractor.kt
@@ -76,6 +76,7 @@
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
@@ -164,81 +165,87 @@
val actions: Flow<List<UserActionModel>>
get() =
combine(
- repository.selectedUserInfo,
- userInfos,
- repository.userSwitcherSettings,
- keyguardInteractor.isKeyguardShowing,
- ) { _, userInfos, settings, isDeviceLocked ->
- buildList {
- val canAccessUserSwitcher = !isDeviceLocked || settings.isAddUsersFromLockscreen
- if (canAccessUserSwitcher) {
- // The device is locked and our setting to allow actions that add users
- // from the lock-screen is not enabled. We can finish building the list
- // here.
- val isFullScreen = featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)
+ repository.selectedUserInfo,
+ userInfos,
+ repository.userSwitcherSettings,
+ keyguardInteractor.isKeyguardShowing,
+ ) { _, userInfos, settings, isDeviceLocked ->
+ buildList {
+ val canAccessUserSwitcher =
+ !isDeviceLocked || settings.isAddUsersFromLockscreen
+ if (canAccessUserSwitcher) {
+ // The device is locked and our setting to allow actions that add users
+ // from the lock-screen is not enabled. We can finish building the list
+ // here.
+ val isFullScreen =
+ featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)
- val actionList: List<UserActionModel> =
- if (isFullScreen) {
- listOf(
- UserActionModel.ADD_USER,
- UserActionModel.ADD_SUPERVISED_USER,
- UserActionModel.ENTER_GUEST_MODE,
- )
- } else {
- listOf(
- UserActionModel.ENTER_GUEST_MODE,
- UserActionModel.ADD_USER,
- UserActionModel.ADD_SUPERVISED_USER,
- )
- }
- actionList.map {
- when (it) {
- UserActionModel.ENTER_GUEST_MODE -> {
- val hasGuestUser = userInfos.any { it.isGuest }
- if (
- !hasGuestUser &&
- canCreateGuestUser(settings, canAccessUserSwitcher)
- ) {
- add(UserActionModel.ENTER_GUEST_MODE)
- }
+ val actionList: List<UserActionModel> =
+ if (isFullScreen) {
+ listOf(
+ UserActionModel.ADD_USER,
+ UserActionModel.ADD_SUPERVISED_USER,
+ UserActionModel.ENTER_GUEST_MODE,
+ )
+ } else {
+ listOf(
+ UserActionModel.ENTER_GUEST_MODE,
+ UserActionModel.ADD_USER,
+ UserActionModel.ADD_SUPERVISED_USER,
+ )
}
- UserActionModel.ADD_USER -> {
- val canCreateUsers =
- UserActionsUtil.canCreateUser(
- manager,
- repository,
- settings.isUserSwitcherEnabled,
- canAccessUserSwitcher
- )
+ actionList.map {
+ when (it) {
+ UserActionModel.ENTER_GUEST_MODE -> {
+ val hasGuestUser = userInfos.any { it.isGuest }
+ if (
+ !hasGuestUser &&
+ canCreateGuestUser(settings, canAccessUserSwitcher)
+ ) {
+ add(UserActionModel.ENTER_GUEST_MODE)
+ }
+ }
+ UserActionModel.ADD_USER -> {
+ val canCreateUsers =
+ UserActionsUtil.canCreateUser(
+ manager,
+ repository,
+ settings.isUserSwitcherEnabled,
+ canAccessUserSwitcher
+ )
- if (canCreateUsers) {
- add(UserActionModel.ADD_USER)
+ if (canCreateUsers) {
+ add(UserActionModel.ADD_USER)
+ }
}
- }
- UserActionModel.ADD_SUPERVISED_USER -> {
- if (
- UserActionsUtil.canCreateSupervisedUser(
- manager,
- repository,
- settings.isUserSwitcherEnabled,
- canAccessUserSwitcher,
- supervisedUserPackageName,
- )
- ) {
- add(UserActionModel.ADD_SUPERVISED_USER)
+ UserActionModel.ADD_SUPERVISED_USER -> {
+ if (
+ UserActionsUtil.canCreateSupervisedUser(
+ manager,
+ repository,
+ settings.isUserSwitcherEnabled,
+ canAccessUserSwitcher,
+ supervisedUserPackageName,
+ )
+ ) {
+ add(UserActionModel.ADD_SUPERVISED_USER)
+ }
}
+ else -> Unit
}
- else -> Unit
}
}
- }
- if (
- UserActionsUtil.canManageUsers(repository, settings.isUserSwitcherEnabled)
- ) {
- add(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT)
+ if (
+ UserActionsUtil.canManageUsers(
+ repository,
+ settings.isUserSwitcherEnabled
+ )
+ ) {
+ add(UserActionModel.NAVIGATE_TO_USER_MANAGEMENT)
+ }
}
}
- }
+ .flowOn(backgroundDispatcher)
val userRecords: StateFlow<ArrayList<UserRecord>> =
combine(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index 1f87ec8..fb92a0f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -16,7 +16,6 @@
package com.android.systemui.volume.dagger;
-import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.os.Looper;
@@ -42,7 +41,6 @@
import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
import com.android.systemui.volume.panel.dagger.VolumePanelComponent;
import com.android.systemui.volume.panel.dagger.factory.VolumePanelComponentFactory;
-import com.android.systemui.volume.panel.ui.activity.VolumePanelActivity;
import com.android.systemui.volume.ui.navigation.VolumeNavigator;
import dagger.Binds;
@@ -82,12 +80,6 @@
@Binds
VolumeComponent provideVolumeComponent(VolumeDialogComponent volumeDialogComponent);
- /** Inject into VolumePanelActivity. */
- @Binds
- @IntoMap
- @ClassKey(VolumePanelActivity.class)
- Activity bindVolumePanelActivity(VolumePanelActivity activity);
-
/** */
@Binds
VolumePanelComponentFactory bindVolumePanelComponentFactory(VolumePanelComponent.Factory impl);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/CoroutineModule.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/CoroutineModule.kt
deleted file mode 100644
index 3ce0bac..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/CoroutineModule.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.volume.panel.dagger
-
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
-import dagger.Module
-import dagger.Provides
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.SupervisorJob
-
-/** Provides Volume Panel coroutine tools. */
-@Module
-interface CoroutineModule {
-
- companion object {
-
- /**
- * Provides a coroutine scope to use inside [VolumePanelScope].
- * [com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel] manages the
- * lifecycle of this scope. It's cancelled when the View Model is destroyed. This helps to
- * free occupied resources when volume panel is not shown.
- */
- @VolumePanelScope
- @Provides
- fun provideCoroutineScope(@Application applicationScope: CoroutineScope): CoroutineScope =
- CoroutineScope(applicationScope.coroutineContext + SupervisorJob())
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/VolumePanelComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/VolumePanelComponent.kt
index ec64f3d9..30d865b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/VolumePanelComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/VolumePanelComponent.kt
@@ -45,7 +45,6 @@
modules =
[
// Volume Panel infra modules
- CoroutineModule::class,
DefaultMultibindsModule::class,
DomainModule::class,
UiModule::class,
@@ -61,6 +60,12 @@
)
interface VolumePanelComponent {
+ /**
+ * Provides a coroutine scope to use inside [VolumePanelScope].
+ * [com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel] manages the lifecycle
+ * of this scope. It's cancelled when the View Model is destroyed. This helps to free occupied
+ * resources when volume panel is not shown.
+ */
fun coroutineScope(): CoroutineScope
fun componentsInteractor(): ComponentsInteractor
@@ -74,6 +79,9 @@
@Subcomponent.Factory
interface Factory : VolumePanelComponentFactory {
- override fun create(@BindsInstance viewModel: VolumePanelViewModel): VolumePanelComponent
+ override fun create(
+ @BindsInstance viewModel: VolumePanelViewModel,
+ @BindsInstance scope: CoroutineScope,
+ ): VolumePanelComponent
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/factory/VolumePanelComponentFactory.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/factory/VolumePanelComponentFactory.kt
index e470c3f..5c36b01 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/factory/VolumePanelComponentFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/dagger/factory/VolumePanelComponentFactory.kt
@@ -19,6 +19,7 @@
import com.android.systemui.volume.panel.dagger.VolumePanelComponent
import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel
import dagger.BindsInstance
+import kotlinx.coroutines.CoroutineScope
/**
* Common interface for all [dagger.Subcomponent.Factory] providing [VolumePanelComponent].
@@ -26,5 +27,8 @@
*/
interface VolumePanelComponentFactory {
- fun create(@BindsInstance viewModel: VolumePanelViewModel): VolumePanelComponent
+ fun create(
+ @BindsInstance viewModel: VolumePanelViewModel,
+ @BindsInstance scope: CoroutineScope,
+ ): VolumePanelComponent
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/activity/VolumePanelActivity.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/activity/VolumePanelActivity.kt
deleted file mode 100644
index ccb91ac..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/activity/VolumePanelActivity.kt
+++ /dev/null
@@ -1,65 +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.volume.panel.ui.activity
-
-import android.os.Bundle
-import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.activity.enableEdgeToEdge
-import androidx.activity.viewModels
-import com.android.internal.logging.UiEventLogger
-import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag
-import com.android.systemui.volume.panel.ui.VolumePanelUiEvent
-import com.android.systemui.volume.panel.ui.composable.VolumePanelRoot
-import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel
-import javax.inject.Inject
-import javax.inject.Provider
-
-class VolumePanelActivity
-@Inject
-constructor(
- private val volumePanelViewModelFactory: Provider<VolumePanelViewModel.Factory>,
- private val volumePanelFlag: VolumePanelFlag,
- private val configurationController: ConfigurationController,
- private val uiEventLogger: UiEventLogger,
-) : ComponentActivity() {
-
- private val viewModel: VolumePanelViewModel by
- viewModels(factoryProducer = { volumePanelViewModelFactory.get() })
-
- override fun onCreate(savedInstanceState: Bundle?) {
- enableEdgeToEdge()
- super.onCreate(savedInstanceState)
- volumePanelFlag.assertNewVolumePanel()
- uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_SHOWN)
- setContent {
- VolumePanelRoot(
- viewModel = viewModel,
- onDismiss = {
- uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_GONE)
- finish()
- }
- )
- }
- }
-
- override fun onContentChanged() {
- super.onContentChanged()
- configurationController.onConfigurationChanged(resources.configuration)
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt
index 1de4fd1..eff408a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt
@@ -18,8 +18,6 @@
import android.content.Context
import android.content.res.Resources
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -33,7 +31,6 @@
import com.android.systemui.volume.panel.ui.layout.ComponentsLayoutManager
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -45,13 +42,17 @@
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
+// Can't inject a constructor here because VolumePanelComponent provides this view model for its
+// components.
class VolumePanelViewModel(
resources: Resources,
+ coroutineScope: CoroutineScope,
daggerComponentFactory: VolumePanelComponentFactory,
configurationController: ConfigurationController,
-) : ViewModel() {
+) {
- private val volumePanelComponent: VolumePanelComponent = daggerComponentFactory.create(this)
+ private val volumePanelComponent: VolumePanelComponent =
+ daggerComponentFactory.create(this, coroutineScope)
private val scope: CoroutineScope
get() = volumePanelComponent.coroutineScope()
@@ -118,28 +119,21 @@
mutablePanelVisibility.update { false }
}
- override fun onCleared() {
- scope.cancel()
- super.onCleared()
- }
-
class Factory
@Inject
constructor(
@Application private val context: Context,
private val daggerComponentFactory: VolumePanelComponentFactory,
private val configurationController: ConfigurationController,
- ) : ViewModelProvider.Factory {
+ ) {
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- check(modelClass == VolumePanelViewModel::class.java)
+ fun create(coroutineScope: CoroutineScope): VolumePanelViewModel {
return VolumePanelViewModel(
context.resources,
+ coroutineScope,
daggerComponentFactory,
configurationController,
)
- as T
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ui/navigation/VolumeNavigator.kt b/packages/SystemUI/src/com/android/systemui/volume/ui/navigation/VolumeNavigator.kt
index 790638c..eae33af 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ui/navigation/VolumeNavigator.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/ui/navigation/VolumeNavigator.kt
@@ -16,37 +16,41 @@
package com.android.systemui.volume.ui.navigation
-import android.content.Context
import android.content.Intent
import android.provider.Settings
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.rememberCoroutineScope
+import com.android.internal.logging.UiEventLogger
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.statusbar.phone.SystemUIDialogFactory
+import com.android.systemui.statusbar.phone.createBottomSheet
import com.android.systemui.volume.VolumePanelFactory
import com.android.systemui.volume.domain.model.VolumePanelRoute
-import com.android.systemui.volume.panel.ui.activity.VolumePanelActivity
+import com.android.systemui.volume.panel.ui.VolumePanelUiEvent
+import com.android.systemui.volume.panel.ui.composable.VolumePanelRoot
+import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel
import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
class VolumeNavigator
@Inject
constructor(
- @Application private val context: Context,
+ @Application private val applicationScope: CoroutineScope,
+ @Main private val mainContext: CoroutineContext,
private val volumePanelFactory: VolumePanelFactory,
private val activityStarter: ActivityStarter,
+ private val viewModelFactory: VolumePanelViewModel.Factory,
+ private val dialogFactory: SystemUIDialogFactory,
+ private val uiEventLogger: UiEventLogger,
) {
fun openVolumePanel(route: VolumePanelRoute) {
when (route) {
- VolumePanelRoute.COMPOSE_VOLUME_PANEL ->
- activityStarter.startActivityDismissingKeyguard(
- /* intent = */ Intent(context, VolumePanelActivity::class.java),
- /* onlyProvisioned = */ false,
- /* dismissShade= */ true,
- /* disallowEnterPictureInPictureWhileLaunching = */ true,
- /* callback= */ null,
- /* flags= */ 0,
- /* animationController= */ null,
- /* userHandle= */ null,
- )
+ VolumePanelRoute.COMPOSE_VOLUME_PANEL -> showNewVolumePanel()
VolumePanelRoute.SETTINGS_VOLUME_PANEL ->
activityStarter.startActivity(
/* intent= */ Intent(Settings.Panel.ACTION_VOLUME),
@@ -56,4 +60,25 @@
volumePanelFactory.create(aboveStatusBar = true, view = null)
}
}
+
+ private fun showNewVolumePanel() {
+ applicationScope.launch(mainContext) {
+ dialogFactory
+ .createBottomSheet(
+ content = { dialog ->
+ LaunchedEffect(dialog) {
+ dialog.setOnDismissListener {
+ uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_GONE)
+ }
+ }
+
+ VolumePanelRoot(
+ viewModel = viewModelFactory.create(rememberCoroutineScope()),
+ onDismiss = { dialog.dismiss() },
+ )
+ },
+ )
+ .show()
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index d354fa2..d6f0ef8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -19,6 +19,7 @@
import static android.app.StatusBarManager.SESSION_KEYGUARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
import static android.hardware.biometrics.SensorProperties.STRENGTH_CONVENIENCE;
@@ -82,7 +83,6 @@
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
-import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -2276,8 +2276,7 @@
private void faceAuthLockOut() {
when(mFaceAuthInteractor.isLockedOut()).thenReturn(true);
mFaceAuthenticationListener.getValue().onAuthenticationStatusChanged(
- new ErrorFaceAuthenticationStatus(FaceManager.FACE_ERROR_LOCKOUT_PERMANENT, "",
- 0L));
+ new ErrorFaceAuthenticationStatus(FACE_ERROR_LOCKOUT_PERMANENT, "", 0L));
}
private void statusBarShadeIsNotLocked() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
index 1e3b556..d01d57e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
@@ -24,26 +24,35 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.Region;
+import android.hardware.display.DisplayManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.testing.AndroidTestingRunner;
-import android.util.Pair;
+import android.testing.TestableLooper;
import android.view.GestureDetector;
import android.view.IWindowManager;
import android.view.InputEvent;
import android.view.MotionEvent;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
-import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
import androidx.test.filters.SmallTest;
+import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.ambient.touch.dagger.InputSessionComponent;
+import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.display.DisplayHelper;
@@ -67,31 +76,58 @@
@SmallTest
@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class TouchMonitorTest extends SysuiTestCase {
+ private KosmosJavaAdapter mKosmos;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+ mKosmos = new KosmosJavaAdapter(this);
+ }
+
+ private static class SimpleLifecycleOwner implements LifecycleOwner {
+ LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
+ @NonNull
+ @Override
+ public Lifecycle getLifecycle() {
+ return mLifecycle;
+ }
+
+ public void setState(Lifecycle.State state) {
+ mLifecycle.setCurrentState(state);
+ }
}
private static class Environment {
private final InputSessionComponent.Factory mInputFactory;
private final InputSession mInputSession;
- private final Lifecycle mLifecycle;
- private final LifecycleOwner mLifecycleOwner;
+ private final SimpleLifecycleOwner mLifecycleOwner;
+
+ private final LifecycleRegistry mLifecycleRegistry;
private final TouchMonitor mMonitor;
- private final DefaultLifecycleObserver mLifecycleObserver;
private final InputChannelCompat.InputEventListener mEventListener;
private final GestureDetector.OnGestureListener mGestureListener;
private final DisplayHelper mDisplayHelper;
+ private final DisplayManager mDisplayManager;
+ private final WindowManager mWindowManager;
+ private final WindowMetrics mWindowMetrics;
private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private final FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
+
private final Rect mDisplayBounds = Mockito.mock(Rect.class);
private final IWindowManager mIWindowManager;
- Environment(Set<TouchHandler> handlers) {
- mLifecycle = Mockito.mock(Lifecycle.class);
- mLifecycleOwner = Mockito.mock(LifecycleOwner.class);
+ private final KosmosJavaAdapter mKosmos;
+
+
+ Environment(Set<TouchHandler> handlers, KosmosJavaAdapter kosmos) {
+ mLifecycleOwner = new SimpleLifecycleOwner();
+ mLifecycleRegistry = spy(new LifecycleRegistry(mLifecycleOwner));
+
mIWindowManager = Mockito.mock(IWindowManager.class);
+ mDisplayManager = Mockito.mock(DisplayManager.class);
+ mWindowManager = Mockito.mock(WindowManager.class);
+ mKosmos = kosmos;
mInputFactory = Mockito.mock(InputSessionComponent.Factory.class);
final InputSessionComponent inputComponent = Mockito.mock(InputSessionComponent.class);
@@ -104,18 +140,16 @@
mDisplayHelper = Mockito.mock(DisplayHelper.class);
when(mDisplayHelper.getMaxBounds(anyInt(), anyInt()))
.thenReturn(mDisplayBounds);
- mMonitor = new TouchMonitor(mExecutor, mBackgroundExecutor,
- mLifecycle, mInputFactory, mDisplayHelper, handlers, mIWindowManager, 0);
+
+ mWindowMetrics = Mockito.mock(WindowMetrics.class);
+ when(mWindowMetrics.getBounds()).thenReturn(mDisplayBounds);
+ when(mWindowManager.getMaximumWindowMetrics()).thenReturn(mWindowMetrics);
+ mMonitor = new TouchMonitor(mExecutor, mBackgroundExecutor, mLifecycleRegistry,
+ mInputFactory, mDisplayHelper, mKosmos.getConfigurationInteractor(),
+ handlers, mIWindowManager, 0);
mMonitor.init();
- final ArgumentCaptor<LifecycleObserver> lifecycleObserverCaptor =
- ArgumentCaptor.forClass(LifecycleObserver.class);
- verify(mLifecycle).addObserver(lifecycleObserverCaptor.capture());
- assertThat(lifecycleObserverCaptor.getValue() instanceof DefaultLifecycleObserver)
- .isTrue();
- mLifecycleObserver = (DefaultLifecycleObserver) lifecycleObserverCaptor.getValue();
-
- updateLifecycle(observer -> observer.first.onResume(observer.second));
+ updateLifecycle(Lifecycle.State.RESUMED);
// Capture creation request.
final ArgumentCaptor<InputChannelCompat.InputEventListener> inputEventListenerCaptor =
@@ -145,8 +179,8 @@
listenerConsumer.accept(mGestureListener);
}
- void updateLifecycle(Consumer<Pair<DefaultLifecycleObserver, LifecycleOwner>> consumer) {
- consumer.accept(Pair.create(mLifecycleObserver, mLifecycleOwner));
+ void updateLifecycle(Lifecycle.State state) {
+ mLifecycleRegistry.setCurrentState(state);
}
void verifyInputSessionDispose() {
@@ -156,10 +190,33 @@
}
@Test
+ @EnableFlags(Flags.FLAG_AMBIENT_TOUCH_MONITOR_LISTEN_TO_DISPLAY_CHANGES)
+ public void testConfigurationListenerUpdatesBounds() {
+ final TouchHandler touchHandler = createTouchHandler();
+ final Environment environment = new Environment(Stream.of(touchHandler)
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
+ ArgumentCaptor<DisplayManager.DisplayListener> listenerCaptor =
+ ArgumentCaptor.forClass(DisplayManager.DisplayListener.class);
+ final Rect testRect = new Rect(0, 0, 2, 2);
+ final Configuration configuration = new Configuration();
+ configuration.windowConfiguration.setMaxBounds(testRect);
+
+ mKosmos.getConfigurationRepository().onConfigurationChange(configuration);
+ final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
+ when(initialEvent.getX()).thenReturn(0.0f);
+ when(initialEvent.getY()).thenReturn(0.0f);
+ environment.publishInputEvent(initialEvent);
+
+ // Verify display bounds passed into TouchHandler#getTouchInitiationRegion
+ verify(touchHandler).getTouchInitiationRegion(eq(testRect), any(), any());
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_AMBIENT_TOUCH_MONITOR_LISTEN_TO_DISPLAY_CHANGES)
public void testReportedDisplayBounds() {
final TouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
when(initialEvent.getX()).thenReturn(0.0f);
@@ -190,7 +247,7 @@
}).when(touchHandler).getTouchInitiationRegion(any(), any(), any());
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
// Ensure touch outside specified region is not delivered.
final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
@@ -219,7 +276,7 @@
}).when(touchHandler).getTouchInitiationRegion(any(), any(), any());
final Environment environment = new Environment(Stream.of(touchHandler, unzonedTouchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
// Ensure touch outside specified region is delivered to unzoned touch handler.
final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
@@ -261,7 +318,7 @@
when(touchHandler.isEnabled()).thenReturn(false);
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
when(initialEvent.getX()).thenReturn(5.0f);
when(initialEvent.getY()).thenReturn(5.0f);
@@ -277,7 +334,7 @@
final TouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -297,7 +354,7 @@
final TouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -321,7 +378,7 @@
final TouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -340,7 +397,7 @@
final TouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -365,7 +422,7 @@
when(touchHandler2.isEnabled()).thenReturn(true);
final Environment environment = new Environment(Stream.of(touchHandler, touchHandler2)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -389,7 +446,7 @@
final TouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -435,7 +492,7 @@
Mockito.mock(TouchHandler.TouchSession.Callback.class);
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -453,11 +510,9 @@
final TouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
- environment.updateLifecycle(observerOwnerPair -> {
- observerOwnerPair.first.onPause(observerOwnerPair.second);
- });
+ environment.updateLifecycle(Lifecycle.State.STARTED);
environment.verifyInputSessionDispose();
}
@@ -467,7 +522,7 @@
final TouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -486,9 +541,7 @@
verify(touchHandler).onSessionStart(touchSessionArgumentCaptor.capture());
- environment.updateLifecycle(observerOwnerPair -> {
- observerOwnerPair.first.onPause(observerOwnerPair.second);
- });
+ environment.updateLifecycle(Lifecycle.State.STARTED);
verify(environment.mInputSession, never()).dispose();
@@ -505,7 +558,7 @@
final TouchHandler touchHandler = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -524,9 +577,7 @@
verify(touchHandler).onSessionStart(touchSessionArgumentCaptor.capture());
- environment.updateLifecycle(observerOwnerPair -> {
- observerOwnerPair.first.onDestroy(observerOwnerPair.second);
- });
+ environment.updateLifecycle(Lifecycle.State.DESTROYED);
// Check to make sure the input session is now disposed.
environment.verifyInputSessionDispose();
@@ -538,7 +589,7 @@
final TouchHandler touchHandler1 = createTouchHandler();
final TouchHandler touchHandler2 = createTouchHandler();
final Environment environment = new Environment(Stream.of(touchHandler1, touchHandler2)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -574,7 +625,7 @@
Mockito.mock(TouchHandler.TouchSession.Callback.class);
final Environment environment = new Environment(Stream.of(touchHandler)
- .collect(Collectors.toCollection(HashSet::new)));
+ .collect(Collectors.toCollection(HashSet::new)), mKosmos);
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
@@ -584,9 +635,7 @@
environment.executeAll();
- environment.updateLifecycle(observerOwnerPair -> {
- observerOwnerPair.first.onDestroy(observerOwnerPair.second);
- });
+ environment.updateLifecycle(Lifecycle.State.DESTROYED);
environment.executeAll();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt
index 9e007e9..63b4ff7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt
@@ -91,7 +91,7 @@
@Test
fun maxBoundsChange_emitsMaxBoundsChange() =
testScope.runTest {
- val values by collectValues(underTest.naturalMaxBounds)
+ val values by collectValues(underTest.maxBounds)
updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
runCurrent()
@@ -109,7 +109,7 @@
@Test
fun maxBoundsSameOnConfigChange_doesNotEmitMaxBoundsChange() =
testScope.runTest {
- val values by collectValues(underTest.naturalMaxBounds)
+ val values by collectValues(underTest.maxBounds)
updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
runCurrent()
@@ -122,6 +122,48 @@
@Test
fun firstMaxBoundsChange_emitsMaxBoundsChange() =
testScope.runTest {
+ val values by collectValues(underTest.maxBounds)
+
+ updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
+ runCurrent()
+
+ assertThat(values).containsExactly(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT))
+ }
+
+ @Test
+ fun maxBoundsChange_emitsNaturalMaxBoundsChange() =
+ testScope.runTest {
+ val values by collectValues(underTest.naturalMaxBounds)
+
+ updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
+ runCurrent()
+ updateDisplay(width = DISPLAY_WIDTH * 2, height = DISPLAY_HEIGHT * 3)
+ runCurrent()
+
+ assertThat(values)
+ .containsExactly(
+ Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT),
+ Rect(0, 0, DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 3),
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun maxBoundsSameOnConfigChange_doesNotEmitNaturalMaxBoundsChange() =
+ testScope.runTest {
+ val values by collectValues(underTest.naturalMaxBounds)
+
+ updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
+ runCurrent()
+ updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
+ runCurrent()
+
+ assertThat(values).containsExactly(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT))
+ }
+
+ @Test
+ fun firstMaxBoundsChange_emitsNaturalMaxBoundsChange() =
+ testScope.runTest {
val values by collectValues(underTest.naturalMaxBounds)
updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
@@ -131,7 +173,7 @@
}
@Test
- fun displayRotatedButMaxBoundsTheSame_doesNotEmitNewMaxBoundsChange() =
+ fun displayRotatedButMaxBoundsTheSame_doesNotEmitNewNaturalMaxBoundsChange() =
testScope.runTest {
val values by collectValues(underTest.naturalMaxBounds)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
index 5581f0c..431fef6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
@@ -17,7 +17,9 @@
package com.android.systemui.deviceentry.domain.interactor
import android.content.res.mainResources
-import android.hardware.face.FaceManager
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT
import android.hardware.fingerprint.FingerprintManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -266,7 +268,7 @@
faceAuthRepository.setAuthenticationStatus(
HelpFaceAuthenticationStatus(
msg = "Move left",
- msgId = FaceManager.FACE_ACQUIRED_TOO_RIGHT,
+ msgId = FACE_ACQUIRED_TOO_RIGHT,
)
)
@@ -293,7 +295,7 @@
faceAuthRepository.setAuthenticationStatus(
HelpFaceAuthenticationStatus(
msg = "Move left",
- msgId = FaceManager.FACE_ACQUIRED_TOO_RIGHT,
+ msgId = FACE_ACQUIRED_TOO_RIGHT,
)
)
@@ -318,7 +320,7 @@
faceAuthRepository.setAuthenticationStatus(
HelpFaceAuthenticationStatus(
msg = "Move left",
- msgId = FaceManager.FACE_ACQUIRED_TOO_RIGHT,
+ msgId = FACE_ACQUIRED_TOO_RIGHT,
)
)
@@ -333,10 +335,7 @@
// WHEN authentication status error is FACE_ERROR_HW_UNAVAILABLE
faceAuthRepository.setAuthenticationStatus(
- ErrorFaceAuthenticationStatus(
- msgId = FaceManager.FACE_ERROR_HW_UNAVAILABLE,
- msg = "test"
- )
+ ErrorFaceAuthenticationStatus(msgId = FACE_ERROR_HW_UNAVAILABLE, msg = "test")
)
// THEN faceErrorMessage isn't updated - it's still null since it was suppressed
@@ -350,10 +349,7 @@
// WHEN authentication status error is FACE_ERROR_HW_UNAVAILABLE
faceAuthRepository.setAuthenticationStatus(
- ErrorFaceAuthenticationStatus(
- msgId = FaceManager.FACE_ERROR_HW_UNAVAILABLE,
- msg = "test"
- )
+ ErrorFaceAuthenticationStatus(msgId = FACE_ERROR_HW_UNAVAILABLE, msg = "test")
)
// GIVEN face is allowed
@@ -370,7 +366,7 @@
// WHEN authentication status error is FACE_ERROR_TIMEOUT
faceAuthRepository.setAuthenticationStatus(
- ErrorFaceAuthenticationStatus(msgId = FaceManager.FACE_ERROR_TIMEOUT, msg = "test")
+ ErrorFaceAuthenticationStatus(msgId = FACE_ERROR_TIMEOUT, msg = "test")
)
// GIVEN face is allowed
@@ -389,7 +385,7 @@
// WHEN authentication status error is FACE_ERROR_TIMEOUT
faceAuthRepository.setAuthenticationStatus(
- ErrorFaceAuthenticationStatus(msgId = FaceManager.FACE_ERROR_TIMEOUT, msg = "test")
+ ErrorFaceAuthenticationStatus(msgId = FACE_ERROR_TIMEOUT, msg = "test")
)
// GIVEN face is allowed
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
index b3cfcf2..857af66 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
@@ -27,6 +27,7 @@
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.media.controls.MediaTestUtils
import com.android.systemui.media.controls.data.repository.MediaFilterRepository
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_RESUME
import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.shared.model.MediaData
@@ -38,6 +39,7 @@
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
@@ -77,6 +79,7 @@
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class MediaDataFilterImplTest : SysuiTestCase() {
+ val kosmos = testKosmos()
@Mock private lateinit var listener: MediaDataProcessor.Listener
@Mock private lateinit var userTracker: UserTracker
@@ -91,12 +94,12 @@
@Mock private lateinit var cardAction: SmartspaceAction
private lateinit var mediaDataFilter: MediaDataFilterImpl
- private lateinit var repository: MediaFilterRepository
private lateinit var testScope: TestScope
private lateinit var dataMain: MediaData
private lateinit var dataGuest: MediaData
private lateinit var dataPrivateProfile: MediaData
private val clock = FakeSystemClock()
+ private val repository: MediaFilterRepository = kosmos.mediaFilterRepository
@Before
fun setup() {
@@ -104,7 +107,6 @@
MediaPlayerData.clear()
whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false)
testScope = TestScope()
- repository = MediaFilterRepository(FakeSystemClock())
mediaDataFilter =
MediaDataFilterImpl(
context,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
index ffb50c1..1de7ee3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
@@ -54,6 +54,7 @@
import com.android.systemui.dump.DumpManager
import com.android.systemui.media.controls.data.repository.MediaDataRepository
import com.android.systemui.media.controls.data.repository.MediaFilterRepository
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.media.controls.domain.resume.MediaResumeListener
import com.android.systemui.media.controls.domain.resume.ResumeMediaBrowser
@@ -68,6 +69,7 @@
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
import com.android.systemui.statusbar.SbnBuilder
+import com.android.systemui.testKosmos
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
@@ -125,6 +127,7 @@
@RunWithLooper(setAsMainLooper = true)
@RunWith(AndroidTestingRunner::class)
class MediaDataProcessorTest : SysuiTestCase() {
+ val kosmos = testKosmos()
@JvmField @Rule val mockito = MockitoJUnit.rule()
@Mock lateinit var mediaControllerFactory: MediaControllerFactory
@@ -168,7 +171,6 @@
@Mock private lateinit var ugm: IUriGrantsManager
@Mock private lateinit var imageSource: ImageDecoder.Source
private lateinit var mediaDataRepository: MediaDataRepository
- private lateinit var mediaFilterRepository: MediaFilterRepository
private lateinit var testScope: TestScope
private lateinit var testDispatcher: TestDispatcher
private lateinit var testableLooper: TestableLooper
@@ -183,6 +185,7 @@
Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION,
1
)
+ private val mediaFilterRepository: MediaFilterRepository = kosmos.mediaFilterRepository
private lateinit var staticMockSession: MockitoSession
@@ -210,7 +213,6 @@
)
testDispatcher = UnconfinedTestDispatcher()
testScope = TestScope(testDispatcher)
- mediaFilterRepository = MediaFilterRepository(clock)
mediaDataRepository = MediaDataRepository(mediaFlags, dumpManager)
mediaDataProcessor =
MediaDataProcessor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
index c3daf84..0a5aace 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
@@ -36,6 +36,7 @@
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.MediaTestUtils
import com.android.systemui.media.controls.domain.pipeline.EMPTY_SMARTSPACE_MEDIA_DATA
@@ -44,6 +45,7 @@
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.controls.ui.view.MediaScrollView
+import com.android.systemui.media.controls.ui.viewmodel.mediaCarouselViewModel
import com.android.systemui.media.controls.util.MediaFlags
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.plugins.ActivityStarter
@@ -100,6 +102,7 @@
val kosmos = testKosmos()
@Mock lateinit var mediaControlPanelFactory: Provider<MediaControlPanel>
+ @Mock lateinit var mediaViewControllerFactory: Provider<MediaViewController>
@Mock lateinit var panel: MediaControlPanel
@Mock lateinit var visualStabilityProvider: VisualStabilityProvider
@Mock lateinit var mediaHostStatesManager: MediaHostStatesManager
@@ -148,6 +151,7 @@
mediaHostStatesManager,
activityStarter,
clock,
+ kosmos.testDispatcher,
executor,
bgExecutor,
testDispatcher,
@@ -162,6 +166,8 @@
kosmos.keyguardTransitionInteractor,
globalSettings,
secureSettings,
+ kosmos.mediaCarouselViewModel,
+ mediaViewControllerFactory,
)
verify(configurationController).addCallback(capture(configListener))
verify(mediaDataManager).addListener(capture(listener))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
index cb4ab64..e1c2d3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
@@ -29,12 +29,7 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.Classifier
-import com.android.systemui.kosmos.applicationCoroutineScope
-import com.android.systemui.kosmos.testDispatcher
-import com.android.systemui.media.controls.util.MediaFlags
-import com.android.systemui.media.controls.util.mediaFlags
import com.android.systemui.plugins.FalsingManager
-import com.android.systemui.testKosmos
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.concurrency.FakeRepeatableExecutor
import com.android.systemui.util.time.FakeSystemClock
@@ -61,7 +56,6 @@
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class SeekBarViewModelTest : SysuiTestCase() {
- val kosmos = testKosmos()
private lateinit var viewModel: SeekBarViewModel
private lateinit var fakeExecutor: FakeExecutor
@@ -81,7 +75,6 @@
@Mock private lateinit var mockTransport: MediaController.TransportControls
@Mock private lateinit var falsingManager: FalsingManager
@Mock private lateinit var mockBar: SeekBar
- @Mock private lateinit var mediaFlags: MediaFlags
private val token1 = MediaSession.Token(1, null)
private val token2 = MediaSession.Token(2, null)
@@ -90,18 +83,10 @@
@Before
fun setUp() {
fakeExecutor = FakeExecutor(FakeSystemClock())
- viewModel =
- SeekBarViewModel(
- kosmos.applicationCoroutineScope,
- kosmos.testDispatcher,
- FakeRepeatableExecutor(fakeExecutor),
- falsingManager,
- mediaFlags,
- )
+ viewModel = SeekBarViewModel(FakeRepeatableExecutor(fakeExecutor), falsingManager)
viewModel.logSeek = {}
whenever(mockController.sessionToken).thenReturn(token1)
whenever(mockBar.context).thenReturn(context)
- whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(false)
// LiveData to run synchronously
ArchTaskExecutor.getInstance().setDelegate(taskExecutor)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index 9d14116..3695d8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -35,6 +35,7 @@
import android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX
import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
import android.telephony.TelephonyCallback
+import android.telephony.TelephonyCallback.CarrierRoamingNtnModeListener
import android.telephony.TelephonyCallback.DataActivityListener
import android.telephony.TelephonyCallback.DisplayInfoListener
import android.telephony.TelephonyCallback.ServiceStateListener
@@ -983,26 +984,19 @@
@Test
@EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
- fun isNonTerrestrial_updatesFromServiceState() =
+ fun isNonTerrestrial_updatesFromCallback0() =
testScope.runTest {
val latest by collectLastValue(underTest.isNonTerrestrial)
- // Lambda makes it a little clearer what we are testing IMO
- val serviceStateCreator = { ntn: Boolean ->
- mock<ServiceState>().also {
- whenever(it.isUsingNonTerrestrialNetwork).thenReturn(ntn)
- }
- }
-
// Starts out false
assertThat(latest).isFalse()
- getTelephonyCallbackForType<ServiceStateListener>()
- .onServiceStateChanged(serviceStateCreator(true))
+ val callback = getTelephonyCallbackForType<CarrierRoamingNtnModeListener>()
+
+ callback.onCarrierRoamingNtnModeChanged(true)
assertThat(latest).isTrue()
- getTelephonyCallbackForType<ServiceStateListener>()
- .onServiceStateChanged(serviceStateCreator(false))
+ callback.onCarrierRoamingNtnModeChanged(false)
assertThat(latest).isFalse()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectTest.kt
deleted file mode 100644
index b1df159..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectTest.kt
+++ /dev/null
@@ -1,91 +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.surfaceeffects.revealeffect
-
-import android.graphics.RenderEffect
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper
-import androidx.test.filters.SmallTest
-import com.android.systemui.animation.AnimatorTestRule
-import com.android.systemui.model.SysUiStateTest
-import com.android.systemui.surfaceeffects.RenderEffectDrawCallback
-import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-class RippleRevealEffectTest : SysUiStateTest() {
-
- @get:Rule val animatorTestRule = AnimatorTestRule(this)
-
- @Test
- fun play_triggersDrawCallback() {
- var effectFromCallback: RenderEffect? = null
- val revealEffectConfig = RippleRevealEffectConfig(duration = 1000f)
- val drawCallback =
- object : RenderEffectDrawCallback {
- override fun onDraw(renderEffect: RenderEffect) {
- effectFromCallback = renderEffect
- }
- }
- val revealEffect = RippleRevealEffect(revealEffectConfig, drawCallback)
- assertThat(effectFromCallback).isNull()
-
- revealEffect.play()
-
- animatorTestRule.advanceTimeBy(500L)
-
- assertThat(effectFromCallback).isNotNull()
- }
-
- @Test
- fun play_triggersStateChangedCallback() {
- val revealEffectConfig = RippleRevealEffectConfig(duration = 1000f)
- val drawCallback =
- object : RenderEffectDrawCallback {
- override fun onDraw(renderEffect: RenderEffect) {}
- }
- var animationStartedCalled = false
- var animationEndedCalled = false
- val stateChangedCallback =
- object : RippleRevealEffect.AnimationStateChangedCallback {
- override fun onAnimationStart() {
- animationStartedCalled = true
- }
-
- override fun onAnimationEnd() {
- animationEndedCalled = true
- }
- }
- val revealEffect =
- RippleRevealEffect(revealEffectConfig, drawCallback, stateChangedCallback)
-
- assertThat(animationStartedCalled).isFalse()
- assertThat(animationEndedCalled).isFalse()
-
- revealEffect.play()
-
- assertThat(animationStartedCalled).isTrue()
-
- animatorTestRule.advanceTimeBy(revealEffectConfig.duration.toLong())
-
- assertThat(animationEndedCalled).isTrue()
- }
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
index 7dab5c2..690bde7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
@@ -16,7 +16,16 @@
package com.android.systemui.media.controls.data.repository
+import android.content.applicationContext
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.policy.configurationController
import com.android.systemui.util.time.systemClock
-val Kosmos.mediaFilterRepository by Kosmos.Fixture { MediaFilterRepository(systemClock) }
+val Kosmos.mediaFilterRepository by
+ Kosmos.Fixture {
+ MediaFilterRepository(
+ applicationContext = applicationContext,
+ systemClock = systemClock,
+ configurationController = configurationController
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
index 6eae28f..069995a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
@@ -17,6 +17,7 @@
package com.android.systemui.media.controls.ui.viewmodel
import android.content.applicationContext
+import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
@@ -32,6 +33,7 @@
applicationScope = applicationCoroutineScope,
applicationContext = applicationContext,
backgroundDispatcher = testDispatcher,
+ backgroundExecutor = fakeExecutor,
visualStabilityProvider = visualStabilityProvider,
interactor = mediaCarouselInteractor,
controlInteractorFactory = mediaControlInteractorFactory,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt
index b3fb15f..2f3d3c3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt
@@ -17,8 +17,8 @@
package com.android.systemui.media.controls.ui.viewmodel
import android.content.applicationContext
+import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaControlInteractor
import com.android.systemui.media.controls.util.mediaUiEventLogger
@@ -26,9 +26,9 @@
val Kosmos.mediaControlViewModel by
Kosmos.Fixture {
MediaControlViewModel(
- applicationScope = applicationCoroutineScope,
applicationContext = applicationContext,
backgroundDispatcher = testDispatcher,
+ backgroundExecutor = fakeExecutor,
interactor = mediaControlInteractor,
logger = mediaUiEventLogger,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
index d17dd6c..0101961 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
@@ -23,7 +23,6 @@
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.FakeShadeRepository
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import org.junit.Assert
@@ -33,12 +32,14 @@
/** Sets shade expansion to a value between 0-1. */
fun setShadeExpansion(shadeExpansion: Float) {
- setShadeAndQsExpansion(shadeExpansion, 0f)
+ delegate.assertFlagValid()
+ delegate.setShadeExpansion(shadeExpansion)
}
/** Sets QS expansion to a value between 0-1. */
fun setQsExpansion(qsExpansion: Float) {
- setShadeAndQsExpansion(0f, qsExpansion)
+ delegate.assertFlagValid()
+ delegate.setQsExpansion(qsExpansion)
}
/** Sets both shade and QS expansion. One value must be zero or values must add up to 1f. */
@@ -48,7 +49,7 @@
shadeExpansion == 0f || qsExpansion == 0f || shadeExpansion + qsExpansion == 1f,
)
delegate.assertFlagValid()
- delegate.setShadeAndQsExpansionInternal(shadeExpansion, qsExpansion)
+ delegate.setShadeAndQsExpansion(shadeExpansion, qsExpansion)
}
/** Sets the shade expansion on the lockscreen to the given amount from 0-1. */
@@ -56,6 +57,12 @@
delegate.assertFlagValid()
delegate.setLockscreenShadeExpansion(lockscreenShadeExpansion)
}
+
+ /** Sets whether the user is moving the shade with touch input. */
+ fun setLockscreenShadeTracking(lockscreenShadeTracking: Boolean) {
+ delegate.assertFlagValid()
+ delegate.setLockscreenShadeTracking(lockscreenShadeTracking)
+ }
}
/** Sets up shade state for tests for a specific value of the scene container flag. */
@@ -64,16 +71,25 @@
fun assertFlagValid()
/** Sets both shade and QS expansion. One value must be zero or values must add up to 1f. */
- fun setShadeAndQsExpansionInternal(shadeExpansion: Float, qsExpansion: Float)
+ fun setShadeAndQsExpansion(shadeExpansion: Float, qsExpansion: Float)
/** Sets the shade expansion on the lockscreen to the given amount from 0-1. */
fun setLockscreenShadeExpansion(lockscreenShadeExpansion: Float)
+
+ /** Sets whether the user is moving the shade with touch input. */
+ fun setLockscreenShadeTracking(lockscreenShadeTracking: Boolean)
+
+ /** Sets shade expansion to a value between 0-1. */
+ fun setShadeExpansion(shadeExpansion: Float)
+
+ /** Sets QS expansion to a value between 0-1. */
+ fun setQsExpansion(qsExpansion: Float)
}
/** Sets up shade state for tests when the scene container flag is disabled. */
class ShadeTestUtilLegacyImpl(val testScope: TestScope, val shadeRepository: FakeShadeRepository) :
ShadeTestUtilDelegate {
- override fun setShadeAndQsExpansionInternal(shadeExpansion: Float, qsExpansion: Float) {
+ override fun setShadeAndQsExpansion(shadeExpansion: Float, qsExpansion: Float) {
shadeRepository.setLegacyShadeExpansion(shadeExpansion)
shadeRepository.setQsExpansion(qsExpansion)
testScope.runCurrent()
@@ -83,24 +99,56 @@
shadeRepository.setLockscreenShadeExpansion(lockscreenShadeExpansion)
}
+ override fun setLockscreenShadeTracking(lockscreenShadeTracking: Boolean) {
+ shadeRepository.setLegacyLockscreenShadeTracking(lockscreenShadeTracking)
+ }
+
override fun assertFlagValid() {
Assert.assertFalse(SceneContainerFlag.isEnabled)
}
+
+ /** Sets shade expansion to a value between 0-1. */
+ override fun setShadeExpansion(shadeExpansion: Float) {
+ shadeRepository.setLegacyShadeExpansion(shadeExpansion)
+ testScope.runCurrent()
+ }
+
+ /** Sets QS expansion to a value between 0-1. */
+ override fun setQsExpansion(qsExpansion: Float) {
+ shadeRepository.setQsExpansion(qsExpansion)
+ testScope.runCurrent()
+ }
}
/** Sets up shade state for tests when the scene container flag is enabled. */
class ShadeTestUtilSceneImpl(val testScope: TestScope, val sceneInteractor: SceneInteractor) :
ShadeTestUtilDelegate {
- override fun setShadeAndQsExpansionInternal(shadeExpansion: Float, qsExpansion: Float) {
+ val isUserInputOngoing = MutableStateFlow(true)
+
+ override fun setShadeAndQsExpansion(shadeExpansion: Float, qsExpansion: Float) {
if (shadeExpansion == 0f) {
setTransitionProgress(Scenes.Lockscreen, Scenes.QuickSettings, qsExpansion)
} else if (qsExpansion == 0f) {
setTransitionProgress(Scenes.Lockscreen, Scenes.Shade, shadeExpansion)
+ } else if (shadeExpansion == 1f) {
+ setIdleScene(Scenes.Shade)
+ } else if (qsExpansion == 1f) {
+ setIdleScene(Scenes.QuickSettings)
} else {
setTransitionProgress(Scenes.Shade, Scenes.QuickSettings, qsExpansion)
}
}
+ /** Sets shade expansion to a value between 0-1. */
+ override fun setShadeExpansion(shadeExpansion: Float) {
+ setShadeAndQsExpansion(shadeExpansion, 0f)
+ }
+
+ /** Sets QS expansion to a value between 0-1. */
+ override fun setQsExpansion(qsExpansion: Float) {
+ setShadeAndQsExpansion(0f, qsExpansion)
+ }
+
override fun setLockscreenShadeExpansion(lockscreenShadeExpansion: Float) {
if (lockscreenShadeExpansion == 0f) {
setIdleScene(Scenes.Lockscreen)
@@ -111,6 +159,10 @@
}
}
+ override fun setLockscreenShadeTracking(lockscreenShadeTracking: Boolean) {
+ isUserInputOngoing.value = lockscreenShadeTracking
+ }
+
private fun setIdleScene(scene: SceneKey) {
sceneInteractor.changeScene(scene, "test")
val transitionState =
@@ -127,8 +179,8 @@
fromScene = from,
toScene = to,
progress = MutableStateFlow(progress),
- isInitiatedByUserInput = false,
- isUserInputOngoing = flowOf(false),
+ isInitiatedByUserInput = true,
+ isUserInputOngoing = isUserInputOngoing,
)
)
sceneInteractor.setTransitionState(transitionState)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt
index 348a02e..4a79452 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/VolumePanelKosmos.kt
@@ -69,6 +69,7 @@
Kosmos.Fixture {
VolumePanelViewModel(
mainResources,
+ testScope.backgroundScope,
KosmosVolumePanelComponentFactory(this),
fakeConfigurationController,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt
index e5f5d4e..1e895b5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/dagger/factory/KosmosVolumePanelComponentFactory.kt
@@ -32,7 +32,10 @@
class KosmosVolumePanelComponentFactory(private val kosmos: Kosmos) : VolumePanelComponentFactory {
- override fun create(viewModel: VolumePanelViewModel): VolumePanelComponent =
+ override fun create(
+ viewModel: VolumePanelViewModel,
+ scope: CoroutineScope
+ ): VolumePanelComponent =
object : VolumePanelComponent {
override fun coroutineScope(): CoroutineScope = kosmos.testScope.backgroundScope
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 6f20adf..a619257 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -1396,7 +1396,14 @@
int innerDepth = parser.getDepth();
try {
if (Flags.recoverabilityDetection()) {
- observerMitigationCount = parser.getAttributeInt(null, ATTR_MITIGATION_COUNT);
+ try {
+ observerMitigationCount =
+ parser.getAttributeInt(null, ATTR_MITIGATION_COUNT);
+ } catch (XmlPullParserException e) {
+ Slog.i(
+ TAG,
+ "ObserverInternal mitigation count was not present.");
+ }
}
while (XmlUtils.nextElementWithin(parser, innerDepth)) {
if (TAG_PACKAGE.equals(parser.getName())) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 96228b2..23891d2 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3856,7 +3856,7 @@
void onFgsTimeout(ServiceRecord sr) {
synchronized (mAm) {
final int fgsType = getTimeLimitedFgsType(sr.foregroundServiceType);
- if (fgsType == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE) {
+ if (fgsType == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE || sr.app == null) {
mFGSAnrTimer.discard(sr);
return;
}
@@ -7600,8 +7600,14 @@
super(Objects.requireNonNull(am).mHandler, msg, label);
}
- void start(@NonNull ProcessRecord proc, long millis) {
- start(proc, proc.getPid(), proc.uid, millis);
+ @Override
+ public int getPid(@NonNull ProcessRecord proc) {
+ return proc.getPid();
+ }
+
+ @Override
+ public int getUid(@NonNull ProcessRecord proc) {
+ return proc.uid;
}
}
@@ -7611,11 +7617,14 @@
super(Objects.requireNonNull(am).mHandler, msg, label);
}
- void start(@NonNull ServiceRecord service, long millis) {
- start(service,
- (service.app != null) ? service.app.getPid() : 0,
- service.appInfo.uid,
- millis);
+ @Override
+ public int getPid(@NonNull ServiceRecord service) {
+ return (service.app != null) ? service.app.getPid() : 0;
+ }
+
+ @Override
+ public int getUid(@NonNull ServiceRecord service) {
+ return (service.appInfo != null) ? service.appInfo.uid : 0;
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 49f2c8b..c47e42d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3541,13 +3541,23 @@
mAppProfiler.setAllowLowerMemLevelLocked(false);
doLowMem = false;
}
+ if (doOomAdj) {
+ if (Flags.migrateFullOomadjUpdates()) {
+ app.forEachConnectionHost((host) -> enqueueOomAdjTargetLocked(host));
+ }
+ }
+
EventLogTags.writeAmProcDied(app.userId, pid, app.processName, setAdj, setProcState);
if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
"Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
handleAppDiedLocked(app, pid, false, true, fromBinderDied);
if (doOomAdj) {
- updateOomAdjLocked(OOM_ADJ_REASON_PROCESS_END);
+ if (Flags.migrateFullOomadjUpdates()) {
+ updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_PROCESS_END);
+ } else {
+ updateOomAdjLocked(OOM_ADJ_REASON_PROCESS_END);
+ }
}
if (doLowMem) {
mAppProfiler.doLowMemReportIfNeededLocked(app);
@@ -17723,11 +17733,6 @@
}
@GuardedBy({"this", "mProcLock"})
- final void setAppIdTempAllowlistStateLSP(int uid, boolean onAllowlist) {
- mOomAdjuster.setAppIdTempAllowlistStateLSP(uid, onAllowlist);
- }
-
- @GuardedBy({"this", "mProcLock"})
final void setUidTempAllowlistStateLSP(int uid, boolean onAllowlist) {
mOomAdjuster.setUidTempAllowlistStateLSP(uid, onAllowlist);
}
@@ -18689,7 +18694,7 @@
} else {
mFgsStartTempAllowList.removeUid(changingUid);
}
- setAppIdTempAllowlistStateLSP(changingUid, adding);
+ setUidTempAllowlistStateLSP(changingUid, adding);
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index bf4f34f..5af9424 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -117,6 +117,7 @@
import android.util.DisplayMetrics;
import android.util.TeeWriter;
import android.util.proto.ProtoOutputStream;
+import android.view.Choreographer;
import android.view.Display;
import android.window.SplashScreen;
@@ -241,6 +242,23 @@
case "start":
case "start-activity":
return runStartActivity(pw);
+ case "start-in-vsync":
+ final ProgressWaiter waiter = new ProgressWaiter(0);
+ final int[] startResult = new int[1];
+ startResult[0] = -1;
+ mInternal.mUiHandler.runWithScissors(
+ () -> Choreographer.getInstance().postFrameCallback(frameTimeNanos -> {
+ try {
+ startResult[0] = runStartActivity(pw);
+ waiter.onFinished(0, null /* extras */);
+ } catch (Exception ex) {
+ getErrPrintWriter().println(
+ "Error: unable to start activity, " + ex);
+ }
+ }),
+ USER_OPERATION_TIMEOUT_MS / 2);
+ waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS);
+ return startResult[0];
case "startservice":
case "start-service":
return runStartService(pw, false);
@@ -281,6 +299,8 @@
return runClearWatchHeap(pw);
case "clear-start-info":
return runClearStartInfo(pw);
+ case "start-info-detailed-monitoring":
+ return runStartInfoDetailedMonitoring(pw);
case "clear-exit-info":
return runClearExitInfo(pw);
case "bug-report":
@@ -1395,12 +1415,12 @@
"runClearStartInfo()");
String opt;
int userId = UserHandle.USER_CURRENT;
- String packageName = null;
while ((opt = getNextOption()) != null) {
if (opt.equals("--user")) {
userId = UserHandle.parseUserArg(getNextArgRequired());
} else {
- packageName = opt;
+ getErrPrintWriter().println("Error: Unknown option: " + opt);
+ return -1;
}
}
if (userId == UserHandle.USER_CURRENT) {
@@ -1411,21 +1431,19 @@
userId = user.id;
}
mInternal.mProcessList.getAppStartInfoTracker()
- .clearHistoryProcessStartInfo(packageName, userId);
+ .clearHistoryProcessStartInfo(getNextArg(), userId);
return 0;
}
- int runClearExitInfo(PrintWriter pw) throws RemoteException {
- mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
- "runClearExitInfo()");
+ int runStartInfoDetailedMonitoring(PrintWriter pw) throws RemoteException {
String opt;
int userId = UserHandle.USER_CURRENT;
- String packageName = null;
while ((opt = getNextOption()) != null) {
if (opt.equals("--user")) {
userId = UserHandle.parseUserArg(getNextArgRequired());
} else {
- packageName = opt;
+ getErrPrintWriter().println("Error: Unknown option: " + opt);
+ return -1;
}
}
if (userId == UserHandle.USER_CURRENT) {
@@ -1435,7 +1453,33 @@
}
userId = user.id;
}
- mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(packageName, userId);
+ mInternal.mProcessList.getAppStartInfoTracker()
+ .configureDetailedMonitoring(pw, getNextArg(), userId);
+ return 0;
+ }
+
+ int runClearExitInfo(PrintWriter pw) throws RemoteException {
+ mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
+ "runClearExitInfo()");
+ String opt;
+ int userId = UserHandle.USER_CURRENT;
+ while ((opt = getNextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ } else {
+ getErrPrintWriter().println("Error: Unknown option: " + opt);
+ return -1;
+ }
+ }
+ if (userId == UserHandle.USER_CURRENT) {
+ UserInfo user = mInterface.getCurrentUser();
+ if (user == null) {
+ return -1;
+ }
+ userId = user.id;
+ }
+ mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(getNextArg(),
+ userId);
return 0;
}
@@ -4236,6 +4280,9 @@
pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as.");
pw.println(" --display <DISPLAY_ID>: The display to launch the activity into.");
pw.println(" --splashscreen-icon: Show the splash screen icon on launch.");
+ pw.println(" start-in-vsync");
+ pw.println(" Start an Activity with vsync aligned. See `start-activity` for the");
+ pw.println(" possible options.");
pw.println(" start-service [--user <USER_ID> | current] <INTENT>");
pw.println(" Start a Service. Options are:");
pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
@@ -4356,10 +4403,15 @@
pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
pw.println(" clear-watch-heap");
pw.println(" Clear the previously set-watch-heap.");
- pw.println(" clear-start-info [--user <USER_ID> | all | current] [package]");
- pw.println(" Clear the process start-info for given package");
- pw.println(" clear-exit-info [--user <USER_ID> | all | current] [package]");
- pw.println(" Clear the process exit-info for given package");
+ pw.println(" clear-start-info [--user <USER_ID> | all | current] <PACKAGE>");
+ pw.println(" Clear process start-info for the given package.");
+ pw.println(" Clear start-info for all packages if no package is provided.");
+ pw.println(" start-info-detailed-monitoring [--user <USER_ID> | all | current] <PACKAGE>");
+ pw.println(" Enable application start info detailed monitoring for the given package.");
+ pw.println(" Disable if no package is supplied.");
+ pw.println(" clear-exit-info [--user <USER_ID> | all | current] <PACKAGE>");
+ pw.println(" Clear process exit-info for the given package.");
+ pw.println(" Clear exit-info for all packages if no package is provided.");
pw.println(" bug-report [--progress | --telephony]");
pw.println(" Request bug report generation; will launch a notification");
pw.println(" when done to select where it should be delivered. Options are:");
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index 2be1fe2..376f654 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -65,6 +65,7 @@
import java.util.Collections;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -82,8 +83,12 @@
private static final int FOREACH_ACTION_REMOVE_ITEM = 1;
private static final int FOREACH_ACTION_STOP_ITERATION = 2;
+ private static final String MONITORING_MODE_EMPTY_TEXT = "No records";
+
@VisibleForTesting static final int APP_START_INFO_HISTORY_LIST_SIZE = 16;
+ private static final int APP_START_INFO_MONITORING_MODE_LIST_SIZE = 100;
+
@VisibleForTesting static final String APP_START_STORE_DIR = "procstartstore";
@VisibleForTesting static final String APP_START_INFO_FILE = "procstartinfo";
@@ -426,6 +431,40 @@
ApplicationStartInfo.START_TIMESTAMP_APPLICATION_ONCREATE);
}
+ /**
+ * Helper functions for monitoring shell command.
+ * > adb shell am start-info-detailed-monitoring [package-name]
+ */
+ void configureDetailedMonitoring(PrintWriter pw, String packageName, int userId) {
+ synchronized (mLock) {
+ if (!mEnabled) {
+ return;
+ }
+
+ forEachPackageLocked((name, records) -> {
+ for (int i = 0; i < records.size(); i++) {
+ records.valueAt(i).disableAppMonitoringMode();
+ }
+ return AppStartInfoTracker.FOREACH_ACTION_NONE;
+ });
+
+ if (TextUtils.isEmpty(packageName)) {
+ pw.println("ActivityManager AppStartInfo detailed monitoring disabled");
+ } else {
+ SparseArray<AppStartInfoContainer> array = mData.getMap().get(packageName);
+ if (array != null) {
+ for (int i = 0; i < array.size(); i++) {
+ array.valueAt(i).enableAppMonitoringModeForUser(userId);
+ }
+ pw.println("ActivityManager AppStartInfo detailed monitoring enabled for "
+ + packageName);
+ } else {
+ pw.println("Package " + packageName + " not found");
+ }
+ }
+ }
+ }
+
/** Report a bind application timestamp to add to {@link ApplicationStartInfo}. */
public void reportBindApplicationTimeNanos(ProcessRecord app, long timeNs) {
addTimestampToStart(app, timeNs,
@@ -1011,15 +1050,46 @@
/** A container class of (@link android.app.ApplicationStartInfo) */
final class AppStartInfoContainer {
- private List<ApplicationStartInfo> mInfos; // Always kept sorted by first timestamp.
+ private ArrayList<ApplicationStartInfo> mInfos; // Always kept sorted by first timestamp.
private int mMaxCapacity;
private int mUid;
+ private boolean mMonitoringModeEnabled = false;
AppStartInfoContainer(final int maxCapacity) {
mInfos = new ArrayList<ApplicationStartInfo>();
mMaxCapacity = maxCapacity;
}
+ int getMaxCapacity() {
+ return mMonitoringModeEnabled ? APP_START_INFO_MONITORING_MODE_LIST_SIZE : mMaxCapacity;
+ }
+
+ @GuardedBy("mLock")
+ void enableAppMonitoringModeForUser(int userId) {
+ if (UserHandle.getUserId(mUid) == userId) {
+ mMonitoringModeEnabled = true;
+ }
+ }
+
+ @GuardedBy("mLock")
+ void disableAppMonitoringMode() {
+ mMonitoringModeEnabled = false;
+
+ // Capacity is reduced by turning off monitoring mode. Check if array size is within
+ // new lower limits and trim extraneous records if it is not.
+ if (mInfos.size() <= getMaxCapacity()) {
+ return;
+ }
+
+ // Sort records so we can remove the least recent ones.
+ Collections.sort(mInfos, (a, b) ->
+ Long.compare(getStartTimestamp(b), getStartTimestamp(a)));
+
+ // Remove records and trim list object back to size.
+ mInfos.subList(0, mInfos.size() - getMaxCapacity()).clear();
+ mInfos.trimToSize();
+ }
+
@GuardedBy("mLock")
void getStartInfoLocked(
final int filterPid, final int maxNum, ArrayList<ApplicationStartInfo> results) {
@@ -1029,7 +1099,7 @@
@GuardedBy("mLock")
void addStartInfoLocked(ApplicationStartInfo info) {
int size = mInfos.size();
- if (size >= mMaxCapacity) {
+ if (size >= getMaxCapacity()) {
// Remove oldest record if size is over max capacity.
int oldestIndex = -1;
long oldestTimeStamp = Long.MAX_VALUE;
@@ -1061,12 +1131,59 @@
@GuardedBy("mLock")
void dumpLocked(PrintWriter pw, String prefix, SimpleDateFormat sdf) {
+ if (mMonitoringModeEnabled) {
+ // For monitoring mode, calculate the average start time for each start state to
+ // add to output.
+ List<Long> coldStartTimes = new ArrayList<>();
+ List<Long> warmStartTimes = new ArrayList<>();
+ List<Long> hotStartTimes = new ArrayList<>();
+
+ for (int i = 0; i < mInfos.size(); i++) {
+ ApplicationStartInfo startInfo = mInfos.get(i);
+ Map<Integer, Long> timestamps = startInfo.getStartupTimestamps();
+
+ // Confirm required timestamps exist.
+ if (timestamps.containsKey(ApplicationStartInfo.START_TIMESTAMP_LAUNCH)
+ && timestamps.containsKey(
+ ApplicationStartInfo.START_TIMESTAMP_FIRST_FRAME)) {
+ // Add timestamp to correct collection.
+ long time = timestamps.get(ApplicationStartInfo.START_TIMESTAMP_FIRST_FRAME)
+ - timestamps.get(ApplicationStartInfo.START_TIMESTAMP_LAUNCH);
+ switch (startInfo.getStartType()) {
+ case ApplicationStartInfo.START_TYPE_COLD:
+ coldStartTimes.add(time);
+ break;
+ case ApplicationStartInfo.START_TYPE_WARM:
+ warmStartTimes.add(time);
+ break;
+ case ApplicationStartInfo.START_TYPE_HOT:
+ hotStartTimes.add(time);
+ break;
+ }
+ }
+ }
+
+ pw.println(prefix + " Average Start Time in ns for Cold Starts: "
+ + (coldStartTimes.isEmpty() ? MONITORING_MODE_EMPTY_TEXT
+ : calculateAverage(coldStartTimes)));
+ pw.println(prefix + " Average Start Time in ns for Warm Starts: "
+ + (warmStartTimes.isEmpty() ? MONITORING_MODE_EMPTY_TEXT
+ : calculateAverage(warmStartTimes)));
+ pw.println(prefix + " Average Start Time in ns for Hot Starts: "
+ + (hotStartTimes.isEmpty() ? MONITORING_MODE_EMPTY_TEXT
+ : calculateAverage(hotStartTimes)));
+ }
+
int size = mInfos.size();
for (int i = 0; i < size; i++) {
mInfos.get(i).dump(pw, prefix + " ", "#" + i, sdf);
}
}
+ private long calculateAverage(List<Long> vals) {
+ return (long) vals.stream().mapToDouble(a -> a).average().orElse(0.0);
+ }
+
@GuardedBy("mLock")
void writeToProto(ProtoOutputStream proto, long fieldId) throws IOException {
long token = proto.start(fieldId);
@@ -1076,6 +1193,7 @@
mInfos.get(i)
.writeToProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO);
}
+ proto.write(AppsStartInfoProto.Package.User.MONITORING_ENABLED, mMonitoringModeEnabled);
proto.end(token);
}
@@ -1094,6 +1212,10 @@
info.readFromProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO);
mInfos.add(info);
break;
+ case (int) AppsStartInfoProto.Package.User.MONITORING_ENABLED:
+ mMonitoringModeEnabled = proto.readBoolean(
+ AppsStartInfoProto.Package.User.MONITORING_ENABLED);
+ break;
}
}
proto.end(token);
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index 48dd039..4425a38 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -1339,8 +1339,14 @@
MSG_DELIVERY_TIMEOUT, "BROADCAST_TIMEOUT", true);
}
- void start(@NonNull BroadcastProcessQueue queue, long timeoutMillis) {
- start(queue, queue.app.getPid(), queue.app.uid, timeoutMillis);
+ @Override
+ public int getPid(@NonNull BroadcastProcessQueue queue) {
+ return (queue.app != null) ? queue.app.getPid() : 0;
+ }
+
+ @Override
+ public int getUid(@NonNull BroadcastProcessQueue queue) {
+ return (queue.app != null) ? queue.app.uid : 0;
}
}
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 9b72db8..a289dd1 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -3696,27 +3696,18 @@
}
@GuardedBy({"mService", "mProcLock"})
- void setAppIdTempAllowlistStateLSP(int uid, boolean onAllowlist) {
- boolean changed = false;
- for (int i = mActiveUids.size() - 1; i >= 0; i--) {
- final UidRecord uidRec = mActiveUids.valueAt(i);
- if (uidRec.getUid() == uid && uidRec.isCurAllowListed() != onAllowlist) {
- uidRec.setCurAllowListed(onAllowlist);
- changed = true;
- }
- }
- if (changed) {
- updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
- }
- }
-
- @GuardedBy({"mService", "mProcLock"})
void setUidTempAllowlistStateLSP(int uid, boolean onAllowlist) {
- boolean changed = false;
final UidRecord uidRec = mActiveUids.get(uid);
if (uidRec != null && uidRec.isCurAllowListed() != onAllowlist) {
uidRec.setCurAllowListed(onAllowlist);
- updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
+ if (Flags.migrateFullOomadjUpdates()) {
+ for (int i = uidRec.getNumOfProcs() - 1; i >= 0; i--) {
+ enqueueOomAdjTargetLocked(uidRec.getProcessRecordByIndex(i));
+ }
+ updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_ALLOWLIST);
+ } else {
+ updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
+ }
}
}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 0816527..a74c489 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -71,6 +71,7 @@
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
+import java.util.function.Consumer;
/**
* Full information about a particular process that
@@ -1692,4 +1693,22 @@
&& !mOptRecord.shouldNotFreeze()
&& mState.getCurAdj() >= ProcessList.FREEZER_CUTOFF_ADJ;
}
+
+ public void forEachConnectionHost(Consumer<ProcessRecord> consumer) {
+ for (int i = mServices.numberOfConnections() - 1; i >= 0; i--) {
+ final ConnectionRecord cr = mServices.getConnectionAt(i);
+ final ProcessRecord service = cr.binding.service.app;
+ consumer.accept(service);
+ }
+ for (int i = mServices.numberOfSdkSandboxConnections() - 1; i >= 0; i--) {
+ final ConnectionRecord cr = mServices.getSdkSandboxConnectionAt(i);
+ final ProcessRecord service = cr.binding.service.app;
+ consumer.accept(service);
+ }
+ for (int i = mProviders.numberOfProviderConnections() - 1; i >= 0; i--) {
+ ContentProviderConnection cpc = mProviders.getProviderConnectionAt(i);
+ ProcessRecord provider = cpc.provider.proc;
+ consumer.accept(provider);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index 19be5f9..fb63ec6 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -106,3 +106,13 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "migrate_full_oomadj_updates"
+ namespace: "backstage_power"
+ description: "Migrate full updates to partial updates where possible"
+ bug: "324915545"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
index cd5d0c8..ff1e5d5 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
@@ -16,13 +16,14 @@
package com.android.server.biometrics.log;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_START;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.SensorManager;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricsProtoEnums;
-import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.util.Slog;
@@ -137,7 +138,7 @@
final boolean isFingerprint = mStatsModality == BiometricsProtoEnums.MODALITY_FINGERPRINT;
if (isFace || isFingerprint) {
if ((isFingerprint && acquiredInfo == FingerprintManager.FINGERPRINT_ACQUIRED_START)
- || (isFace && acquiredInfo == FaceManager.FACE_ACQUIRED_START)) {
+ || (isFace && acquiredInfo == FACE_ACQUIRED_START)) {
mFirstAcquireTimeMs = System.currentTimeMillis();
}
} else if (acquiredInfo == BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index 8d32235..ef7abdd 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -17,6 +17,9 @@
package com.android.server.biometrics.sensors.face.aidl;
import static android.adaptiveauth.Flags.reportBiometricAuthAttempts;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_SENSOR_DIRTY;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN;
import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_VENDOR;
import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_VENDOR_BASE;
import static android.hardware.face.FaceManager.getAuthHelpMessage;
@@ -43,7 +46,6 @@
import android.hardware.biometrics.face.IFace;
import android.hardware.face.FaceAuthenticateOptions;
import android.hardware.face.FaceAuthenticationFrame;
-import android.hardware.face.FaceManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
@@ -90,8 +92,8 @@
private final SensorPrivacyManager mSensorPrivacyManager;
@NonNull
private final AuthenticationStateListeners mAuthenticationStateListeners;
- @FaceManager.FaceAcquired
- private int mLastAcquire = FaceManager.FACE_ACQUIRED_UNKNOWN;
+ @BiometricFaceConstants.FaceAcquired
+ private int mLastAcquire = FACE_ACQUIRED_UNKNOWN;
public FaceAuthenticationClient(@NonNull Context context,
@NonNull Supplier<AidlSession> lazyDaemon,
@@ -232,9 +234,9 @@
public boolean wasUserDetected() {
// Do not provide haptic feedback if the user was not detected, and an error (usually
// ERROR_TIMEOUT) is received.
- return mLastAcquire != FaceManager.FACE_ACQUIRED_NOT_DETECTED
- && mLastAcquire != FaceManager.FACE_ACQUIRED_SENSOR_DIRTY
- && mLastAcquire != FaceManager.FACE_ACQUIRED_UNKNOWN;
+ return mLastAcquire != FACE_ACQUIRED_NOT_DETECTED
+ && mLastAcquire != FACE_ACQUIRED_SENSOR_DIRTY
+ && mLastAcquire != FACE_ACQUIRED_UNKNOWN;
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
index 6b99493..559462a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
@@ -16,6 +16,8 @@
package com.android.server.biometrics.sensors.face.aidl;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -28,7 +30,6 @@
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.ISession;
import android.hardware.biometrics.face.SensorProps;
-import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.os.Binder;
import android.os.Handler;
@@ -296,7 +297,7 @@
if (client != null && client.isInterruptable()) {
Slog.e(TAG, "Sending face hardware unavailable error for client: " + client);
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
- errorConsumer.onError(FaceManager.FACE_ERROR_HW_UNAVAILABLE,
+ errorConsumer.onError(FACE_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 50b1464..d3de71e 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -154,6 +154,11 @@
Flags::useFusionProxSensor
);
+ private final FlagState mPeakRefreshRatePhysicalLimit = new FlagState(
+ Flags.FLAG_ENABLE_PEAK_REFRESH_RATE_PHYSICAL_LIMIT,
+ Flags::enablePeakRefreshRatePhysicalLimit
+ );
+
/**
* @return {@code true} if 'port' is allowed in display layout configuration file.
*/
@@ -312,6 +317,10 @@
return mUseFusionProxSensor.getName();
}
+ public boolean isPeakRefreshRatePhysicalLimitEnabled() {
+ return mPeakRefreshRatePhysicalLimit.isEnabled();
+ }
+
/**
* dumps all flagstates
* @param pw printWriter
@@ -343,6 +352,7 @@
pw.println(" " + mRefactorDisplayPowerController);
pw.println(" " + mResolutionBackupRestore);
pw.println(" " + mUseFusionProxSensor);
+ pw.println(" " + mPeakRefreshRatePhysicalLimit);
}
private static class FlagState {
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index a7dd243..3d64fc2 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -244,3 +244,14 @@
bug: "306203895"
is_fixed_read_only: true
}
+
+flag {
+ name: "enable_peak_refresh_rate_physical_limit"
+ namespace: "display_manager"
+ description: "Flag for adding physical refresh rate limit if smooth display setting is on "
+ bug: "332413475"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
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 1c8c8a4..3084dae 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -940,6 +940,7 @@
Settings.Secure.getUriFor(Settings.Secure.MATCH_CONTENT_FRAME_RATE);
private final boolean mVsynLowPowerVoteEnabled;
+ private final boolean mPeakRefreshRatePhysicalLimitEnabled;
private final Context mContext;
private float mDefaultPeakRefreshRate;
@@ -950,6 +951,7 @@
super(handler);
mContext = context;
mVsynLowPowerVoteEnabled = flags.isVsyncLowPowerVoteEnabled();
+ mPeakRefreshRatePhysicalLimitEnabled = flags.isPeakRefreshRatePhysicalLimitEnabled();
// We don't want to load from the DeviceConfig while constructing since this leads to
// a spike in the latency of DisplayManagerService startup. This happens because
// reading from the DeviceConfig is an intensive IO operation and having it in the
@@ -1127,11 +1129,19 @@
// used to predict if we're going to be doing frequent refresh rate switching, and if
// so, enable the brightness observer. The logic here is more complicated and fragile
// than necessary, and we should improve it. See b/156304339 for more info.
- Vote peakVote = peakRefreshRate == 0f
+ if (mPeakRefreshRatePhysicalLimitEnabled) {
+ Vote peakVote = peakRefreshRate == 0f
+ ? null
+ : Vote.forPhysicalRefreshRates(0f,
+ Math.max(minRefreshRate, peakRefreshRate));
+ mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE,
+ peakVote);
+ }
+ Vote peakRenderVote = peakRefreshRate == 0f
? null
: Vote.forRenderFrameRates(0f, Math.max(minRefreshRate, peakRefreshRate));
mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE,
- peakVote);
+ peakRenderVote);
mVotesStorage.updateVote(displayId, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE,
Vote.forRenderFrameRates(minRefreshRate, Float.POSITIVE_INFINITY));
Vote defaultVote =
diff --git a/services/core/java/com/android/server/display/mode/Vote.java b/services/core/java/com/android/server/display/mode/Vote.java
index 5b987f4..ddb334e 100644
--- a/services/core/java/com/android/server/display/mode/Vote.java
+++ b/services/core/java/com/android/server/display/mode/Vote.java
@@ -76,46 +76,52 @@
int PRIORITY_APP_REQUEST_SIZE = 7;
- // SETTING_PEAK_RENDER_FRAME_RATE has a high priority and will restrict the bounds of the
- // rest of low priority voters. It votes [0, max(PEAK, MIN)]
- int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 8;
+ // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE restricts physical refresh rate to
+ // [0, max(PEAK, MIN)], depending on user settings peakRR/minRR values
+ int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 8;
+
+ // PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE has a higher priority than
+ // PRIORITY_USER_SETTING_PEAK_REFRESH_RATE and will limit render rate to [0, max(PEAK, MIN)]
+ // in case physical refresh rate vote is discarded (due to other high priority votes),
+ // render rate vote can still apply
+ int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 9;
// Restrict all displays to 60Hz when external display is connected. It votes [59Hz, 61Hz].
- int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 9;
+ int PRIORITY_SYNCHRONIZED_REFRESH_RATE = 10;
// Restrict displays max available resolution and refresh rates. It votes [0, LIMIT]
- int PRIORITY_LIMIT_MODE = 10;
+ int PRIORITY_LIMIT_MODE = 11;
// To avoid delay in switching between 60HZ -> 90HZ when activating LHBM, set refresh
// rate to max value (same as for PRIORITY_UDFPS) on lock screen
- int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 11;
+ int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 12;
// For concurrent displays we want to limit refresh rate on all displays
- int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 12;
+ int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 13;
// For internal application to limit display modes to specific ids
- int PRIORITY_SYSTEM_REQUESTED_MODES = 13;
+ int PRIORITY_SYSTEM_REQUESTED_MODES = 14;
// LOW_POWER_MODE force the render frame rate to [0, 60HZ] if
// Settings.Global.LOW_POWER_MODE is on.
- int PRIORITY_LOW_POWER_MODE = 14;
+ int PRIORITY_LOW_POWER_MODE = 15;
// PRIORITY_FLICKER_REFRESH_RATE_SWITCH votes for disabling refresh rate switching. If the
// higher priority voters' result is a range, it will fix the rate to a single choice.
// It's used to avoid refresh rate switches in certain conditions which may result in the
// user seeing the display flickering when the switches occur.
- int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 15;
+ int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 16;
// Force display to [0, 60HZ] if skin temperature is at or above CRITICAL.
- int PRIORITY_SKIN_TEMPERATURE = 16;
+ int PRIORITY_SKIN_TEMPERATURE = 17;
// The proximity sensor needs the refresh rate to be locked in order to function, so this is
// set to a high priority.
- int PRIORITY_PROXIMITY = 17;
+ int PRIORITY_PROXIMITY = 18;
// The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
// to function, so this needs to be the highest priority of all votes.
- int PRIORITY_UDFPS = 18;
+ int PRIORITY_UDFPS = 19;
// Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
// APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index a818eab..816242d 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -205,7 +205,7 @@
Intent intent = new Intent(DreamService.SERVICE_INTERFACE);
intent.setComponent(name);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- intent.putExtra(DreamService.EXTRA_DREAM_OVERLAY_COMPONENT, overlayComponentName);
+ DreamService.setDreamOverlayComponent(intent, overlayComponentName);
try {
if (!mContext.bindServiceAsUser(intent, mCurrentDream,
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java
index 4636a49..7285151 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java
@@ -244,8 +244,9 @@
// Broadcast messages shouldn't be sent with any permissions tagged per CHRE API
// requirements.
if (!messagePermissions.isEmpty()) {
- Log.wtf(TAG, "Received broadcast message with permissions from "
+ Log.e(TAG, "Received broadcast message with permissions from "
+ message.getNanoAppId());
+ return ErrorCode.PERMANENT_ERROR;
}
ContextHubEventLogger.getInstance().logMessageFromNanoapp(contextHubId, message,
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index f981d79..3998667 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -665,6 +665,9 @@
}
private void addUserEngagedSession(MediaSessionRecordImpl mediaSessionRecord) {
+ if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
+ return;
+ }
synchronized (mLock) {
int uid = mediaSessionRecord.getUid();
mUserEngagedSessionsForFgs.putIfAbsent(uid, new HashSet<>());
@@ -673,6 +676,9 @@
}
private void removeUserEngagedSession(MediaSessionRecordImpl mediaSessionRecord) {
+ if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
+ return;
+ }
synchronized (mLock) {
int uid = mediaSessionRecord.getUid();
Set<MediaSessionRecordImpl> mUidUserEngagedSessionsForFgs =
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 36790ab..2e25ad8 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -573,12 +573,16 @@
(scanFlags & SCAN_DONT_KILL_APP) != 0 /* retainImplicitGrantOnReplace */);
mPm.addAllPackageProperties(pkg);
- if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) {
- mPm.mDomainVerificationManager.addPackage(pkgSetting,
- request.getPreVerifiedDomains());
- } else {
- mPm.mDomainVerificationManager.migrateState(oldPkgSetting, pkgSetting,
- request.getPreVerifiedDomains());
+ // Only verify app links for non-archival installations, otherwise there won't be any
+ // declared app links.
+ if (!request.isArchived()) {
+ if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) {
+ mPm.mDomainVerificationManager.addPackage(pkgSetting,
+ request.getPreVerifiedDomains());
+ } else {
+ mPm.mDomainVerificationManager.migrateState(oldPkgSetting, pkgSetting,
+ request.getPreVerifiedDomains());
+ }
}
int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 6e17fd3..4ddd546 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -91,7 +91,7 @@
@GuardedBy("mLock")
private final ArrayMap<Integer, ArrayMap<IBinder, ArraySet<AppHintSession>>> mActiveSessions;
- /** Lock to protect mActiveSessions. */
+ /** Lock to protect mActiveSessions and the UidObserver. */
private final Object mLock = new Object();
@GuardedBy("mNonIsolatedTidsLock")
@@ -318,11 +318,10 @@
@VisibleForTesting
final class MyUidObserver extends UidObserver {
- private final Object mCacheLock = new Object();
- @GuardedBy("mCacheLock")
+ @GuardedBy("mLock")
private final SparseIntArray mProcStatesCache = new SparseIntArray();
public boolean isUidForeground(int uid) {
- synchronized (mCacheLock) {
+ synchronized (mLock) {
return mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)
<= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
}
@@ -331,10 +330,8 @@
@Override
public void onUidGone(int uid, boolean disabled) {
FgThread.getHandler().post(() -> {
- synchronized (mCacheLock) {
- mProcStatesCache.delete(uid);
- }
synchronized (mLock) {
+ mProcStatesCache.delete(uid);
ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = mActiveSessions.get(uid);
if (tokenMap == null) {
return;
@@ -357,7 +354,7 @@
@Override
public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
FgThread.getHandler().post(() -> {
- synchronized (mCacheLock) {
+ synchronized (mLock) {
if (powerhintThreadCleanup()) {
final boolean before = isUidForeground(uid);
mProcStatesCache.put(uid, procState);
@@ -370,9 +367,7 @@
} else {
mProcStatesCache.put(uid, procState);
}
- }
- boolean shouldAllowUpdate = isUidForeground(uid);
- synchronized (mLock) {
+ boolean shouldAllowUpdate = isUidForeground(uid);
ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = mActiveSessions.get(uid);
if (tokenMap == null) {
return;
@@ -691,10 +686,10 @@
}
}
- AppHintSession hs = new AppHintSession(callingUid, callingTgid, tids, token,
- halSessionPtr, durationNanos);
logPerformanceHintSessionAtom(callingUid, halSessionPtr, durationNanos, tids);
synchronized (mLock) {
+ AppHintSession hs = new AppHintSession(callingUid, callingTgid, tids, token,
+ halSessionPtr, durationNanos);
ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap =
mActiveSessions.get(callingUid);
if (tokenMap == null) {
diff --git a/services/core/java/com/android/server/utils/AnrTimer.java b/services/core/java/com/android/server/utils/AnrTimer.java
index e944eca..592d039 100644
--- a/services/core/java/com/android/server/utils/AnrTimer.java
+++ b/services/core/java/com/android/server/utils/AnrTimer.java
@@ -47,7 +47,7 @@
* mode, the timer just sends a delayed message. In modern mode, the timer is implemented in
* native code; on expiration, the message is sent without delay.
*
- * <p>There are four external operations on a timer:
+ * <p>There are five external operations on a timer:
* <ul>
*
* <li>{@link #start} starts a timer. The timer is started with an object that the message
@@ -74,9 +74,13 @@
* exit. (So, instances in system server generally need not be explicitly closed since they are
* created during process start and will last until process exit.)
*
+ * <p>AnrTimer parameterized by the type <code>V</code>. The public methods on AnrTimer require
+ * an instance of <code>V</code>; the instance of <code>V</code> is a key that identifies a
+ * specific timer.
+ *
* @hide
*/
-public class AnrTimer<V> implements AutoCloseable {
+public abstract class AnrTimer<V> implements AutoCloseable {
/**
* The log tag.
@@ -101,6 +105,20 @@
private static final long TRACE_TAG = Trace.TRACE_TAG_ACTIVITY_MANAGER;
/**
+ * Fetch the Linux pid from the object. The returned value may be zero to indicate that there
+ * is no valid pid available.
+ * @return a valid pid or zero.
+ */
+ public abstract int getPid(V obj);
+
+ /**
+ * Fetch the Linux uid from the object. The returned value may be zero to indicate that there
+ * is no valid uid available.
+ * @return a valid uid or zero.
+ */
+ public abstract int getUid(V obj);
+
+ /**
* Return true if the feature is enabled. By default, the value is take from the Flags class
* but it can be changed for local testing.
*/
@@ -564,13 +582,11 @@
* allows a client to deliver an immediate timeout via the AnrTimer.
*
* @param arg The key by which the timer is known. This is never examined or modified.
- * @param pid The Linux process ID of the target being timed.
- * @param uid The Linux user ID of the target being timed.
* @param timeoutMs The timer timeout, in milliseconds.
*/
- public void start(@NonNull V arg, int pid, int uid, long timeoutMs) {
+ public void start(@NonNull V arg, long timeoutMs) {
if (timeoutMs < 0) timeoutMs = 0;
- mFeature.start(arg, pid, uid, timeoutMs);
+ mFeature.start(arg, getPid(arg), getUid(arg), timeoutMs);
}
/**
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index ad54efc..84c37180 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -75,7 +75,7 @@
IGNORED_ERROR_TOKEN(VibrationProto.IGNORED_ERROR_TOKEN),
IGNORED_APP_OPS(VibrationProto.IGNORED_APP_OPS),
IGNORED_BACKGROUND(VibrationProto.IGNORED_BACKGROUND),
- IGNORED_UNKNOWN_VIBRATION(VibrationProto.IGNORED_UNKNOWN_VIBRATION),
+ IGNORED_MISSING_PERMISSION(VibrationProto.IGNORED_MISSING_PERMISSION),
IGNORED_UNSUPPORTED(VibrationProto.IGNORED_UNSUPPORTED),
IGNORED_FOR_EXTERNAL(VibrationProto.IGNORED_FOR_EXTERNAL),
IGNORED_FOR_HIGHER_IMPORTANCE(VibrationProto.IGNORED_FOR_HIGHER_IMPORTANCE),
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 8281ac1..09c2493 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -436,26 +436,26 @@
IBinder token, boolean fromIme) {
HapticFeedbackVibrationProvider hapticVibrationProvider = getHapticVibrationProvider();
if (hapticVibrationProvider == null) {
- Slog.w(TAG, "performHapticFeedback; haptic vibration provider not ready.");
+ Slog.e(TAG, "performHapticFeedback; haptic vibration provider not ready.");
return null;
}
if (hapticVibrationProvider.isRestrictedHapticFeedback(constant)
&& !hasPermission(android.Manifest.permission.VIBRATE_SYSTEM_CONSTANTS)) {
- Slog.w(TAG, "performHapticFeedback; no permission for effect " + constant);
+ Slog.w(TAG, "performHapticFeedback; no permission for system constant " + constant);
return null;
}
VibrationEffect effect = hapticVibrationProvider.getVibrationForHapticFeedback(constant);
if (effect == null) {
- Slog.w(TAG, "performHapticFeedback; vibration absent for effect " + constant);
+ Slog.w(TAG, "performHapticFeedback; vibration absent for constant " + constant);
return null;
}
- CombinedVibration combinedVibration = CombinedVibration.createParallel(effect);
+ CombinedVibration vib = CombinedVibration.createParallel(effect);
VibrationAttributes attrs =
hapticVibrationProvider.getVibrationAttributesForHapticFeedback(
constant, /* bypassVibrationIntensitySetting= */ always, fromIme);
+ reason = "performHapticFeedback(constant=" + constant + "): " + reason;
VibratorFrameworkStatsLogger.logPerformHapticsFeedbackIfKeyboard(uid, constant);
- return vibrateWithoutPermissionCheck(uid, deviceId, opPkg, combinedVibration, attrs,
- "performHapticFeedback: " + reason, token);
+ return vibrateWithoutPermissionCheck(uid, deviceId, opPkg, vib, attrs, reason, token);
}
/**
@@ -1951,39 +1951,34 @@
/** Implementation of {@link IExternalVibratorService} to be triggered on external control. */
@VisibleForTesting
final class ExternalVibratorService extends IExternalVibratorService.Stub {
- private static final ExternalVibrationScale SCALE_MUTE = new ExternalVibrationScale();
-
- static {
- SCALE_MUTE.scaleLevel = ExternalVibrationScale.ScaleLevel.SCALE_MUTE;
- }
@Override
public ExternalVibrationScale onExternalVibrationStart(ExternalVibration vib) {
- if (!hasExternalControlCapability()) {
- return SCALE_MUTE;
- }
- if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE,
- vib.getUid(), -1 /*owningUid*/, true /*exported*/)
- != PackageManager.PERMISSION_GRANTED) {
- Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid()
- + " tried to play externally controlled vibration"
- + " without VIBRATE permission, ignoring.");
- return SCALE_MUTE;
- }
-
// Create Vibration.Stats as close to the received request as possible, for tracking.
ExternalVibrationHolder vibHolder = new ExternalVibrationHolder(vib);
- VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(),
- /* effect= */ null);
- 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();
- }
-
+ // Mute the request until we run all the checks and accept the vibration.
+ vibHolder.scale.scaleLevel = ExternalVibrationScale.ScaleLevel.SCALE_MUTE;
boolean alreadyUnderExternalControl = false;
boolean waitForCompletion = false;
+
synchronized (mLock) {
+ if (!hasExternalControlCapability()) {
+ endVibrationAndWriteStatsLocked(vibHolder,
+ new Vibration.EndInfo(Vibration.Status.IGNORED_UNSUPPORTED));
+ return vibHolder.scale;
+ }
+
+ if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE,
+ vib.getUid(), -1 /*owningUid*/, true /*exported*/)
+ != PackageManager.PERMISSION_GRANTED) {
+ Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid()
+ + " tried to play externally controlled vibration"
+ + " without VIBRATE permission, ignoring.");
+ endVibrationAndWriteStatsLocked(vibHolder,
+ new Vibration.EndInfo(Vibration.Status.IGNORED_MISSING_PERMISSION));
+ return vibHolder.scale;
+ }
+
Vibration.EndInfo vibrationEndInfo = shouldIgnoreVibrationLocked(
vibHolder.callerInfo);
@@ -2001,8 +1996,6 @@
}
if (vibrationEndInfo != null) {
- vibHolder.scale = SCALE_MUTE;
- // Failed to start the vibration, end it and report metrics right away.
endVibrationAndWriteStatsLocked(vibHolder, vibrationEndInfo);
return vibHolder.scale;
}
@@ -2040,6 +2033,15 @@
vibHolder.callerInfo),
/* continueExternalControl= */ true);
}
+
+ VibrationAttributes attrs = fixupVibrationAttributes(vib.getVibrationAttributes(),
+ /* effect= */ null);
+ 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();
+ }
+
mCurrentExternalVibration = vibHolder;
vibHolder.linkToDeath();
vibHolder.scale.scaleLevel = mVibrationScaler.getScaleLevel(attrs.getUsage());
@@ -2055,8 +2057,10 @@
endExternalVibrateLocked(
new Vibration.EndInfo(Vibration.Status.IGNORED_ERROR_CANCELLING),
/* continueExternalControl= */ false);
+ // Mute the request, vibration will be ignored.
+ vibHolder.scale.scaleLevel = ExternalVibrationScale.ScaleLevel.SCALE_MUTE;
}
- return SCALE_MUTE;
+ return vibHolder.scale;
}
}
if (!alreadyUnderExternalControl) {
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index fe4522a..c5683f3 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -99,6 +99,7 @@
import android.window.SizeConfigurationBuckets;
import android.window.TransitionInfo;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.AssistUtils;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.protolog.common.ProtoLog;
@@ -108,6 +109,9 @@
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.uri.GrantUri;
import com.android.server.uri.NeededUriGrants;
+import com.android.server.utils.quota.Categorizer;
+import com.android.server.utils.quota.Category;
+import com.android.server.utils.quota.CountQuotaTracker;
import com.android.server.vr.VrManagerInternal;
/**
@@ -123,6 +127,13 @@
private final ActivityTaskSupervisor mTaskSupervisor;
private final Context mContext;
+ // Prevent malicious app abusing the Activity#setPictureInPictureParams API
+ @VisibleForTesting CountQuotaTracker mSetPipAspectRatioQuotaTracker;
+ // Limit to 60 times / minute
+ private static final int SET_PIP_ASPECT_RATIO_LIMIT = 60;
+ // The timeWindowMs here can not be smaller than QuotaTracker#MIN_WINDOW_SIZE_MS
+ private static final long SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS = 60_000;
+
/** Wrapper around VoiceInteractionServiceManager. */
private AssistUtils mAssistUtils;
@@ -1035,6 +1046,25 @@
+ ": Current activity does not support picture-in-picture.");
}
+ // Rate limit how frequent an app can request aspect ratio change via
+ // Activity#setPictureInPictureParams
+ final int userId = UserHandle.getCallingUserId();
+ if (mSetPipAspectRatioQuotaTracker == null) {
+ mSetPipAspectRatioQuotaTracker = new CountQuotaTracker(mContext,
+ Categorizer.SINGLE_CATEGORIZER);
+ mSetPipAspectRatioQuotaTracker.setCountLimit(Category.SINGLE_CATEGORY,
+ SET_PIP_ASPECT_RATIO_LIMIT, SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS);
+ }
+ if (r.pictureInPictureArgs.hasSetAspectRatio()
+ && params.hasSetAspectRatio()
+ && !r.pictureInPictureArgs.getAspectRatio().equals(
+ params.getAspectRatio())
+ && !mSetPipAspectRatioQuotaTracker.noteEvent(
+ userId, r.packageName, "setPipAspectRatio")) {
+ throw new IllegalStateException(caller
+ + ": Too many PiP aspect ratio change requests from " + r.packageName);
+ }
+
final float minAspectRatio = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
final float maxAspectRatio = mContext.getResources().getFloat(
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b3c43bc..fc05d17 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1374,13 +1374,14 @@
final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
+ final int userId = UserHandle.getCallingUserId();
ActivityInfo aInfo = null;
try {
List<ResolveInfo> resolves =
AppGlobals.getPackageManager().queryIntentActivities(
intent, r.resolvedType,
PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
- UserHandle.getCallingUserId()).getList();
+ userId).getList();
// Look for the original activity in the list...
final int N = resolves != null ? resolves.size() : 0;
@@ -1465,6 +1466,7 @@
.setRealCallingPid(-1)
.setRealCallingUid(r.launchedFromUid)
.setActivityOptions(options)
+ .setUserId(userId)
.execute();
r.finishing = wasFinishing;
return res == ActivityManager.START_SUCCESS;
diff --git a/services/core/java/com/android/server/wm/PerfettoTransitionTracer.java b/services/core/java/com/android/server/wm/PerfettoTransitionTracer.java
index 883d27f..498182d 100644
--- a/services/core/java/com/android/server/wm/PerfettoTransitionTracer.java
+++ b/services/core/java/com/android/server/wm/PerfettoTransitionTracer.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.tracing.perfetto.DataSourceParams.PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_STALL_AND_ABORT;
+
import android.annotation.NonNull;
import android.internal.perfetto.protos.ShellTransitionOuterClass.ShellTransition;
import android.internal.perfetto.protos.TracePacketOuterClass.TracePacket;
@@ -39,7 +41,8 @@
PerfettoTransitionTracer() {
Producer.init(InitArguments.DEFAULTS);
- mDataSource.register(DataSourceParams.DEFAULTS);
+ mDataSource.register(
+ new DataSourceParams(PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_STALL_AND_ABORT));
}
/**
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 622a809..6003c1b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2477,6 +2477,7 @@
final DisplayContent display = getChildAt(displayNdx);
final boolean curResult = result;
boolean[] resumedOnDisplay = new boolean[1];
+ final ActivityRecord topOfDisplay = display.topRunningActivity();
display.forAllRootTasks(rootTask -> {
final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) {
@@ -2490,8 +2491,7 @@
resumedOnDisplay[0] |= curResult;
return;
}
- if (topRunningActivity.isState(RESUMED)
- && topRunningActivity == rootTask.getDisplayArea().topRunningActivity()) {
+ if (topRunningActivity.isState(RESUMED) && topRunningActivity == topOfDisplay) {
// Kick off any lingering app transitions form the MoveTaskToFront operation,
// but only consider the top activity on that display.
rootTask.executeAppTransition(targetOptions);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index de7c0eb..616ab88 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -349,6 +349,7 @@
import com.android.server.DisplayThread;
import com.android.server.FgThread;
import com.android.server.LocalServices;
+import com.android.server.SystemConfig;
import com.android.server.UiThread;
import com.android.server.Watchdog;
import com.android.server.input.InputManagerService;
@@ -454,13 +455,12 @@
/**
* Use WMShell for app transition.
*/
- public static final String ENABLE_SHELL_TRANSITIONS = "persist.wm.debug.shell_transit";
+ private static final String ENABLE_SHELL_TRANSITIONS = "persist.wm.debug.shell_transit";
/**
* @see #ENABLE_SHELL_TRANSITIONS
*/
- public static final boolean sEnableShellTransitions =
- SystemProperties.getBoolean(ENABLE_SHELL_TRANSITIONS, true);
+ public static final boolean sEnableShellTransitions = getShellTransitEnabled();
/**
* Allows a fullscreen windowing mode activity to launch in its desired orientation directly
@@ -10230,4 +10230,13 @@
}
}
}
+
+ private static boolean getShellTransitEnabled() {
+ android.content.pm.FeatureInfo autoFeature = SystemConfig.getInstance()
+ .getAvailableFeatures().get(PackageManager.FEATURE_AUTOMOTIVE);
+ if (autoFeature != null && autoFeature.version >= 0) {
+ return SystemProperties.getBoolean(ENABLE_SHELL_TRANSITIONS, true);
+ }
+ return true;
+ }
}
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 a2a4773..52e157b 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
@@ -78,7 +78,6 @@
import android.view.SurfaceControl;
import android.view.SurfaceControl.IdleScreenRefreshRateConfig;
import android.view.SurfaceControl.RefreshRateRange;
-import android.view.SurfaceControl.RefreshRateRanges;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
@@ -843,61 +842,6 @@
assertThat(desiredSpecs.appRequest.physical.max).isAtLeast(expectedAppRequestedRefreshRate);
}
- void verifySpecsWithRefreshRateSettings(DisplayModeDirector director, float minFps,
- float peakFps, float defaultFps, RefreshRateRanges primary,
- RefreshRateRanges appRequest) {
- DesiredDisplayModeSpecs specs = director.getDesiredDisplayModeSpecsWithInjectedFpsSettings(
- minFps, peakFps, defaultFps);
- assertThat(specs.primary).isEqualTo(primary);
- assertThat(specs.appRequest).isEqualTo(appRequest);
- }
-
- @Test
- public void testSpecsFromRefreshRateSettings() {
- // Confirm that, with varying settings for min, peak, and default refresh rate,
- // DesiredDisplayModeSpecs is calculated correctly.
- float[] refreshRates = {30.f, 60.f, 90.f, 120.f, 150.f};
- DisplayModeDirector director =
- createDirectorFromRefreshRateArray(refreshRates, /*baseModeId=*/0);
-
- float inf = Float.POSITIVE_INFINITY;
- RefreshRateRange rangeAll = new RefreshRateRange(0, inf);
- RefreshRateRange range0to60 = new RefreshRateRange(0, 60);
- RefreshRateRange range0to90 = new RefreshRateRange(0, 90);
- RefreshRateRange range0to120 = new RefreshRateRange(0, 120);
- RefreshRateRange range60to90 = new RefreshRateRange(60, 90);
- RefreshRateRange range90to90 = new RefreshRateRange(90, 90);
- RefreshRateRange range90to120 = new RefreshRateRange(90, 120);
- RefreshRateRange range60toInf = new RefreshRateRange(60, inf);
- RefreshRateRange range90toInf = new RefreshRateRange(90, inf);
-
- RefreshRateRanges frameRateAll = new RefreshRateRanges(rangeAll, rangeAll);
- RefreshRateRanges frameRate90toInf = new RefreshRateRanges(range90toInf, range90toInf);
- RefreshRateRanges frameRate0to60 = new RefreshRateRanges(rangeAll, range0to60);
- RefreshRateRanges frameRate0to90 = new RefreshRateRanges(rangeAll, range0to90);
- RefreshRateRanges frameRate0to120 = new RefreshRateRanges(rangeAll, range0to120);
- RefreshRateRanges frameRate60to90 = new RefreshRateRanges(range60toInf, range60to90);
- RefreshRateRanges frameRate90to90 = new RefreshRateRanges(range90toInf, range90to90);
- RefreshRateRanges frameRate90to120 = new RefreshRateRanges(range90toInf, range90to120);
-
- verifySpecsWithRefreshRateSettings(director, 0, 0, 0, frameRateAll, frameRateAll);
- verifySpecsWithRefreshRateSettings(director, 0, 0, 90, frameRate0to90, frameRateAll);
- verifySpecsWithRefreshRateSettings(director, 0, 90, 0, frameRate0to90, frameRate0to90);
- verifySpecsWithRefreshRateSettings(director, 0, 90, 60, frameRate0to60, frameRate0to90);
- verifySpecsWithRefreshRateSettings(director, 0, 90, 120, frameRate0to90,
- frameRate0to90);
- verifySpecsWithRefreshRateSettings(director, 90, 0, 0, frameRate90toInf, frameRateAll);
- verifySpecsWithRefreshRateSettings(director, 90, 0, 120, frameRate90to120,
- frameRateAll);
- verifySpecsWithRefreshRateSettings(director, 90, 0, 60, frameRate90toInf, frameRateAll);
- verifySpecsWithRefreshRateSettings(director, 90, 120, 0, frameRate90to120,
- frameRate0to120);
- verifySpecsWithRefreshRateSettings(director, 90, 60, 0, frameRate90to90,
- frameRate0to90);
- verifySpecsWithRefreshRateSettings(director, 60, 120, 90, frameRate60to90,
- frameRate0to120);
- }
-
void verifyBrightnessObserverCall(DisplayModeDirector director, float minFps, float peakFps,
float defaultFps, float brightnessObserverMin, float brightnessObserverMax) {
BrightnessObserver brightnessObserver = mock(BrightnessObserver.class);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/SettingsObserverTest.kt b/services/tests/displayservicetests/src/com/android/server/display/mode/SettingsObserverTest.kt
index 3c87261..3e0677c 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/SettingsObserverTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/SettingsObserverTest.kt
@@ -21,6 +21,8 @@
import android.provider.Settings
import android.util.SparseArray
import android.view.Display
+import android.view.SurfaceControl.RefreshRateRange
+import android.view.SurfaceControl.RefreshRateRanges
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SmallTest
import com.android.internal.util.test.FakeSettingsProvider
@@ -29,6 +31,7 @@
import com.android.server.display.mode.DisplayModeDirector.DisplayDeviceConfigProvider
import com.android.server.testutils.TestHandler
import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
import com.google.testing.junit.testparameterinjector.TestParameter
import com.google.testing.junit.testparameterinjector.TestParameterInjector
import org.junit.Before
@@ -40,6 +43,32 @@
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
+private val RANGE_NO_LIMIT = RefreshRateRange(0f, Float.POSITIVE_INFINITY)
+private val RANGE_0_60 = RefreshRateRange(0f, 60f)
+private val RANGE_0_90 = RefreshRateRange(0f, 90f)
+private val RANGE_0_120 = RefreshRateRange(0f, 120f)
+private val RANGE_60_90 = RefreshRateRange(60f, 90f)
+private val RANGE_60_120 = RefreshRateRange(60f, 120f)
+private val RANGE_60_INF = RefreshRateRange(60f, Float.POSITIVE_INFINITY)
+private val RANGE_90_90 = RefreshRateRange(90f, 90f)
+private val RANGE_90_120 = RefreshRateRange(90f, 120f)
+private val RANGE_90_INF = RefreshRateRange(90f, Float.POSITIVE_INFINITY)
+
+private val RANGES_NO_LIMIT = RefreshRateRanges(RANGE_NO_LIMIT, RANGE_NO_LIMIT)
+private val RANGES_NO_LIMIT_60 = RefreshRateRanges(RANGE_NO_LIMIT, RANGE_0_60)
+private val RANGES_NO_LIMIT_90 = RefreshRateRanges(RANGE_NO_LIMIT, RANGE_0_90)
+private val RANGES_NO_LIMIT_120 = RefreshRateRanges(RANGE_NO_LIMIT, RANGE_0_120)
+private val RANGES_90 = RefreshRateRanges(RANGE_0_90, RANGE_0_90)
+private val RANGES_120 = RefreshRateRanges(RANGE_0_120, RANGE_0_120)
+private val RANGES_90_60 = RefreshRateRanges(RANGE_0_90, RANGE_0_60)
+private val RANGES_90TO90 = RefreshRateRanges(RANGE_90_90, RANGE_90_90)
+private val RANGES_90TO120 = RefreshRateRanges(RANGE_90_120, RANGE_90_120)
+private val RANGES_60TO120_60TO90 = RefreshRateRanges(RANGE_60_120, RANGE_60_90)
+private val RANGES_MIN90 = RefreshRateRanges(RANGE_90_INF, RANGE_90_INF)
+private val RANGES_MIN90_90TO120 = RefreshRateRanges(RANGE_90_INF, RANGE_90_120)
+private val RANGES_MIN60_60TO90 = RefreshRateRanges(RANGE_60_INF, RANGE_60_90)
+private val RANGES_MIN90_90TO90 = RefreshRateRanges(RANGE_90_INF, RANGE_90_90)
+
@SmallTest
@RunWith(TestParameterInjector::class)
class SettingsObserverTest {
@@ -63,7 +92,7 @@
}
@Test
- fun testLowPowerMode(@TestParameter testCase: SettingsObserverTestCase) {
+ fun `test low power mode`(@TestParameter testCase: LowPowerTestCase) {
whenever(mockFlags.isVsyncLowPowerVoteEnabled).thenReturn(testCase.vsyncLowPowerVoteEnabled)
whenever(spyContext.contentResolver)
.thenReturn(settingsProviderRule.mockContentResolver(null))
@@ -87,23 +116,127 @@
Vote.PRIORITY_LOW_POWER_MODE)).isEqualTo(testCase.expectedVote)
}
- enum class SettingsObserverTestCase(
- val vrrSupported: Boolean,
- val vsyncLowPowerVoteEnabled: Boolean,
- val lowPowerModeEnabled: Boolean,
- internal val expectedVote: Vote?
+ enum class LowPowerTestCase(
+ val vrrSupported: Boolean,
+ val vsyncLowPowerVoteEnabled: Boolean,
+ val lowPowerModeEnabled: Boolean,
+ internal val expectedVote: Vote?
) {
ALL_ENABLED(true, true, true,
- SupportedRefreshRatesVote(listOf(
- SupportedRefreshRatesVote.RefreshRates(60f, 240f),
- SupportedRefreshRatesVote.RefreshRates(60f, 60f)
- ))),
+ SupportedRefreshRatesVote(listOf(
+ SupportedRefreshRatesVote.RefreshRates(60f, 240f),
+ SupportedRefreshRatesVote.RefreshRates(60f, 60f)
+ ))),
LOW_POWER_OFF(true, true, false, null),
DVRR_NOT_SUPPORTED_LOW_POWER_ON(false, true, true,
- RefreshRateVote.RenderVote(0f, 60f)),
+ RefreshRateVote.RenderVote(0f, 60f)),
DVRR_NOT_SUPPORTED_LOW_POWER_OFF(false, true, false, null),
VSYNC_VOTE_DISABLED_SUPPORTED_LOW_POWER_ON(true, false, true,
- RefreshRateVote.RenderVote(0f, 60f)),
+ RefreshRateVote.RenderVote(0f, 60f)),
VSYNC_VOTE_DISABLED_LOW_POWER_OFF(true, false, false, null),
}
+
+ @Test
+ fun `test settings refresh rates`(@TestParameter testCase: SettingsRefreshRateTestCase) {
+ whenever(mockFlags.isPeakRefreshRatePhysicalLimitEnabled)
+ .thenReturn(testCase.peakRefreshRatePhysicalLimitEnabled)
+
+ val displayModeDirector = DisplayModeDirector(
+ spyContext, testHandler, mockInjector, mockFlags, mockDisplayDeviceConfigProvider)
+
+ val modes = arrayOf(
+ Display.Mode(1, 1000, 1000, 60f),
+ Display.Mode(1, 1000, 1000, 90f),
+ Display.Mode(1, 1000, 1000, 120f)
+ )
+ displayModeDirector.injectSupportedModesByDisplay(SparseArray<Array<Display.Mode>>().apply {
+ append(Display.DEFAULT_DISPLAY, modes)
+ })
+ displayModeDirector.injectDefaultModeByDisplay(SparseArray<Display.Mode>().apply {
+ append(Display.DEFAULT_DISPLAY, modes[0])
+ })
+
+ val specs = displayModeDirector.getDesiredDisplayModeSpecsWithInjectedFpsSettings(
+ testCase.minRefreshRate, testCase.peakRefreshRate, testCase.defaultRefreshRate)
+
+ assertWithMessage("Primary RefreshRateRanges: ")
+ .that(specs.primary).isEqualTo(testCase.expectedPrimaryRefreshRateRanges)
+ assertWithMessage("App RefreshRateRanges: ")
+ .that(specs.appRequest).isEqualTo(testCase.expectedAppRefreshRateRanges)
+ }
+
+ /**
+ * Votes considered:
+ * priority: PRIORITY_USER_SETTING_PEAK_REFRESH_RATE (also used for appRanged)
+ * condition: peakRefreshRatePhysicalLimitEnabled, peakRR > 0
+ * vote: physical(minRR, peakRR)
+ *
+ * priority: PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE (also used for appRanged)
+ * condition: peakRR > 0
+ * vote: render(minRR, peakRR)
+ *
+ * priority: PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE
+ * condition: -
+ * vote: render(minRR, INF)
+ *
+ * priority: PRIORITY_DEFAULT_RENDER_FRAME_RATE
+ * condition: defaultRR > 0
+ * vote: render(0, defaultRR)
+ *
+ * 0 considered not set
+ *
+ * For this test:
+ * primary physical rate:
+ * (minRR, peakRefreshRatePhysicalLimitEnabled ? max(minRR, peakRR) : INF)
+ * primary render rate : (minRR, min(defaultRR, max(minRR, peakRR)))
+ *
+ * app physical rate: (0, peakRefreshRatePhysicalLimitEnabled ? max(minRR, peakRR) : INF)
+ * app render rate: (0, max(minRR, peakRR))
+ */
+ enum class SettingsRefreshRateTestCase(
+ val minRefreshRate: Float,
+ val peakRefreshRate: Float,
+ val defaultRefreshRate: Float,
+ val peakRefreshRatePhysicalLimitEnabled: Boolean,
+ val expectedPrimaryRefreshRateRanges: RefreshRateRanges,
+ val expectedAppRefreshRateRanges: RefreshRateRanges,
+ ) {
+ NO_LIMIT(0f, 0f, 0f, false, RANGES_NO_LIMIT, RANGES_NO_LIMIT),
+ NO_LIMIT_WITH_PHYSICAL_RR(0f, 0f, 0f, true, RANGES_NO_LIMIT, RANGES_NO_LIMIT),
+
+ LIMITS_0_0_90(0f, 0f, 90f, false, RANGES_NO_LIMIT_90, RANGES_NO_LIMIT),
+ LIMITS_0_0_90_WITH_PHYSICAL_RR(0f, 0f, 90f, true, RANGES_NO_LIMIT_90, RANGES_NO_LIMIT),
+
+ LIMITS_0_90_0(0f, 90f, 0f, false, RANGES_NO_LIMIT_90, RANGES_NO_LIMIT_90),
+ LIMITS_0_90_0_WITH_PHYSICAL_RR(0f, 90f, 0f, true, RANGES_90, RANGES_90),
+
+ LIMITS_0_90_60(0f, 90f, 60f, false, RANGES_NO_LIMIT_60, RANGES_NO_LIMIT_90),
+ LIMITS_0_90_60_WITH_PHYSICAL_RR(0f, 90f, 60f, true, RANGES_90_60, RANGES_90),
+
+ LIMITS_0_90_120(0f, 90f, 120f, false, RANGES_NO_LIMIT_90, RANGES_NO_LIMIT_90),
+ LIMITS_0_90_120_WITH_PHYSICAL_RR(0f, 90f, 120f, true, RANGES_90, RANGES_90),
+
+ LIMITS_90_0_0(90f, 0f, 0f, false, RANGES_MIN90, RANGES_NO_LIMIT),
+ LIMITS_90_0_0_WITH_PHYSICAL_RR(90f, 0f, 0f, true, RANGES_MIN90, RANGES_NO_LIMIT),
+
+ LIMITS_90_0_120(90f, 0f, 120f, false, RANGES_MIN90_90TO120, RANGES_NO_LIMIT),
+ LIMITS_90_0_120_WITH_PHYSICAL_RR(90f,
+ 0f,
+ 120f,
+ true,
+ RANGES_MIN90_90TO120,
+ RANGES_NO_LIMIT),
+
+ LIMITS_90_0_60(90f, 0f, 60f, false, RANGES_MIN90, RANGES_NO_LIMIT),
+ LIMITS_90_0_60_WITH_PHYSICAL_RR(90f, 0f, 60f, true, RANGES_MIN90, RANGES_NO_LIMIT),
+
+ LIMITS_90_120_0(90f, 120f, 0f, false, RANGES_MIN90_90TO120, RANGES_NO_LIMIT_120),
+ LIMITS_90_120_0_WITH_PHYSICAL_RR(90f, 120f, 0f, true, RANGES_90TO120, RANGES_120),
+
+ LIMITS_90_60_0(90f, 60f, 0f, false, RANGES_MIN90_90TO90, RANGES_NO_LIMIT_90),
+ LIMITS_90_60_0_WITH_PHYSICAL_RR(90f, 60f, 0f, true, RANGES_90TO90, RANGES_90),
+
+ LIMITS_60_120_90(60f, 120f, 90f, false, RANGES_MIN60_60TO90, RANGES_NO_LIMIT_120),
+ LIMITS_60_120_90_WITH_PHYSICAL_RR(60f, 120f, 90f, true, RANGES_60TO120_60TO90, RANGES_120),
+ }
}
\ No newline at end of file
diff --git a/services/tests/dreamservicetests/Android.bp b/services/tests/dreamservicetests/Android.bp
index 86b3a6c..6369d45 100644
--- a/services/tests/dreamservicetests/Android.bp
+++ b/services/tests/dreamservicetests/Android.bp
@@ -18,7 +18,9 @@
"mockito-target-minus-junit4",
"services.core",
"mockingservicestests-utils-mockito",
+ "platform-test-annotations",
"servicestests-utils",
+ "testables",
],
defaults: [
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
index 293ab7b..23314cd 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
@@ -19,17 +19,26 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
+import android.os.Looper;
+import android.platform.test.annotations.EnableFlags;
import android.service.dreams.DreamService;
+import android.service.dreams.Flags;
+import android.service.dreams.IDreamOverlayCallback;
+import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -38,6 +47,18 @@
public class DreamServiceTest {
private static final String TEST_PACKAGE_NAME = "com.android.frameworks.dreamservicetests";
+ private TestableLooper mTestableLooper;
+
+ @Before
+ public void setup() throws Exception {
+ mTestableLooper = new TestableLooper(Looper.getMainLooper());
+ }
+
+ @After
+ public void tearDown() {
+ mTestableLooper.destroy();
+ }
+
@Test
public void testMetadataParsing() throws PackageManager.NameNotFoundException {
final String testDreamClassName = "com.android.server.dreams.TestDreamService";
@@ -70,4 +91,76 @@
PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA));
return DreamService.getDreamMetadata(context, si);
}
+
+ /**
+ * Verifies progressing a {@link DreamService} to creation
+ */
+ @Test
+ public void testCreate() throws Exception {
+ final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+ .setShouldShowComplications(true)
+ .build();
+ assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_CREATE));
+ }
+
+ /**
+ * Verifies progressing a {@link DreamService} to binding
+ */
+ @Test
+ public void testBind() throws Exception {
+ final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+ .setShouldShowComplications(true)
+ .build();
+ assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_BIND));
+ }
+
+ /**
+ * Verifies progressing a {@link DreamService} through
+ * {@link android.service.dreams.DreamActivity} creation.
+ */
+ @Test
+ public void testDreamActivityCreate() throws Exception {
+ final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+ .setShouldShowComplications(true)
+ .build();
+ assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_DREAM_ACTIVITY_CREATED));
+ }
+
+ /**
+ * Verifies progressing a {@link DreamService} through starting.
+ */
+ @Test
+ public void testStart() throws Exception {
+ final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+ .setShouldShowComplications(true)
+ .build();
+ assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_STARTED));
+ }
+
+ /**
+ * Verifies progressing a {@link DreamService} through waking.
+ */
+ @Test
+ public void testWake() throws Exception {
+ final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+ .setShouldShowComplications(true)
+ .build();
+ assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_WOKEN));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT)
+ public void testRedirect() throws Exception {
+ TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+ .setDreamOverlayPresent(true)
+ .setShouldShowComplications(true)
+ .build();
+
+ environment.advance(TestDreamEnvironment.DREAM_STATE_STARTED);
+ final IDreamOverlayCallback overlayCallback = environment.getDreamOverlayCallback();
+ overlayCallback.onRedirectWake(true);
+ environment.resetClientInvocations();
+ environment.advance(TestDreamEnvironment.DREAM_STATE_WOKEN);
+ verify(environment.getDreamOverlayClient()).onWakeRequested();
+ }
}
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
new file mode 100644
index 0000000..ef85ba5
--- /dev/null
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
@@ -0,0 +1,418 @@
+/*
+ * 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.dreams;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.description;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.IntDef;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IRemoteCallback;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.service.dreams.DreamActivity;
+import android.service.dreams.DreamOverlayConnectionHandler;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
+import android.service.dreams.IDreamOverlayCallback;
+import android.service.dreams.IDreamOverlayClient;
+import android.service.dreams.IDreamService;
+import android.testing.TestableLooper;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowInsetsController;
+import android.view.WindowManager;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.function.Consumer;
+
+
+/**
+ * {@link TestDreamEnvironment} sets up entire testing environment around a dream service, allowing
+ * bring-up and interaction around the dream.
+ *
+ * @hide
+ */
+@VisibleForTesting
+public class TestDreamEnvironment {
+ private static final String FAKE_DREAM_PACKAGE_NAME = "com.foo.bar";
+ private static final ComponentName FAKE_DREAM_OVERLAY_COMPONENT =
+ ComponentName.createRelative(FAKE_DREAM_PACKAGE_NAME, ".OverlayComponent");
+ private static final String FAKE_DREAM_SETTINGS_ACTIVITY = ".SettingsActivity";
+ private static final ComponentName FAKE_DREAM_ACTIVITY_COMPONENT =
+ ComponentName.createRelative(FAKE_DREAM_PACKAGE_NAME, ".DreamActivity");
+ private static final ComponentName FAKE_DREAM_COMPONENT =
+ ComponentName.createRelative(FAKE_DREAM_PACKAGE_NAME, ".DreamService");
+
+ /** Initial state when creating a test environment */
+ public static final int DREAM_STATE_INIT = 0;
+
+ /** State where the dream has been created */
+ public static final int DREAM_STATE_CREATE = 1;
+
+ /** State where the dream has been bound to */
+ public static final int DREAM_STATE_BIND = 2;
+
+ /** State where the dream activity has been created and signaled back to the dream */
+ public static final int DREAM_STATE_DREAM_ACTIVITY_CREATED = 3;
+
+
+ /** State where the dream has started after being attached */
+ public static final int DREAM_STATE_STARTED = 4;
+
+ /** State where the dream has been woken */
+ public static final int DREAM_STATE_WOKEN = 5;
+
+
+ @IntDef(prefix = { "DREAM_STATE_" }, value = {
+ DREAM_STATE_INIT,
+ DREAM_STATE_CREATE,
+ DREAM_STATE_BIND,
+ DREAM_STATE_DREAM_ACTIVITY_CREATED,
+ DREAM_STATE_STARTED,
+ DREAM_STATE_WOKEN,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DreamState{}
+
+ /**
+ * A convenience builder for assembling a {@link TestDreamEnvironment}.
+ */
+ public static class Builder {
+ private final TestableLooper mLooper;
+ private boolean mShouldShowComplications;
+ private boolean mOverlayPresent;
+ private boolean mWindowless;
+
+ public Builder(TestableLooper looper) {
+ mLooper = looper;
+ }
+
+ /**
+ * Sets whether the dream should show complications.
+ * @param show {@code true} for showing complications, {@code false} otherwise.
+ * @return The updated {@link Builder}.
+ */
+ public Builder setShouldShowComplications(boolean show) {
+ mShouldShowComplications = show;
+ return this;
+ }
+
+ /**
+ * Sets whether a dream overlay is present
+ * @param present {@code true} if the overlay is present, {@code false} otherwise.
+ */
+ public Builder setDreamOverlayPresent(boolean present) {
+ mOverlayPresent = present;
+ return this;
+ }
+
+ /**
+ * Sets whether the dream should be windowless
+ */
+ public Builder setWindowless(boolean windowless) {
+ mWindowless = windowless;
+ return this;
+ }
+
+ /**
+ * Builds the a {@link TestDreamEnvironment} based on the builder.
+ */
+ public TestDreamEnvironment build() throws Exception {
+ return new TestDreamEnvironment(mLooper, mShouldShowComplications,
+ mOverlayPresent, mWindowless);
+ }
+ }
+
+ private static class TestInjector implements DreamService.Injector {
+ @Mock
+ private Resources mResources;
+
+ @Mock
+ private PackageManager mPackageManager;
+
+ @Mock
+ private TypedArray mAttributes;
+
+ @Mock
+ private ServiceInfo mServiceInfo;
+
+ private final Handler mHandler;
+ private final IDreamManager mDreamManager;
+ private final DreamOverlayConnectionHandler mDreamOverlayConnectionHandler;
+
+ TestInjector(Looper looper,
+ IDreamManager dreamManager,
+ DreamOverlayConnectionHandler dreamOverlayConnectionHandler,
+ boolean shouldShowComplications) {
+ MockitoAnnotations.initMocks(this);
+ mHandler = new Handler(looper);
+ mDreamManager = dreamManager;
+ mDreamOverlayConnectionHandler = dreamOverlayConnectionHandler;
+ mServiceInfo.packageName = FAKE_DREAM_PACKAGE_NAME;
+ when(mAttributes.getBoolean(eq(R.styleable.Dream_showClockAndComplications),
+ anyBoolean()))
+ .thenReturn(shouldShowComplications);
+ when(mAttributes.getDrawable(eq(com.android.internal.R.styleable.Dream_previewImage)))
+ .thenReturn(mock(Drawable.class));
+ when(mAttributes.getString(eq(com.android.internal.R.styleable.Dream_settingsActivity)))
+ .thenReturn(FAKE_DREAM_SETTINGS_ACTIVITY);
+ when(mPackageManager.extractPackageItemInfoAttributes(any(), any(), any(), any()))
+ .thenReturn(mAttributes);
+ }
+ @Override
+ public void init(Context context) {
+ }
+
+ @Override
+ public DreamOverlayConnectionHandler createOverlayConnection(
+ ComponentName overlayComponent) {
+ return mDreamOverlayConnectionHandler;
+ }
+
+ @Override
+ public ComponentName getDreamActivityComponent() {
+ return FAKE_DREAM_ACTIVITY_COMPONENT;
+ }
+
+ @Override
+ public ComponentName getDreamComponent() {
+ return FAKE_DREAM_COMPONENT;
+ }
+
+ @Override
+ public String getDreamPackageName() {
+ return FAKE_DREAM_PACKAGE_NAME;
+ }
+
+ @Override
+ public IDreamManager getDreamManager() {
+ return mDreamManager;
+ }
+
+ @Override
+ public ServiceInfo getServiceInfo() {
+ return mServiceInfo;
+ }
+
+ @Override
+ public Handler getHandler() {
+ return mHandler;
+ }
+
+ @Override
+ public PackageManager getPackageManager() {
+ return mPackageManager;
+ }
+
+ @Override
+ public Resources getResources() {
+ return mResources;
+ }
+ }
+
+ @Mock
+ private IDreamManager mDreamManager;
+
+ @Mock
+ private DreamOverlayConnectionHandler mDreamOverlayConnectionHandler;
+
+ @Mock
+ private DreamActivity mDreamActivity;
+
+ @Mock
+ private Window mActivityWindow;
+
+ @Mock
+ private View mDecorView;
+
+ @Mock
+ private IDreamOverlayClient mDreamOverlayClient;
+
+ private final TestableLooper mTestableLooper;
+ private final DreamService mService;
+ private final boolean mWindowless;
+
+ private IDreamService mDreamServiceWrapper;
+
+ private @DreamState int mCurrentDreamState = DREAM_STATE_INIT;
+
+ private IDreamOverlayCallback mDreamOverlayCallback;
+
+ private boolean mOverlayPresent;
+
+ public TestDreamEnvironment(
+ TestableLooper looper,
+ boolean shouldShowComplications,
+ boolean overlayPresent,
+ boolean windowless
+ ) {
+ MockitoAnnotations.initMocks(this);
+
+ mOverlayPresent = overlayPresent;
+ mWindowless = windowless;
+
+ mTestableLooper = looper;
+ final DreamService.Injector injector = new TestInjector(mTestableLooper.getLooper(),
+ mDreamManager, mDreamOverlayConnectionHandler, shouldShowComplications);
+
+ when(mDreamActivity.getWindow()).thenReturn(mActivityWindow);
+ when(mActivityWindow.getAttributes()).thenReturn(mock(WindowManager.LayoutParams.class));
+ when(mActivityWindow.getDecorView()).thenReturn(mDecorView);
+ when(mDreamOverlayConnectionHandler.bind()).thenReturn(true);
+
+ doAnswer((InvocationOnMock invocation) -> {
+ Consumer<IDreamOverlayClient> client =
+ (Consumer<IDreamOverlayClient>) invocation.getArguments()[0];
+ client.accept(mDreamOverlayClient);
+ return null;
+ }).when(mDreamOverlayConnectionHandler).addConsumer(any());
+ when(mDecorView.getWindowInsetsController()).thenReturn(
+ mock(WindowInsetsController.class));
+
+ mService = new DreamService(injector);
+ }
+
+ /**
+ * Advances a dream to a given state, progressing through all previous states.
+ */
+ public boolean advance(@DreamState int state) throws Exception {
+ if (state <= mCurrentDreamState) {
+ return false;
+ }
+
+ do {
+ switch(++mCurrentDreamState) {
+ case DREAM_STATE_CREATE -> createDream();
+ case DREAM_STATE_BIND -> bindToDream();
+ case DREAM_STATE_DREAM_ACTIVITY_CREATED -> createDreamActivity();
+ case DREAM_STATE_STARTED -> startDream();
+ case DREAM_STATE_WOKEN -> wakeDream();
+ }
+ } while (mCurrentDreamState < state);
+
+ return true;
+ }
+
+ private void createDream() {
+ mService.onCreate();
+ mService.setWindowless(mWindowless);
+ }
+
+ private void bindToDream() {
+ final Intent intent = new Intent();
+
+ if (mOverlayPresent) {
+ DreamService.setDreamOverlayComponent(intent, FAKE_DREAM_OVERLAY_COMPONENT);
+ }
+
+ mDreamServiceWrapper = IDreamService.Stub.asInterface(mService.onBind(intent));
+
+ if (mOverlayPresent) {
+ // Ensure that the overlay has been bound by the dream.
+ verify(mDreamOverlayConnectionHandler,
+ description("dream did not bind to the dream overlay")).bind();
+ }
+ }
+
+ private void createDreamActivity() throws RemoteException {
+ final IRemoteCallback callback = mock(IRemoteCallback.class);
+ mDreamServiceWrapper.attach(mock(IBinder.class), false, false, callback);
+ mTestableLooper.processAllMessages();
+
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mDreamManager,
+ description("dream manager was not informed to start the dream activity"))
+ .startDreamActivity(intentCaptor.capture());
+ final Intent intent = intentCaptor.getValue();
+
+ final DreamService.DreamActivityCallbacks dreamActivityCallbacks =
+ DreamActivity.getCallback(intent);
+
+ dreamActivityCallbacks.onActivityCreated(mDreamActivity);
+ }
+
+ private void startDream() throws RemoteException {
+ final ArgumentCaptor<View.OnAttachStateChangeListener> attachChangeListenerCaptor =
+ ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+ verify(mDecorView,
+ description("dream did not add a listener to when the decor view is attached"))
+ .addOnAttachStateChangeListener(attachChangeListenerCaptor.capture());
+
+ resetClientInvocations();
+ attachChangeListenerCaptor.getValue().onViewAttachedToWindow(mDecorView);
+
+ if (mOverlayPresent) {
+ final ArgumentCaptor<IDreamOverlayCallback> overlayCallbackCaptor =
+ ArgumentCaptor.forClass(IDreamOverlayCallback.class);
+ verify(mDreamOverlayClient, description("dream client not informed of dream start"))
+ .startDream(any(), overlayCallbackCaptor.capture(), any(), anyBoolean());
+
+ mDreamOverlayCallback = overlayCallbackCaptor.getValue();
+ }
+ }
+
+ private void wakeDream() throws RemoteException {
+ mService.wakeUp();
+ }
+
+ /**
+ * Retrieves the dream overlay callback.
+ */
+ public IDreamOverlayCallback getDreamOverlayCallback() throws Exception {
+ advance(DREAM_STATE_STARTED);
+ return mDreamOverlayCallback;
+ }
+
+ /**
+ * Resets interactions with the dream overlay client.
+ */
+ public void resetClientInvocations() {
+ Mockito.clearInvocations(mDreamOverlayClient);
+ }
+
+ /**
+ * Retrieves the dream overlay client.
+ */
+ public IDreamOverlayClient getDreamOverlayClient() {
+ return mDreamOverlayClient;
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 9590783..cc69c1d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -245,9 +245,11 @@
LocalServices.removeServiceForTest(PackageManagerInternal.class);
}
+ @SuppressWarnings("GuardedBy")
@After
public void tearDown() {
sService.mOomAdjuster.resetInternal();
+ sService.mOomAdjuster.mActiveUids.clear();
}
private static <T> void setFieldValue(Class clazz, Object obj, String fieldName, T val) {
@@ -2816,6 +2818,69 @@
SCHED_GROUP_DEFAULT);
}
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testSetUidTempAllowlistState() {
+ final ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+ setProcessesToLru(app, app2);
+
+ // App1 binds to app2 and gets temp allowlisted.
+ bindService(app2, app, null, null, 0, mock(IBinder.class));
+ sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP_UID, true);
+
+ assertEquals(true, app.getUidRecord().isSetAllowListed());
+ assertEquals(true, app.mOptRecord.shouldNotFreeze());
+ assertEquals(true, app2.mOptRecord.shouldNotFreeze());
+
+ sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP_UID, false);
+ assertEquals(false, app.getUidRecord().isSetAllowListed());
+ assertEquals(false, app.mOptRecord.shouldNotFreeze());
+ assertEquals(false, app2.mOptRecord.shouldNotFreeze());
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testSetUidTempAllowlistState_multipleAllowlistClients() {
+ final ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+ final ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
+ MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
+ setProcessesToLru(app, app2, app3);
+
+ // App1 and app2 both bind to app3 and get temp allowlisted.
+ bindService(app3, app, null, null, 0, mock(IBinder.class));
+ bindService(app3, app2, null, null, 0, mock(IBinder.class));
+ sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP_UID, true);
+ sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP2_UID, true);
+
+ assertEquals(true, app.getUidRecord().isSetAllowListed());
+ assertEquals(true, app2.getUidRecord().isSetAllowListed());
+ assertEquals(true, app.mOptRecord.shouldNotFreeze());
+ assertEquals(true, app2.mOptRecord.shouldNotFreeze());
+ assertEquals(true, app3.mOptRecord.shouldNotFreeze());
+
+ // Remove app1 from allowlist.
+ sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP_UID, false);
+ assertEquals(false, app.getUidRecord().isSetAllowListed());
+ assertEquals(true, app2.getUidRecord().isSetAllowListed());
+ assertEquals(false, app.mOptRecord.shouldNotFreeze());
+ assertEquals(true, app2.mOptRecord.shouldNotFreeze());
+ assertEquals(true, app3.mOptRecord.shouldNotFreeze());
+
+ // Now remove app2 from allowlist.
+ sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP2_UID, false);
+ assertEquals(false, app.getUidRecord().isSetAllowListed());
+ assertEquals(false, app2.getUidRecord().isSetAllowListed());
+ assertEquals(false, app.mOptRecord.shouldNotFreeze());
+ assertEquals(false, app2.mOptRecord.shouldNotFreeze());
+ assertEquals(false, app3.mOptRecord.shouldNotFreeze());
+ }
+
private ProcessRecord makeDefaultProcessRecord(int pid, int uid, String processName,
String packageName, boolean hasShownUi) {
return new ProcessRecordBuilder(pid, uid, processName, packageName).setHasShownUi(
@@ -3057,6 +3122,14 @@
receivers.addCurReceiver(mock(BroadcastRecord.class));
}
providers.setLastProviderTime(mLastProviderTime);
+
+ UidRecord uidRec = sService.mOomAdjuster.mActiveUids.get(mUid);
+ if (uidRec == null) {
+ uidRec = new UidRecord(mUid, sService);
+ sService.mOomAdjuster.mActiveUids.put(mUid, uidRec);
+ }
+ uidRec.addProcess(app);
+ app.setUidRecord(uidRec);
return app;
}
}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java
index d51828e..4e3e80f 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java
@@ -341,7 +341,7 @@
}}, 0, 1234);
mMockClock.uptime = 1000;
- collector.forceSchedule();
+ collector.schedule();
waitForIdle();
mUidResolver.noteIsolatedUidRemoved(ISOLATED_UID, UID_2);
@@ -354,7 +354,7 @@
}}, 1234, 3421);
mMockClock.uptime = 2000;
- collector.forceSchedule();
+ collector.schedule();
waitForIdle();
assertThat(layout.getUidTimeByPowerBracket(mCollectedStats.uidStats.get(UID_2), 0))
diff --git a/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java b/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java
index 44d1161..06c3db8 100644
--- a/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java
+++ b/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java
@@ -136,8 +136,14 @@
this(helper.mHandler, MSG_TIMEOUT, caller());
}
- void start(TestArg arg, long millis) {
- start(arg, arg.pid, arg.uid, millis);
+ @Override
+ public int getPid(TestArg arg) {
+ return arg.pid;
+ }
+
+ @Override
+ public int getUid(TestArg arg) {
+ return arg.uid;
}
// Return the name of method that called the constructor, assuming that this function is
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index dcf3dad..7756edd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -832,7 +832,8 @@
// Assume the task is at the topmost position
assertFalse(rootTask.isTopRootTaskInDisplayArea());
- doReturn(taskDisplayArea.getHomeActivity()).when(taskDisplayArea).topRunningActivity();
+ doReturn(taskDisplayArea.getHomeActivity()).when(taskDisplayArea).topRunningActivity(
+ anyBoolean());
// Use the task as target to resume.
mRootWindowContainer.resumeFocusedTasksTopActivities();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 43b424f..fb854c5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -1235,6 +1235,12 @@
assertNotNull(o.mInfo);
assertNotNull(o.mInfo.pictureInPictureParams);
+ // Bypass the quota check, which causes NPE in current test setup.
+ if (mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker != null) {
+ mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker
+ .setEnabled(false);
+ }
+
final PictureInPictureParams p2 = new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(3, 4)).build();
mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2);
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index b005715..40ad312 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -959,6 +959,11 @@
*/
public static final int SATELLITE_MODEM_STATE_ENABLING_SATELLITE = 8;
/**
+ * The satellite modem is being powered off.
+ * @hide
+ */
+ public static final int SATELLITE_MODEM_STATE_DISABLING_SATELLITE = 9;
+ /**
* Satellite modem state is unknown. This generic modem state should be used only when the
* modem state cannot be mapped to other specific modem states.
*/
@@ -976,6 +981,7 @@
SATELLITE_MODEM_STATE_NOT_CONNECTED,
SATELLITE_MODEM_STATE_CONNECTED,
SATELLITE_MODEM_STATE_ENABLING_SATELLITE,
+ SATELLITE_MODEM_STATE_DISABLING_SATELLITE,
SATELLITE_MODEM_STATE_UNKNOWN
})
@Retention(RetentionPolicy.SOURCE)
diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
index 063088d..03f3a68 100644
--- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
+++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
@@ -50,7 +50,7 @@
testApp.launchViaIntent(wmHelper)
testApp.openIME(wmHelper)
this.setRotation(flicker.scenario.startRotation)
- if (flicker.scenario.isTablet) {
+ if (flicker.scenario.isTablet && tapl.isTransientTaskbar()) {
tapl.launchedAppState.swipeUpToUnstashTaskbar()
}
tapl.launchedAppState.switchToOverview()
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index 994adc9..4c81939 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -227,56 +227,3 @@
],
},
}
-
-cc_genrule {
- name: "aapt2_results",
- srcs: [
- ":aapt2_tests",
- "integration-tests/CompileTest/**/*",
- "integration-tests/CommandTests/**/*",
- "integration-tests/ConvertTest/**/*",
- "integration-tests/DumpTest/**/*",
- ],
- host_supported: true,
- device_supported: false,
- target: {
- windows: {
- compile_multilib: "64",
- },
- },
- out: ["result.xml"],
- cmd: "mkdir -p $(genDir)/integration-tests/CompileTest/ && " +
- "cp $(locations integration-tests/CompileTest/**/*) $(genDir)/integration-tests/CompileTest/ && " +
- "mkdir -p $(genDir)/integration-tests/CommandTests/ && " +
- "cp $(locations integration-tests/CommandTests/**/*) $(genDir)/integration-tests/CommandTests/ && " +
- "mkdir -p $(genDir)/integration-tests/ConvertTest/ && " +
- "cp $(locations integration-tests/ConvertTest/**/*) $(genDir)/integration-tests/ConvertTest/ && " +
- "mkdir -p $(genDir)/integration-tests/DumpTest/ && " +
- "cp $(locations integration-tests/DumpTest/**/*) $(genDir)/integration-tests/DumpTest/ && " +
- "cp $(locations :aapt2_tests) $(genDir)/ && " +
- "$(genDir)/aapt2_tests " +
- "--gtest_output=xml:$(out) " +
- ">/dev/null 2>&1 ; true",
- dist: {
- targets: ["aapt2_run_host_unit_tests"],
- dir: "gtest",
- dest: "aapt2_host_unit_tests_result.xml",
- },
- arch: {
- x86: {
- dist: {
- suffix: "_x86",
- },
- },
- x86_64: {
- dist: {
- suffix: "_x86_64",
- },
- },
- },
-}
-
-phony_rule {
- name: "aapt2_run_host_unit_tests",
- phony_deps: ["aapt2_results"],
-}
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index dc18b1c..8fe414f 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -335,6 +335,11 @@
"are separated by ',' and the name is separated from the value by '='.\n"
"Example: \"flag1=true,flag2=false,flag3=\" (flag3 has no given value).",
&feature_flags_args_);
+ AddOptionalSwitch("--non-updatable-system",
+ "Mark the app as a non-updatable system app. This inserts\n"
+ "updatableSystem=\"false\" to the root manifest node, overwriting any\n"
+ "existing attribute. This is ignored if the manifest has a versionCode.",
+ &options_.manifest_fixer_options.non_updatable_system);
}
int Action(const std::vector<std::string>& args) override;
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index d03f97e..f1e4ead 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -489,6 +489,16 @@
}
}
+ if (options_.non_updatable_system) {
+ if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) {
+ el->RemoveAttribute("", "updatableSystem");
+ el->attributes.push_back(xml::Attribute{"", "updatableSystem", "false"});
+ } else {
+ diag->Note(android::DiagMessage(el->line_number)
+ << "Ignoring --non-updatable-system because the manifest has a versionCode");
+ }
+ }
+
return true;
});
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index 42938a4..df0ece6 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -91,6 +91,11 @@
// Whether to suppress `android:compileSdkVersion*` and `platformBuildVersion*` attributes.
bool no_compile_sdk_metadata = false;
+
+ // Whether to mark the app as a non-updatable system app. This adds `updatableSystem="false"` to
+ // the <manifest> tag. Not used if a version code is set either explicitly in the manifest or
+ // through version_code_default.
+ bool non_updatable_system = false;
};
// Verifies that the manifest is correctly formed and inserts defaults where specified with
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 6151a8e..3cfdf78 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -677,6 +677,83 @@
EXPECT_THAT(attr->value, StrEq("0x00000002"));
}
+TEST_F(ManifestFixerTest, MarkNonUpdatableSystem) {
+ ManifestFixerOptions options;
+ options.non_updatable_system = true;
+
+ std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android" />)EOF",
+ options);
+ ASSERT_THAT(doc, NotNull());
+
+ xml::Element* manifest_el = doc->root.get();
+ ASSERT_THAT(manifest_el, NotNull());
+
+ xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("false"));
+}
+
+TEST_F(ManifestFixerTest, MarkNonUpdatableSystemOverwritingValue) {
+ ManifestFixerOptions options;
+ options.non_updatable_system = true;
+
+ std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ updatableSystem="true" />)EOF",
+ options);
+ ASSERT_THAT(doc, NotNull());
+
+ xml::Element* manifest_el = doc->root.get();
+ ASSERT_THAT(manifest_el, NotNull());
+
+ xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("false"));
+}
+
+TEST_F(ManifestFixerTest, DontMarkNonUpdatableSystemWhenExplicitVersion) {
+ ManifestFixerOptions options;
+ options.non_updatable_system = true;
+
+ std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x00000001" />)EOF",
+ options);
+ ASSERT_THAT(doc, NotNull());
+
+ xml::Element* manifest_el = doc->root.get();
+ ASSERT_THAT(manifest_el, NotNull());
+
+ xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem");
+ ASSERT_THAT(attr, IsNull());
+}
+
+TEST_F(ManifestFixerTest, DontMarkNonUpdatableSystemWhenAddedVersion) {
+ ManifestFixerOptions options;
+ options.non_updatable_system = true;
+ options.version_code_default = std::string("0x10000000");
+
+ std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android" />)EOF",
+ options);
+ ASSERT_THAT(doc, NotNull());
+
+ xml::Element* manifest_el = doc->root.get();
+ ASSERT_THAT(manifest_el, NotNull());
+
+ xml::Attribute* attr = manifest_el->FindAttribute("", "updatableSystem");
+ ASSERT_THAT(attr, IsNull());
+
+ attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("0x10000000"));
+}
+
TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull());
EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull());
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
index 76bac92..16785d1 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
@@ -51,6 +51,8 @@
}
/**
+ * Effectively apply @RavenwoodKeepWholeClass to all classes with these names
+ *
* @return if a given class "seems like" an feature flags class.
*/
private fun ClassNodes.isFeatureFlagsClass(className: String): Boolean {
@@ -59,6 +61,7 @@
return className.endsWith("/Flags")
|| className.endsWith("/FeatureFlags")
|| className.endsWith("/FeatureFlagsImpl")
+ || className.endsWith("/CustomFeatureFlags")
|| className.endsWith("/FakeFeatureFlagsImpl");
}