diff options
387 files changed, 6426 insertions, 2387 deletions
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 be4b7205fea4..d52c4ce8a9df 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.AppSchedulingModuleThread; 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 @@ public final class TimeController extends StateController { 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 @@ public final class TimeController extends StateController { } } - 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 @@ public final class TimeController extends StateController { 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 dd681ca09723..adce203e1140 100644 --- a/config/Android.bp +++ b/config/Android.bp @@ -29,6 +29,13 @@ license { ], } +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 dd6bc55421ef..b9906bf3d668 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -84,6 +84,7 @@ import android.content.pm.parsing.ApkLiteParseUtils; 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.system.StructStat; 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 dalvik.system.VMRuntime; 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 @@ public class ApplicationPackageManager extends PackageManager { } } } + + @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/admin/EnterprisePlatform_OWNERS b/core/java/android/app/admin/EnterprisePlatform_OWNERS index 4d1ed59039d0..9da526f152c2 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 cae4fab0099c..495ae6026805 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -2700,7 +2700,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** * @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 ff48ffafba8a..4d9ecc40228b 100644 --- a/core/java/android/content/pm/ComponentInfo.java +++ b/core/java/android/content/pm/ComponentInfo.java @@ -284,7 +284,7 @@ public class ComponentInfo extends PackageItemInfo { /** * @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 1f821b9c4255..51285decbade 100644 --- a/core/java/android/content/pm/PackageItemInfo.java +++ b/core/java/android/content/pm/PackageItemInfo.java @@ -511,7 +511,7 @@ public class PackageItemInfo { * * @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 f5bff9dc1d0e..83285e0b8e8b 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.dex.ArtManager; 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 @@ public abstract class PackageManager { 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/hardware/biometrics/BiometricFaceConstants.java b/core/java/android/hardware/biometrics/BiometricFaceConstants.java index 2ba1d897fe34..ac47c8d6007b 100644 --- a/core/java/android/hardware/biometrics/BiometricFaceConstants.java +++ b/core/java/android/hardware/biometrics/BiometricFaceConstants.java @@ -34,7 +34,7 @@ import java.lang.annotation.RetentionPolicy; * * @hide */ -public interface BiometricFaceConstants { +public class BiometricFaceConstants { // // Accessibility constants // @@ -43,12 +43,12 @@ public interface BiometricFaceConstants { * 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 @@ public interface BiometricFaceConstants { 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 @@ public interface BiometricFaceConstants { * 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 @@ public interface BiometricFaceConstants { * 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 @@ public interface BiometricFaceConstants { 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 @@ public interface BiometricFaceConstants { * 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 @@ public interface BiometricFaceConstants { * 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 @@ public interface BiometricFaceConstants { * 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 @@ public interface BiometricFaceConstants { * * 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 @@ public interface BiometricFaceConstants { * * 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 @@ public interface BiometricFaceConstants { * * 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 @@ public interface BiometricFaceConstants { * 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 @@ public interface BiometricFaceConstants { * 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 2592630c80d2..d340f3ff70bb 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.INTERACT_ACROSS_USERS; 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.Context; 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 @@ import java.util.List; * @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 02e787b5256c..51758aa32102 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -43,6 +43,13 @@ flag { } 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 a3892238f1e6..7487d901baf5 100644 --- a/core/java/android/service/dreams/DreamActivity.java +++ b/core/java/android/service/dreams/DreamActivity.java @@ -18,9 +18,12 @@ package android.service.dreams; 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 @@ import android.text.TextUtils; * * @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 class DreamActivity extends Activity { 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 cafe02ad8658..85a13c796ee2 100644 --- a/core/java/android/service/dreams/DreamOverlayConnectionHandler.java +++ b/core/java/android/service/dreams/DreamOverlayConnectionHandler.java @@ -39,7 +39,7 @@ import java.util.function.Consumer; * * @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 5da0cb48ad1f..17d2790eac96 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 @@ public abstract class DreamOverlayService extends Service { 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 @@ public abstract class DreamOverlayService extends Service { } } + 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 @@ public abstract class DreamOverlayService extends Service { 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 c26d83c4853d..997c958187fe 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.PackageManager; 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.RemoteException; 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.WindowManager.LayoutParams; 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 @@ public class DreamService extends Service implements Window.Callback { "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 @@ public class DreamService extends Service implements Window.Callback { * The default value for dream category * @hide */ + @VisibleForTesting public static final int DREAM_CATEGORY_DEFAULT = 0; /** @@ -253,8 +241,14 @@ public class DreamService extends Service implements Window.Callback { @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 @@ public class DreamService extends Service implements Window.Callback { 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 class DreamService extends Service implements Window.Callback { 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 @@ public class DreamService extends Service implements Window.Callback { // 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 @@ public class DreamService extends Service implements Window.Callback { + ", 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 @@ public class DreamService extends Service implements Window.Callback { @TestApi public static DreamMetadata getDreamMetadata(@NonNull Context context, @Nullable ServiceInfo serviceInfo) { - if (serviceInfo == null) return null; + return getDreamMetadata(context.getPackageManager(), serviceInfo); + } - final PackageManager pm = context.getPackageManager(); + /** + * 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; - 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 @@ public class DreamService extends Service implements Window.Callback { } } - /** - * 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 @@ public class DreamService extends Service implements Window.Callback { // 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 @@ public class DreamService extends Service implements Window.Callback { * 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 @@ public class DreamService extends Service implements Window.Callback { } @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 @@ public class DreamService extends Service implements Window.Callback { } /** @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 @@ public class DreamService extends Service implements Window.Callback { 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 @@ public class DreamService extends Service implements Window.Callback { * * @hide */ + @VisibleForTesting @TestApi public static final class DreamMetadata { @Nullable @@ -1700,7 +1800,11 @@ public class DreamService extends Service implements Window.Callback { @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 @@ public class DreamService extends Service implements Window.Callback { } } } + + /** + * 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 ec76a334d5b2..fae47806ff45 100644 --- a/core/java/android/service/dreams/IDreamOverlayCallback.aidl +++ b/core/java/android/service/dreams/IDreamOverlayCallback.aidl @@ -23,9 +23,14 @@ package android.service.dreams; * * @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 5054d4d749d3..0eb15a07edf7 100644 --- a/core/java/android/service/dreams/IDreamOverlayClient.aidl +++ b/core/java/android/service/dreams/IDreamOverlayClient.aidl @@ -43,6 +43,9 @@ interface IDreamOverlayClient { /** 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 0a458bccc83c..f87cb85f94b7 100644 --- a/core/java/android/service/dreams/flags.aconfig +++ b/core/java/android/service/dreams/flags.aconfig @@ -21,6 +21,14 @@ flag { } 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 c50c384c6e4d..74428aa10586 100644 --- a/core/java/android/tracing/flags.aconfig +++ b/core/java/android/tracing/flags.aconfig @@ -22,3 +22,11 @@ flag { 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 510a4a376eb3..e7c1885e7ba9 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2430,12 +2430,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, 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 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @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 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @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 class View implements Drawable.Callback, KeyEvent.Callback, */ 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 class View implements Drawable.Callback, KeyEvent.Callback, */ 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 class View implements Drawable.Callback, KeyEvent.Callback, */ public void offsetLeftAndRight(int offset) { if (offset != 0) { - mPrivateFlags4 |= PFLAG4_HAS_MOVED; final boolean matrixIsIdentity = hasIdentityMatrix(); if (matrixIsIdentity) { if (isHardwareAccelerated()) { @@ -25523,7 +25524,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { - mPrivateFlags4 |= PFLAG4_HAS_MOVED; changed = true; // Remember our drawn bit @@ -33976,8 +33976,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // 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) { @@ -33990,14 +33991,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, 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 ) { @@ -34062,6 +34066,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, 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 701b2d3f506a..2cb862cce4ac 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_FIXED_SOURCE; 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 @@ public final class ViewRootImpl implements ViewParent, // 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, case MSG_FRAME_RATE_SETTING: mPreferredFrameRate = 0; mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; - setPreferredFrameRate(mPreferredFrameRate); break; } } @@ -12649,7 +12613,6 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, mFrameRateCategoryChangeReason = reason; // mFrameRateCategoryView = view == null ? "-" : view.getClass().getSimpleName(); } - mHasInvalidation = true; mDrawnThisFrame = true; } @@ -12792,7 +12754,6 @@ public final class ViewRootImpl implements ViewParent, mFrameRateCategoryHighCount = FRAME_RATE_CATEGORY_COUNT; mFrameRateCategoryChangeReason = FRAME_RATE_CATEGORY_REASON_VELOCITY; mFrameRateCategoryView = null; - mHasInvalidation = true; mDrawnThisFrame = true; return; } @@ -12824,7 +12785,6 @@ public final class ViewRootImpl implements ViewParent, mPreferredFrameRate = nextFrameRate; mFrameRateCompatibility = nextFrameRateCompatibility; - mHasInvalidation = true; mDrawnThisFrame = true; } @@ -12944,19 +12904,8 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 4f5544172edf..d72207d9b9ef 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -272,6 +272,7 @@ public class IntentForwarderActivity extends Activity { 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 @@ public class IntentForwarderActivity extends Activity { 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 @@ public class IntentForwarderActivity extends Activity { ((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/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java index 6ff546fd77f8..ded142ce49e5 100644 --- a/core/java/com/android/internal/compat/ChangeReporter.java +++ b/core/java/com/android/internal/compat/ChangeReporter.java @@ -18,22 +18,24 @@ package com.android.internal.compat; import static android.text.TextUtils.formatSimple; +import static java.util.Collections.EMPTY_SET; + import android.annotation.IntDef; import android.util.Log; import android.util.Slog; -import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.compat.flags.Flags; import com.android.internal.util.FrameworkStatsLog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.HashMap; +import java.util.Collections; import java.util.HashSet; -import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; /** * A helper class to report changes to stats log. @@ -42,6 +44,8 @@ import java.util.Set; */ public final class ChangeReporter { private static final String TAG = "CompatChangeReporter"; + private static final Function<Integer, Set<ChangeReport>> NEW_CHANGE_REPORT_SET = + uid -> Collections.synchronizedSet(new HashSet<>()); private int mSource; private static final class ChangeReport { @@ -69,15 +73,14 @@ public final class ChangeReporter { } // Maps uid to a set of ChangeReports (that were reported for that uid). - @GuardedBy("mReportedChanges") - private final Map<Integer, Set<ChangeReport>> mReportedChanges; + private final ConcurrentHashMap<Integer, Set<ChangeReport>> mReportedChanges; // When true will of every time to debug (logcat). private boolean mDebugLogAll; public ChangeReporter(@Source int source) { mSource = source; - mReportedChanges = new HashMap<>(); + mReportedChanges = new ConcurrentHashMap<>(); mDebugLogAll = false; } @@ -93,14 +96,15 @@ public final class ChangeReporter { * actually log. If the sdk version does not matter, should be true. */ public void reportChange(int uid, long changeId, int state, boolean isLoggableBySdk) { - if (shouldWriteToStatsLog(uid, changeId, state)) { + boolean isAlreadyReported = + checkAndSetIsAlreadyReported(uid, new ChangeReport(changeId, state)); + if (!isAlreadyReported) { FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId, state, mSource); } - if (shouldWriteToDebug(uid, changeId, state, isLoggableBySdk)) { + if (shouldWriteToDebug(isAlreadyReported, state, isLoggableBySdk)) { debugLog(uid, changeId, state); } - markAsReported(uid, new ChangeReport(changeId, state)); } /** @@ -129,7 +133,6 @@ public final class ChangeReporter { mDebugLogAll = false; } - /** * Returns whether the next report should be logged to FrameworkStatsLog. * @@ -139,28 +142,26 @@ public final class ChangeReporter { * @return true if the report should be logged */ @VisibleForTesting - public boolean shouldWriteToStatsLog(int uid, long changeId, int state) { + boolean shouldWriteToStatsLog(int uid, long changeId, int state) { return !isAlreadyReported(uid, new ChangeReport(changeId, state)); } /** * Returns whether the next report should be logged to logcat. * - * @param uid affected by the change - * @param changeId the reported change id - * @param state of the reported change - enabled/disabled/only logged - * @param isLoggableBySdk whether debug logging is allowed for this change based on target - * SDK version. This is combined with other logic to determine whether to - * actually log. If the sdk version does not matter, should be true. + * @param isAlreadyReported is the change already reported + * @param state of the reported change - enabled/disabled/only logged + * @param isLoggableBySdk whether debug logging is allowed for this change based on target SDK + * version. This is combined with other logic to determine whether to + * actually log. If the sdk version does not matter, should be true. * @return true if the report should be logged */ - @VisibleForTesting - public boolean shouldWriteToDebug( - int uid, long changeId, int state, boolean isLoggableBySdk) { + private boolean shouldWriteToDebug( + boolean isAlreadyReported, int state, boolean isLoggableBySdk) { // If log all bit is on, always return true. if (mDebugLogAll) return true; // If the change has already been reported, do not write. - if (isAlreadyReported(uid, new ChangeReport(changeId, state))) return false; + if (isAlreadyReported) return false; // If the flag is turned off or the TAG's logging is forced to debug level with // `adb setprop log.tag.CompatChangeReporter=DEBUG`, write to debug since the above checks @@ -178,33 +179,53 @@ public final class ChangeReporter { * @param uid affected by the change * @param changeId the reported change id * @param state of the reported change - enabled/disabled/only logged + * * @return true if the report should be logged */ @VisibleForTesting - public boolean shouldWriteToDebug(int uid, long changeId, int state) { + boolean shouldWriteToDebug(int uid, long changeId, int state) { return shouldWriteToDebug(uid, changeId, state, true); } - private boolean isAlreadyReported(int uid, ChangeReport report) { - synchronized (mReportedChanges) { - Set<ChangeReport> reportedChangesForUid = mReportedChanges.get(uid); - if (reportedChangesForUid == null) { - return false; - } else { - return reportedChangesForUid.contains(report); - } + /** + * Returns whether the next report should be logged to logcat. + * + * @param uid affected by the change + * @param changeId the reported change id + * @param state of the reported change - enabled/disabled/only logged + * @param isLoggableBySdk whether debug logging is allowed for this change based on target SDK + * version. This is combined with other logic to determine whether to + * actually log. If the sdk version does not matter, should be true. + * @return true if the report should be logged + */ + @VisibleForTesting + boolean shouldWriteToDebug(int uid, long changeId, int state, boolean isLoggableBySdk) { + return shouldWriteToDebug( + isAlreadyReported(uid, new ChangeReport(changeId, state)), state, isLoggableBySdk); + } + + /** + * Return if change has been reported. Also mark change as reported if not. + * + * @param uid affected by the change + * @param changeReport change reported to be checked and marked as reported. + * + * @return true if change has been reported, and vice versa. + */ + private boolean checkAndSetIsAlreadyReported(int uid, ChangeReport changeReport) { + boolean isAlreadyReported = isAlreadyReported(uid, changeReport); + if (!isAlreadyReported) { + markAsReported(uid, changeReport); } + return isAlreadyReported; + } + + private boolean isAlreadyReported(int uid, ChangeReport report) { + return mReportedChanges.getOrDefault(uid, EMPTY_SET).contains(report); } private void markAsReported(int uid, ChangeReport report) { - synchronized (mReportedChanges) { - Set<ChangeReport> reportedChangesForUid = mReportedChanges.get(uid); - if (reportedChangesForUid == null) { - mReportedChanges.put(uid, new HashSet<ChangeReport>()); - reportedChangesForUid = mReportedChanges.get(uid); - } - reportedChangesForUid.add(report); - } + mReportedChanges.computeIfAbsent(uid, NEW_CHANGE_REPORT_SET).add(report); } /** @@ -216,9 +237,7 @@ public final class ChangeReporter { * @param uid to reset */ public void resetReportedChanges(int uid) { - synchronized (mReportedChanges) { - mReportedChanges.remove(uid); - } + mReportedChanges.remove(uid); } private void debugLog(int uid, long changeId, int state) { @@ -229,7 +248,6 @@ public final class ChangeReporter { } else { Log.d(TAG, message); } - } /** diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java index 5705b7ea5cf2..7ac553c56bf7 100644 --- a/core/java/com/android/internal/content/PackageMonitor.java +++ b/core/java/com/android/internal/content/PackageMonitor.java @@ -48,8 +48,6 @@ import java.util.concurrent.Executor; 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 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { 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 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { (thread == null) ? BackgroundThread.getHandler() : new Handler(thread)); } - /** * Register for notifications of package changes such as install, removal and other events. */ @@ -101,10 +113,13 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { } 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 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { 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 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { * @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 9dec1027d398..2f09a5550fd4 100644 --- a/core/java/com/android/internal/policy/TransitionAnimation.java +++ b/core/java/com/android/internal/policy/TransitionAnimation.java @@ -1340,35 +1340,39 @@ public class TransitionAnimation { 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/widget/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java index 18d5f6db6ac9..54b9a225f944 100644 --- a/core/java/com/android/internal/widget/LockscreenCredential.java +++ b/core/java/com/android/internal/widget/LockscreenCredential.java @@ -386,6 +386,11 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { } @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/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto index d31baf33eaf7..e3a438da5abc 100644 --- a/core/proto/android/server/activitymanagerservice.proto +++ b/core/proto/android/server/activitymanagerservice.proto @@ -1059,6 +1059,7 @@ message AppsStartInfoProto { 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 9151958e2b94..1d9b0db3218b 100644 --- a/core/proto/android/server/vibrator/vibratormanagerservice.proto +++ b/core/proto/android/server/vibrator/vibratormanagerservice.proto @@ -116,7 +116,7 @@ message VibrationProto { 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 @@ message VibrationProto { 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 @@ message VibrationProto { 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 389e08785133..e2106c53f565 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -298,9 +298,6 @@ <protected-broadcast android:name="android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED" /> - <protected-broadcast android:name="android.hardware.hdmi.action.OSD_MESSAGE" /> - <protected-broadcast android:name="android.hardware.hdmi.action.ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI" /> - <protected-broadcast android:name="android.hardware.usb.action.USB_STATE" /> <protected-broadcast android:name="android.hardware.usb.action.USB_PORT_CHANGED" /> <protected-broadcast android:name="android.hardware.usb.action.USB_PORT_COMPLIANCE_CHANGED" /> @@ -6203,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/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 8218ff1fb671..dbf09ee9ed0c 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 5a7919779fe5..8a2fb4a76edf 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 0ee66fc92ff6..484e6f018a44 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 48ebcadb6df9..aafbb39b5255 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 fef6fa616ab3..f7b903fa9ce0 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 ae1da1630552..0122a2c16ad1 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 71b59037ce6e..15ac935cdf6d 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 25d6c1828f19..78e4f3275fe3 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 953bfbd2d67e..d524aacb0306 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 ba2c5e5f3cca..5f487410c892 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 b1000161f5c0..1e50e924df66 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 aa87f24a0b76..2a214782e7a7 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 f94ebac5b421..a3d71d938597 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 f393074f3dfd..9eb691fd2282 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 33cde13dc541..84598edde367 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 acf22669b1a7..d6880359a58f 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 b304edc7870b..2692d06f4043 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 00b79b65f013..2cc0590c46ae 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 5f6cd389ef41..2ef91cdee31d 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 ec928129427b..0d48bbb678e4 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 12adb1720af8..1ffde6f7bd72 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 230e701d5e54..30e4ecaa2453 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 5de328731789..f59d2aec4087 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 6f186ff6be70..9c41d7306af5 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 a6937d25cf2c..ab403414a0d3 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 4772ff8d1a62..4d61bddf3ca3 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 6768e2967cba..569eb35a166c 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 1c65e61b2bf7..eb1e45346149 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 423cf8846271..3c8230720a7d 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 a248edea375c..cc02a7e377c5 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/strings.xml b/core/res/res/values/strings.xml index 2f9f4df556d0..4ea97a508fda 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 90132c37025d..e304027c0b91 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 9bb064c447b8..62d89f6dc846 100644 --- a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java +++ b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java @@ -19,10 +19,20 @@ package android.app; 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 com.android.internal.annotations.VisibleForTesting; 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 @@ public class ApplicationPackageManagerTest extends TestCase { 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 @@ public class ApplicationPackageManagerTest extends TestCase { 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 @@ public class ApplicationPackageManagerTest extends TestCase { 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 @@ public class ApplicationPackageManagerTest extends TestCase { 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 4cdc993ead21..c4ac98b8abf7 100644 --- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java +++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java @@ -19,6 +19,7 @@ package android.view; 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,80 @@ public class ViewFrameRateTest { 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 36bede96c1b9..852d696f3e13 100644 --- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java +++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java @@ -34,6 +34,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; 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 @@ public class WindowOnBackInvokedDispatcherTest { 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 @@ public class WindowOnBackInvokedDispatcherTest { 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 9cb91229ce58..03cb17e9087f 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 com.google.common.truth.Truth.assertThat; 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 @@ public class PackageMonitorTest { } @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 class PackageMonitorTest { } 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 46a3e7f38bed..89d3058cc14d 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.Bundle; 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 @@ import java.util.function.BiConsumer; 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/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java index 25dc25e176d7..30eb8b5d2f05 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java @@ -18,6 +18,7 @@ package com.android.wm.shell.common.split; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; +import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; @@ -133,8 +134,7 @@ public class SplitDecorManager extends WindowlessWindowManager { lp.token = new Binder(); lp.setTitle(TAG); lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY; - // TODO(b/189839391): Set INPUT_FEATURE_NO_INPUT_CHANNEL after WM supports - // TRUSTED_OVERLAY for windowless window without input channel. + lp.inputFeatures |= INPUT_FEATURE_NO_INPUT_CHANNEL; mViewHost.setView(rootLayout, lp); } 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 c6b127d5f96e..9b2922dff2f5 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 static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SH 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 @@ public class Transitions implements RemoteCallable<Transitions>, 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 @@ public class Transitions implements RemoteCallable<Transitions>, } } } + + 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/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java index 43fd32ba1750..6671391efdeb 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 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL 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 6a9d17fef928..922c55f49a33 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 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { 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 da1699cd6e33..cb6495c6af38 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.Rect; 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.MotionEvent; import android.view.SurfaceControl; import android.view.View; import android.view.ViewConfiguration; +import android.view.WindowManager; import android.widget.ImageButton; import android.window.WindowContainerTransaction; @@ -107,8 +109,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private MaximizeMenu mMaximizeMenu; private ResizeVeil mResizeVeil; - - private Drawable mAppIconDrawable; private Bitmap mAppIconBitmap; private CharSequence mAppName; @@ -160,7 +160,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mSyncQueue = syncQueue; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; + Trace.beginSection("DesktopModeWindowDecoration#loadAppInfo"); loadAppInfo(); + Trace.endSection(); } void setCaptionListeners( @@ -206,6 +208,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin void relayout(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT, boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) { + Trace.beginSection("DesktopModeWindowDecoration#relayout"); if (isHandleMenuActive()) { mHandleMenu.relayout(startT); } @@ -217,16 +220,22 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin 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( @@ -254,7 +263,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin throw new IllegalArgumentException("Unexpected layout resource id"); } } + Trace.beginSection("DesktopModeWindowDecoration#relayout-binding"); mWindowDecorViewHolder.bindData(mTaskInfo); + Trace.endSection(); if (!mTaskInfo.isFocused) { closeHandleMenu(); @@ -270,11 +281,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin updateExclusionRegion(); } closeDragResizeListener(); + Trace.endSection(); // DesktopModeWindowDecoration#relayout return; } if (oldDecorationSurface != mDecorationContainerSurface || mDragResizeListener == null) { closeDragResizeListener(); + Trace.beginSection("DesktopModeWindowDecoration#relayout-DragResizeInputListener"); mDragResizeListener = new DragResizeInputListener( mContext, mHandler, @@ -285,6 +298,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mSurfaceControlBuilderSupplier, mSurfaceControlTransactionSupplier, mDisplayController); + Trace.endSection(); } final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext()) @@ -309,6 +323,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mMaximizeMenu.positionMenu(calculateMaximizeMenuPosition(), startT); } } + Trace.endSection(); // DesktopModeWindowDecoration#relayout } @VisibleForTesting @@ -326,11 +341,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin 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). @@ -345,6 +361,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin 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 @@ -444,12 +465,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin } PackageManager pm = mContext.getApplicationContext().getPackageManager(); final IconProvider provider = new IconProvider(mContext); - mAppIconDrawable = provider.getIcon(activityInfo); + final Drawable appIconDrawable = provider.getIcon(activityInfo); final Resources resources = mContext.getResources(); final BaseIconFactory factory = new BaseIconFactory(mContext, resources.getDisplayMetrics().densityDpi, resources.getDimensionPixelSize(R.dimen.desktop_mode_caption_icon_radius)); - mAppIconBitmap = factory.createScaledBitmap(mAppIconDrawable, MODE_DEFAULT); + mAppIconBitmap = factory.createScaledBitmap(appIconDrawable, MODE_DEFAULT); final ApplicationInfo applicationInfo = activityInfo.applicationInfo; mAppName = pm.getApplicationLabel(applicationInfo); } @@ -466,8 +487,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin * 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() { - mResizeVeil = new ResizeVeil(mContext, mDisplayController, mAppIconDrawable, mTaskInfo, + private void createResizeVeilIfNeeded() { + if (mResizeVeil != null) return; + mResizeVeil = new ResizeVeil(mContext, mDisplayController, mAppIconBitmap, mTaskInfo, mTaskSurface, mSurfaceControlTransactionSupplier); } @@ -475,6 +497,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin * Show the resize veil. */ public void showResizeVeil(Rect taskBounds) { + createResizeVeilIfNeeded(); mResizeVeil.showVeil(mTaskSurface, taskBounds); } @@ -482,6 +505,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin * 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 2c4092ac6d2c..93e2a21c6b02 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 @@ -24,11 +24,12 @@ import android.annotation.NonNull; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.res.Configuration; +import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.drawable.Drawable; +import android.os.Trace; import android.view.Display; import android.view.LayoutInflater; import android.view.SurfaceControl; @@ -64,7 +65,7 @@ public class ResizeVeil { private final SurfaceControlBuilderFactory mSurfaceControlBuilderFactory; private final WindowDecoration.SurfaceControlViewHostFactory mSurfaceControlViewHostFactory; private final SurfaceSession mSurfaceSession = new SurfaceSession(); - private final Drawable mAppIcon; + private final Bitmap mAppIcon; private ImageView mIconView; private int mIconSize; private SurfaceControl mParentSurface; @@ -97,7 +98,7 @@ public class ResizeVeil { public ResizeVeil(Context context, @NonNull DisplayController displayController, - Drawable appIcon, RunningTaskInfo taskInfo, + Bitmap appIcon, RunningTaskInfo taskInfo, SurfaceControl taskSurface, Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) { this(context, @@ -112,7 +113,7 @@ public class ResizeVeil { public ResizeVeil(Context context, @NonNull DisplayController displayController, - Drawable appIcon, RunningTaskInfo taskInfo, + Bitmap appIcon, RunningTaskInfo taskInfo, SurfaceControl taskSurface, Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, SurfaceControlBuilderFactory surfaceControlBuilderFactory, @@ -135,6 +136,7 @@ public class ResizeVeil { // 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() @@ -162,7 +164,7 @@ public class ResizeVeil { final View root = LayoutInflater.from(mContext) .inflate(R.layout.desktop_mode_resize_veil, null /* root */); mIconView = root.findViewById(R.id.veil_application_icon); - mIconView.setImageDrawable(mAppIcon); + mIconView.setImageBitmap(mAppIcon); final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( @@ -179,6 +181,7 @@ public class ResizeVeil { 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 36da1ace8408..54656ffa1e93 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.Point; 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 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> 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 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> 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 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> 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 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> 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 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> } mViewHost.relayout(lp); } + Trace.endSection(); // CaptionViewHostLayout } private Rect calculateBoundingRect(@NonNull OccludingCaptionElement element, @@ -605,7 +604,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> int mCaptionHeightId; int mCaptionWidthId; final List<OccludingCaptionElement> mOccludingCaptionElements = new ArrayList<>(); - boolean mAllowCaptionInputFallthrough; + int mInputFeatures; int mShadowRadiusId; int mCornerRadius; @@ -620,7 +619,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mCaptionHeightId = Resources.ID_NULL; mCaptionWidthId = Resources.ID_NULL; mOccludingCaptionElements.clear(); - mAllowCaptionInputFallthrough = false; + mInputFeatures = 0; mShadowRadiusId = Resources.ID_NULL; mCornerRadius = 0; @@ -630,6 +629,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> 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 d718e157afdb..0f24bb549158 100644 --- a/libs/WindowManager/Shell/tests/OWNERS +++ b/libs/WindowManager/Shell/tests/OWNERS @@ -12,3 +12,4 @@ jorgegil@google.com 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/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java index f9b5882f7ad5..608f74b95280 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 @@ package com.android.wm.shell.windowdecor; 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.Choreographer; 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 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* applyStartTransactionOnDraw= */ true, /* shouldSetTaskPositionAndCrop */ false); - assertThat(relayoutParams.mAllowCaptionInputFallthrough).isTrue(); + assertThat(relayoutParams.hasInputFeatureSpy()).isTrue(); } @Test @@ -204,7 +206,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* applyStartTransactionOnDraw= */ true, /* shouldSetTaskPositionAndCrop */ false); - assertThat(relayoutParams.mAllowCaptionInputFallthrough).isFalse(); + assertThat(relayoutParams.hasInputFeatureSpy()).isFalse(); } @Test @@ -220,7 +222,55 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* 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 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { 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/ResizeVeilTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt index 847c2dd77d0a..87425915fbf7 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt @@ -15,8 +15,8 @@ */ package com.android.wm.shell.windowdecor +import android.graphics.Bitmap import android.graphics.Rect -import android.graphics.drawable.Drawable import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.view.Display @@ -60,7 +60,7 @@ class ResizeVeilTest : ShellTestCase() { @Mock private lateinit var mockDisplayController: DisplayController @Mock - private lateinit var mockAppIcon: Drawable + private lateinit var mockAppIcon: Bitmap @Mock private lateinit var mockDisplay: Display @Mock 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 a9f44929fc64..48ac1e5717aa 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 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { 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 a8e85475aff0..0f29613cad33 100644 --- a/libs/hwui/renderthread/VulkanSurface.cpp +++ b/libs/hwui/renderthread/VulkanSurface.cpp @@ -322,11 +322,16 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window 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 ffd6e161d928..554fe5efac3d 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -1005,7 +1005,6 @@ public final class MediaRouter2 { * 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 99ae14414dad..63a6a58d8ce2 100644 --- a/nfc/jarjar-rules.txt +++ b/nfc/jarjar-rules.txt @@ -27,9 +27,8 @@ rule com.android.nfc.NfcDispatcherProto* com.android.nfc.x.@0 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/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml index c2d452db1e3c..8d44d9c5e1e6 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 32405a495559..95b6c29683bb 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 ccff535a61cd..115f544f8d10 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 c40685762ca1..b239fc35d41e 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 468f4e7eaf0b..7067a408bb75 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 2f6086a63bf1..e0def18b6953 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 336b29f91737..e3a9191ab225 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 2204e0286ac8..a3476d927da7 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 ec2a2d61d386..936ff79817a6 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 8dc0fc23b684..d943979e6db3 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 3c9c3b709f53..b423b2c6b005 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 a3f79cacf99c..cd5b7bb9ff1f 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 d5f3093feb2d..6b22e36d1daa 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 a2f55cd50519..8cde4542c5ca 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt @@ -125,6 +125,7 @@ class CredentialSelectorActivity : ComponentActivity() { 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 7bc32419e070..d4a81109e53c 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt @@ -19,6 +19,7 @@ package com.android.credentialmanager 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 @@ class CredentialSelectorViewModel( 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 @@ class CredentialSelectorViewModel( 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 @@ class CredentialSelectorViewModel( /**************************************************************************/ /** + * 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 @@ class CredentialSelectorViewModel( } /** - * 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 0d19a45ab82a..b43b5f318cf1 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 @@ import java.lang.Exception * ). * * 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 BiometricDisplayInfo( 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 @@ fun runBiometricFlowForGet( getBiometricPromptState: () -> BiometricPromptState, onBiometricPromptStateChange: (BiometricPromptState) -> Unit, onBiometricFailureFallback: (BiometricFlowType) -> Unit, + getBiometricCancellationSignal: () -> CancellationSignal, getRequestDisplayInfo: RequestDisplayInfo? = null, getProviderInfoList: List<ProviderInfo>? = null, getProviderDisplayInfo: ProviderDisplayInfo? = null, @@ -141,11 +142,13 @@ fun runBiometricFlowForGet( 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 @@ fun runBiometricFlowForCreate( getBiometricPromptState: () -> BiometricPromptState, onBiometricPromptStateChange: (BiometricPromptState) -> Unit, onBiometricFailureFallback: (BiometricFlowType) -> Unit, + getBiometricCancellationSignal: () -> CancellationSignal, createRequestDisplayInfo: com.android.credentialmanager.createflow .RequestDisplayInfo? = null, createProviderInfo: EnabledProviderInfo? = null, @@ -185,11 +189,13 @@ fun runBiometricFlowForCreate( 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 @@ private fun runBiometricFlow( openMoreOptionsPage: () -> Unit, onBiometricFailureFallback: (BiometricFlowType) -> Unit, biometricFlowType: BiometricFlowType, - onCancelFlowAndFinish: () -> Unit + onCancelFlowAndFinish: () -> Unit, + getBiometricCancellationSignal: () -> CancellationSignal, ) { try { if (!canCallBiometricPrompt(biometricDisplayInfo, context)) { @@ -217,12 +224,7 @@ private fun runBiometricFlow( 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 @@ private fun getCryptoOpId(biometricDisplayInfo: BiometricDisplayInfo): Int? { * 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 @@ private fun canCallBiometricPrompt( 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 @@ private fun setupBiometricAuthenticationCallback( 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 @@ private fun setupBiometricAuthenticationCallback( 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 @@ private fun retrieveBiometricGetDisplayValues( 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 e1aa0418e7a0..eb77937fd527 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 @@ enum class BiometricPromptState { /** 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 282a1b5736ac..7d61f73a525b 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 @@ package com.android.credentialmanager.createflow 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 @@ fun CreateCredentialScreen( 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 @@ internal fun BiometricSelectionPage( fallbackToOriginalFlow: (BiometricFlowType) -> Unit, getBiometricPromptState: () -> BiometricPromptState, onBiometricPromptStateChange: (BiometricPromptState) -> Unit, + getBiometricCancellationSignal: () -> CancellationSignal, ) { if (biometricEntry == null) { fallbackToOriginalFlow(BiometricFlowType.CREATE) @@ -655,5 +659,6 @@ internal fun BiometricSelectionPage( 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 c98bb5ed17c1..ba61b90fa4dc 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.credmanBiometricApiEnabled 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 @@ fun GetCredentialScreen( 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 @@ internal fun BiometricSelectionPage( fallbackToOriginalFlow: (BiometricFlowType) -> Unit, getBiometricPromptState: () -> BiometricPromptState, onBiometricPromptStateChange: (BiometricPromptState) -> Unit, + getBiometricCancellationSignal: () -> CancellationSignal, ) { if (biometricEntry == null) { fallbackToOriginalFlow(BiometricFlowType.GET) @@ -273,7 +277,8 @@ internal fun BiometricSelectionPage( 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 000000000000..a136aca79290 --- /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 33a1d760f417..e10bd7f9bf3e 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 4b7ea90eeb38..c18d73c60551 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 c39956d63286..a0a1eb98b820 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 f9800b39d448..964120461ddd 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) --> - <skip /> - <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) --> - <skip /> - <!-- no translation found for bluetooth_battery_level_lea_support (5968584103507988820) --> - <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) --> + <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) --> <skip /> - <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (8941549024377771038) --> + <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) --> <skip /> - <!-- no translation found for bluetooth_no_battery_level_lea_support (5721725041048434075) --> + <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) --> <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 729ac2824332..51cf4411b1cd 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 9f1355107e48..b1a7332ae855 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 62c120196abc..13b639a0f5cf 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 b1bbf34b19ba..809601e945d9 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 4af26f29ef40..24830b44eb1e 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 9998c9edf42e..986c0890c61e 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 03065c60d2d0..709707873062 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 b69a54208f30..e4637fe04690 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 2cc6dc582661..e71c2ec7c69e 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 5a4a9236f38d..09b4297714e6 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 9a3ba6316157..b2d75bd4a29f 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 c7f1c6e74333..0f92316e038d 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 cc962b42b63a..c8d7acdccc18 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 2ea96a75ba93..2cc9350e7426 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 d4f14f423131..af00515b5700 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 6b49bc91e0f9..bc08544434df 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 d4f14f423131..af00515b5700 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 d4f14f423131..af00515b5700 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 c2556334caaf..b123a1349403 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 6a40c4208551..5142f249b3fe 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 ab75219103c4..7dc1225210ba 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 c730457c5274..a47a218bae65 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 0668fb208bf9..91b9d20be307 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 3c7f1f89cd0f..7ab13baa7b20 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 da80499e65cc..cafeb1b45951 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 69883841e78b..0d96205411b9 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 709477bb9f1b..1928f32f89bf 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 e5c7f1e5de44..d0f47a89173d 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 d520536f3a1e..b750ae5ebb7c 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 a81daf74f3c7..0f0d516de2d7 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 362393e8cfb1..db2c31845edb 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 f251464bd13f..207e84af968c 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 4b6d727a852d..1b8b23676839 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 1594d1112570..d9730b39f55a 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 b85f4530b6ff..60370f594dea 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 08a2397452cf..fbae08d37e63 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 9ecf47b2e3f8..5a6c75162fe3 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 a51ba393b5d7..aac7223f81d1 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 ba1dae0dfe44..79dbbe755e0a 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 b8f8fa381341..eee0ac6fc56d 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 d049fd41083c..447126b030f2 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 70257debbeed..f8d3b739bf09 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 9ced8a0b808f..b6988ce418d9 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 7be7f382d5b0..d084a9bf79c8 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 c6a5bd431e84..19bea0846174 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 94b8173824d5..4f7b3506797b 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 ff1f3f371ac4..55fa4d3bae6a 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 c5b4a5e49f3f..6d3d54c5d5f5 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 0ba9122c5311..914b967e13dc 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 c431857fbeb4..c39717c3e0c2 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 a916a1c4a15d..5c5ec07fc50c 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 f86206cd67ee..b36098b6da44 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 2dde99f1f540..23c892f03732 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 d2021ba8cc38..d7814eb37210 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 d01fc166f2d6..a7e01a1c17ae 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 6394cb6b2c96..3f2e00382e70 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 eb31f967ef11..b233b5448eae 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 64c4e9694a38..73fe924e4b95 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 d4d27e1fd4cd..767b87d43371 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 38df760e30f8..5bc01f11bbb5 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 9e98623c3895..f0b94bfc7bed 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 38df760e30f8..5bc01f11bbb5 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 dddc11623559..4d6638aa6441 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 9a5a4006ee14..e155948849f3 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 0fce42b8a1a2..dff692e282ae 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 74c9e1f75f58..e85e96d006d2 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 a6d35c80ac24..6eb655c8a7e1 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 3f6e803e4dd1..f112060d7764 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 135176bd5b78..9341616ae29e 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 7712203cd36f..d3370e8ad238 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 53d583a587a6..d230022127ad 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 db112631a889..8097be06a16c 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 c2faca927299..a9d4c031af33 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 7b03f816e8ef..8f59f36bba3f 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 8eef17e6ab52..58b6e84ffb41 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 cf5bd2d2caa4..0300ddc1e31d 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 4b405033c15f..807bc51b8fed 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 a1b21981edc1..cee510b3bbd9 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 82f457639647..4415667cf144 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 9a1386eb011e..f33d9092b7c8 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 d3f8945e2488..816ba8db172b 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 b5a1d511ef3e..b26efb23b17c 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 a131c1248b70..149022ca8680 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 f9bdfbf753c1..7aea126a4bcc 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 fa27db9a427a..dc40304ba24a 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 @@ public class DreamBackend { 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/accessibility/accessibilitymenu/res/values-bs/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml index 749a6f283288..199b0c989ef2 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 fadef1ef35c6..b3aa7e15336b 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -226,6 +226,13 @@ flag { } 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 " @@ -525,6 +532,13 @@ flag { } flag { + name: "smartspace_lockscreen_viewmodel" + namespace: "systemui" + description: "Indicate Smartspace lockscreen viewmodel" + bug: "331451011" +} + +flag { name: "pin_input_field_styled_focus_state" namespace: "systemui" description: "Enables styled focus states on pin input field if keyboard is connected" @@ -828,3 +842,13 @@ flag { 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 ffa2b4662f33..000000000000 --- 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 9675f19613a8..000000000000 --- 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 a3f979542055..000000000000 --- 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 1411c32b813b..000000000000 --- 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 19d6038a0c90..7af8408938a0 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.compose.modifiers.thenIf 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 @@ internal fun PatternBouncer( 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 @@ internal fun PatternBouncer( ) } } - 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 @@ internal fun PatternBouncer( ), 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 89d43438aea2..338987a60227 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.compose.extensions.observeTaps 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 @@ fun CommunalHub( 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 @@ fun CommunalHub( 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 @@ fun CommunalHub( communalContent[index] is CommunalContentModel.CtaTileInViewMode ) { - isButtonToEditWidgetsShowing = true + viewModel.onShowCustomizeWidgetButton() } val key = index?.let { keyAtIndexIfEditable(communalContent, index) } @@ -290,18 +289,22 @@ fun CommunalHub( ) } - 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 @@ private fun ButtonToEditWidgets( } @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/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt index 0f8f1a216f3f..c96a8ce9e159 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.domain.model.CommunalContentModel 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 @@ class CommunalViewModelTest(flags: FlagsParameterization?) : SysuiTestCase() { 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 @@ class CommunalViewModelTest(flags: FlagsParameterization?) : SysuiTestCase() { // 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 @@ class CommunalViewModelTest(flags: FlagsParameterization?) : SysuiTestCase() { 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 11f9e1c0c8f2..eef23372cad2 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 @@ package com.android.systemui.dreams 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.FakeKeyguardBouncerRepositor 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.testKosmos 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.ArgumentCaptor 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 @@ class DreamOverlayServiceTest : SysuiTestCase() { private lateinit var lifecycleRegistry: FakeLifecycleRegistry + lateinit var mCommunalInteractor: CommunalInteractor + private lateinit var mWindowParams: WindowManager.LayoutParams @Mock lateinit var mDreamOverlayCallback: IDreamOverlayCallback @@ -162,6 +174,9 @@ class DreamOverlayServiceTest : SysuiTestCase() { 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 @@ class DreamOverlayServiceTest : SysuiTestCase() { mStateController, mKeyguardUpdateMonitor, mScrimManager, - kosmos.communalInteractor, + mCommunalInteractor, mSystemDialogsCloser, mUiEventLogger, mTouchInsetManager, @@ -605,6 +620,57 @@ class DreamOverlayServiceTest : SysuiTestCase() { .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/smartspace/SmartspaceViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/SmartspaceViewModelTest.kt new file mode 100644 index 000000000000..ffbbeb90d8bb --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/SmartspaceViewModelTest.kt @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.smartspace + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.kosmos.testScope +import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest +import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest +import com.android.systemui.power.domain.interactor.powerInteractor +import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel +import com.android.systemui.smartspace.viewmodel.smartspaceViewModelFactory +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.withTimeoutOrNull +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +class SmartspaceViewModelTest : SysuiTestCase() { + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + + private val powerInteractor = kosmos.powerInteractor + private val smartspaceViewModelFactory = kosmos.smartspaceViewModelFactory + + private lateinit var underTest: SmartspaceViewModel + + @Test + fun dateVew_isAwakeTrue_true() = + testScope.runTest { + underTest = smartspaceViewModelFactory.create(SmartspaceViewModel.SURFACE_DATE_VIEW) + + powerInteractor.setAwakeForTest() + val isAwake by collectLastValue(underTest.isAwake) + + assertThat(isAwake).isTrue() + } + + @Test + fun dateVew_isAwakeFalse_false() = + testScope.runTest { + underTest = smartspaceViewModelFactory.create(SmartspaceViewModel.SURFACE_DATE_VIEW) + + powerInteractor.setAsleepForTest() + val isAwake by collectLastValue(underTest.isAwake) + + assertThat(isAwake).isFalse() + } + + @Test + fun dateVew_isAwakeMultipleTimes_correctResults() = + testScope.runTest { + underTest = smartspaceViewModelFactory.create(SmartspaceViewModel.SURFACE_DATE_VIEW) + val isAwake by collectLastValue(underTest.isAwake) + + powerInteractor.setAsleepForTest() + + assertThat(isAwake).isFalse() + + powerInteractor.setAwakeForTest() + + assertThat(isAwake).isTrue() + + powerInteractor.setAsleepForTest() + + assertThat(isAwake).isFalse() + + powerInteractor.setAwakeForTest() + + assertThat(isAwake).isTrue() + } + + @Test + fun weatherView_isAwakeTrue_doesNotEmit() = + testScope.runTest { + underTest = smartspaceViewModelFactory.create(SmartspaceViewModel.SURFACE_WEATHER_VIEW) + + powerInteractor.setAwakeForTest() + val isAwake = withTimeoutOrNull(100) { underTest.isAwake.firstOrNull() } + + assertThat(isAwake).isNull() + } +} 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 a023033e3aa3..3408e06fe713 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 android.platform.test.flag.junit.FlagsParameterization 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.aodBurnInViewModel 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : @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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer @EnableFlags(FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX) fun validateMarginTopWithLargeScreenHeader_refactorFlagOn_usesHelper() = testScope.runTest { @@ -313,7 +311,6 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @BrokenWithSceneContainer(bugId = 333132830) fun glanceableHubAlpha_lockscreenToHub() = testScope.runTest { val alpha by collectLastValue(underTest.glanceableHubAlpha) @@ -357,7 +354,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : // 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : @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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun boundsOnShade() = testScope.runTest { val bounds by collectLastValue(underTest.bounds) @@ -637,7 +633,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun boundsOnQS() = testScope.runTest { val bounds by collectLastValue(underTest.bounds) @@ -682,7 +678,6 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @BrokenWithSceneContainer(bugId = 333132830) fun maxNotificationsOnLockscreen_DoesNotUpdateWhenUserInteracting() = testScope.runTest { var notificationCount = 10 @@ -700,26 +695,25 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun translationYUpdatesOnKeyguardForBurnIn() = testScope.runTest { val translationY by collectLastValue(underTest.translationY(BurnInParameters())) @@ -752,7 +746,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun translationYUpdatesOnKeyguard() = testScope.runTest { val translationY by collectLastValue(underTest.translationY(BurnInParameters())) @@ -764,7 +758,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun translationYDoesNotUpdateWhenShadeIsExpanded() = testScope.runTest { val translationY by collectLastValue(underTest.translationY(BurnInParameters())) @@ -786,7 +780,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : // 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @DisableFlags(FLAG_SCENE_CONTAINER) + @DisableSceneContainer fun updateBounds_fromKeyguardRoot() = testScope.runTest { val bounds by collectLastValue(underTest.bounds) @@ -806,7 +800,6 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @BrokenWithSceneContainer(bugId = 333132830) fun alphaOnFullQsExpansion() = testScope.runTest { val viewState = ViewStateAccessor() @@ -815,13 +808,13 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } @Test - @BrokenWithSceneContainer(bugId = 333132830) fun shadeCollapseFadeIn() = testScope.runTest { val fadeIn by collectValues(underTest.shadeCollapseFadeIn) @@ -961,8 +953,8 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } 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 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) : } 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 index c69f5c8198eb..87e1f86d8fc7 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 com.android.systemui.SysuiTestCase; 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 @@ import java.util.Queue; * either SysuiTestCase or SysUiBaseFragmentTest. * */ -@RunWith(Parameterized.class) +@RunWith(ParameterizedAndroidJunit4.class) @SmallTest public class EventsTest extends SysuiTestCase { private FakeMetricsLogger mLegacyLogger; @@ -66,23 +69,23 @@ public class EventsTest extends SysuiTestCase { } // 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 @@ public class EventsTest extends SysuiTestCase { } } - @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 @@ public class EventsTest extends SysuiTestCase { }); } } - diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/UtilTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/UtilTest.java index 483dc0c9c974..d6c63af9546a 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 static com.google.common.truth.Truth.assertThat; 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/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml index 5d9345b9c73a..a89dd7b78da1 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 8e3cf4d9b446..91ca69ec34ff 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 63c6132bff41..799b88abffca 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 1c8054797e47..6db4e0252957 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 c92a32ba48d1..7f89ab495559 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 f1291a0b39ff..c2dc3b0233a8 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 b12d822064de..853a020a983a 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 221d16c512fc..80cc48f1f5ef 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 d1c4a9851ab0..d64ffe8275a0 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 62d3fedc099b..b3321f58d7fc 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 81e3fc4a6a38..5c3d96badf69 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 7d668512acfe..f3ffe26f1d09 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 87af353149cd..341dca54280a 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 102768f2655f..ad5a76ac7115 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 d3138ab4b04a..f65364fc0d4e 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 03d04a6eb94d..3161b86178c1 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 89092ad44fc2..33dc496c6378 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 459de64f1f04..e0786ce6b895 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 4879850e9780..8b71d4b5bf2d 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 459de64f1f04..e0786ce6b895 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 459de64f1f04..e0786ce6b895 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 a2340bdc4887..f32b774bc080 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 202bd9345332..3b6f24981e35 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 88fab2da092d..42d403d78777 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 1b4cea78b676..f3c75a4a3598 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 b69ef30d4f62..da885b73401d 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 94fb12f0db15..b63ec78e33ee 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 a7754b0e4e86..21df7c718400 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 5bacaaa1d7ee..850f977f9df3 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 a4a039f1fa44..0df898887258 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 e2b1e532e003..10e860116dff 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 2883cc533c2c..ebfe6f7773ce 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 f30957df9662..ea50302f07be 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 bada67e0d74d..b1849c5f66eb 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 d216fa4609c8..ddae88639018 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 034ac1adac18..717732dd8a0e 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 d428ef807d5a..d5e353a303c9 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 4b97299ff55b..208790733db9 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 30bdfae9d40f..32f72fda876e 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 bc1d91f7b788..13f2e502027e 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 b587f4026174..b31c01c66c13 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 ff11d85aa3af..654acef86b66 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 995a79628066..0fda9f1bc561 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 adcd3d67301f..262d87be150b 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 ca22ba1a3aec..14644cfa7035 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 4e7c4d06efff..94cddf072cf8 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 1d005fb2c928..1561ac37c188 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 f95bb8e5b0fa..037045493bf4 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 040294f546d5..088a9fc77d17 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 da58f3320f7a..09f0050ac567 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 2faf2437abbb..abac1ad57e89 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 2fd4411d51cb..5bf98b5e76df 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 94cdf4cc9c65..608492a9406e 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 dd53db510441..e83cc4e3167e 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 6b858a4d0b93..ad0c4407dda8 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 2472d1fef588..078bfd7f6fe0 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 5bc2fe500e9c..2634bd3c6cc0 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 f52466c3f98e..7f81a5fa5e3f 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 7a37aa03a8de..78566b814762 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 7e8ee6fa8675..03c7cf5ea5fb 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 df823cfde616..6b88f29dd471 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 f6468af3ff36..d10d5f847046 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 a1c72dc7d57d..d0f70ed4a7f9 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 eadb5e5475bb..7889e0bcc50e 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 a1c72dc7d57d..d0f70ed4a7f9 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 e53b4a4daf99..8e4b75235a71 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 8f6d7a80378a..d8d038e58ea6 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 afb57551e738..5082174376a5 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 453dd4404b5f..ffc9f27f82db 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 27c376a3e7a3..515286cc3fce 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 071eda733add..99e5a7b66151 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 233e516b5343..e96d49346fa2 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 579f5262240e..7a5fa65b7a61 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 bc7b016a6360..9dae4218016f 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 b2c83dc04286..b418396e795c 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 5cd1341a2c54..a0a29d026045 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 544844dc6f99..0ef447eb48c1 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 13e4bf8558dc..975820aa0be2 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 30b6ce4c13d3..5b10259f8085 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 e1d768e2dcb9..071313f53b3b 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 16b40bf6d04b..e1b1fa466e70 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 76694df2a438..27145a6ba547 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 41066f989b46..84447fa32679 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 60a46d6067f2..eb928f006271 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 995129ed9de3..4ec1b58ce0dc 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 d18f8284509c..52a191746e4f 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 a5caa3d83326..c96be0e1fb66 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 1b2362dd4f2f..1a85f8d4aff0 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -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/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 519622e24b1f..167ab9043510 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_N 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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab 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 b8ff0c030f01..99be7628b3c6 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 @@ interface QSAccessibilityModule { 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 @@ interface QSAccessibilityModule { 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 e7e12bab745b..227e4dba5d04 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 @@ package com.android.systemui.ambient.touch; 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.Lifecycle; 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 class TouchMonitor { 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 @@ public class TouchMonitor { } }; + private Consumer<Rect> mMaxBoundsConsumer = rect -> mMaxBounds = rect; + /** * Adds a new {@link TouchSessionImpl} to participate in receiving future touches and gestures. @@ -262,6 +270,7 @@ public class TouchMonitor { */ private void startMonitoring() { stopMonitoring(true); + if (bouncerAreaExclusion()) { mBackgroundExecutor.execute(() -> { try { @@ -340,8 +349,13 @@ public class TouchMonitor { 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 @@ public class TouchMonitor { private final int mDisplayId; private final IWindowManager mWindowManagerService; + private Rect mMaxBounds; + /** * Designated constructor for {@link TouchMonitor} @@ -500,6 +516,7 @@ public class TouchMonitor { Lifecycle lifecycle, InputSessionComponent.Factory inputSessionFactory, DisplayHelper displayHelper, + ConfigurationInteractor configurationInteractor, Set<TouchHandler> handlers, IWindowManager windowManagerService, @DisplayId int displayId) { @@ -511,6 +528,7 @@ public class TouchMonitor { mLifecycle = lifecycle; mDisplayHelper = displayHelper; mWindowManagerService = windowManagerService; + mConfigurationInteractor = configurationInteractor; } /** @@ -518,6 +536,9 @@ public class TouchMonitor { */ 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 ea5c5da9b0e2..1c17beb91910 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 @@ public class AuthContainerView extends LinearLayout @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 072fe47df42b..a21114798c8f 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 @@ object BiometricViewBinder { * * 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 @@ object BiometricViewBinder { 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 @@ object BiometricViewBinder { } lifecycleScope.launch { - viewModel.showBpWithoutIconForCredential.collect { - if (!it) { + viewModel.showBpWithoutIconForCredential.collect { showWithoutIcon -> + if (!showWithoutIcon) { PromptIconViewBinder.bind( iconView, iconOverlayView, @@ -428,7 +436,7 @@ object BiometricViewBinder { } // 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 f380746105ed..d1ad783c7cc8 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.Animator 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.ConstraintLayout 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 @@ object BiometricViewSizeBinder { ) .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 @@ object BiometricViewSizeBinder { 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 @@ object BiometricViewSizeBinder { } } - 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 @@ object BiometricViewSizeBinder { lifecycleScope.launch { combine(viewModel.position, viewModel.size, ::Pair).collect { (position, size) -> - view.doOnAttach { - setVisibilities(size) - - if (position.isLeft) { - if (size.isSmall) { - flipConstraintSet.clone(smallConstraintSet) - } else { - flipConstraintSet.clone(mediumConstraintSet) - } + setVisibilities(size) - // 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) + // 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) - } + 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() - ) + } + size.isMedium && currentSize.isSmall -> { + val autoTransition = AutoTransition() + autoTransition.setDuration( + ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong() + ) - TransitionManager.beginDelayedTransition( - view, - autoTransition - ) + TransitionManager.beginDelayedTransition(view, autoTransition) - if (position.isLeft) { - flipConstraintSet.applyTo(view) - } else { - mediumConstraintSet.applyTo(view) - } + if (position.isLeft) { + flipConstraintSet.applyTo(view) + } else { + mediumConstraintSet.applyTo(view) } - size.isMedium -> { - 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() - ) + } + size.isLarge && currentSize.isMedium -> { + val autoTransition = AutoTransition() + autoTransition.setDuration( + ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong() + ) - TransitionManager.beginDelayedTransition( - view, - autoTransition - ) - largeConstraintSet.applyTo(view) - } + TransitionManager.beginDelayedTransition(view, autoTransition) + largeConstraintSet.applyTo(view) } + } - currentSize = size - view.visibility = View.VISIBLE - viewModel.setIsIconViewLoaded(false) - notifyAccessibilityChanged() + currentSize = size + currentPosition = position + notifyAccessibilityChanged() - view.invalidate() - view.requestLayout() - } + 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 d9d3715f0a30..9e836c31c177 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 @@ object PromptIconViewBinder { } } - 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( + 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( + 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 - } - 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 + iconOverlayView.layoutParams.width = iconSize.first + iconOverlayView.layoutParams.height = iconSize.second } - 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 8dbed5f2e323..bde3e992a295 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 @@ constructor( */ 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 @@ constructor( } .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 @@ constructor( 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 4e9acbd25b62..2104f3e1fba6 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.BiometricPrompt 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 @@ constructor( 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 @@ constructor( } } - val fingerprintSensorHeight: Flow<Int> = + val legacyFingerprintSensorHeight: Flow<Int> = combine(modalities, udfpsOverlayInteractor.udfpsOverlayParams) { modalities, overlayParams -> if (modalities.hasUdfps) { @@ -140,6 +162,12 @@ constructor( } } + 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 @@ constructor( 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 @@ constructor( _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 638af5844c3e..e0e1971ba75b 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 @@ class ConfigurationInteractor @Inject constructor(private val repository: Config } } + /** 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 4ac43bcc4abd..511bdc4c6cea 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 @@ abstract class BaseCommunalViewModel( /** 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 @@ abstract class BaseCommunalViewModel( /** 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 f13b5759036b..9dacf8cc4c5a 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 @@ constructor( .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 @@ constructor( 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 @@ constructor( _isEnableWorkProfileDialogShowing.value = isVisible } - private fun setPopupOnDismissCtaVisibility(isVisible: Boolean) { - _isPopupOnDismissCtaShowing.value = isVisible - } + private fun setCurrentPopupType(popupType: PopupType?) { + _currentPopup.value = popupType + delayedHideCurrentPopupJob?.cancel() - private var delayedHidePopupJob: Job? = null - - private fun schedulePopupHiding() { - cancelDelayedPopupHiding() - delayedHidePopupJob = - scope.launch { - delay(POPUP_AUTO_HIDE_TIMEOUT_MS) - onHidePopupAfterDismissCta() - } + if (popupType != null) { + delayedHideCurrentPopupJob = + scope.launch { + delay(POPUP_AUTO_HIDE_TIMEOUT_MS) + setCurrentPopupType(null) + } + } else { + delayedHideCurrentPopupJob = null + } } - 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 @@ constructor( 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 2af49aa5fa1a..db7ffc1bef79 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.app.Activity 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.SelectedComponentRepository 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 @@ abstract class ControlsModule { 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 98deda09613e..ffe392a52c9f 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 @@ constructor( } } .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 5f1667a70e5a..3365340164a2 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 @@ data class ErrorFaceAuthenticationStatus( * 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 c618e92466d7..aa7a7dae8f5e 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 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ 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 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ mExecutor.execute(() -> setLifecycleStateLocked(Lifecycle.State.CREATED)); + collectFlow(getLifecycle(), mCommunalInteractor.isCommunalAvailable(), + mIsCommunalAvailableCallback); collectFlow(getLifecycle(), communalInteractor.isCommunalVisible(), mCommunalVisibleConsumer); collectFlow(getLifecycle(), keyguardInteractor.primaryBouncerShowing, @@ -374,6 +386,16 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ mDreamOverlayCallbackController.onStartDream(); mStarted = true; + + updateRedirectWakeup(); + } + + private void updateRedirectWakeup() { + if (!mStarted || !dreamWakeRedirect()) { + return; + } + + redirectWake(mCommunalAvailable); } @Override @@ -381,6 +403,11 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ 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 516b8c521ca1..b0d134f5f15f 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.complication.dagger.ComplicationComponent; 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.Module; 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 @@ public interface DreamModule { 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 @@ public interface DreamModule { 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 0bc60c4b9543..7c29b39ad12c 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.AnimatorListenerAdapter 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 @@ class ClockSizeTransition( 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 @@ class ClockSizeTransition( 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 df3a974634d7..9719c029574f 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 @@ class MediaFilterRepository @Inject constructor(private val systemClock: SystemC 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 13f934ecda43..33c0b195bf50 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 @@ constructor( // 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 c0bb628b23b8..9f2d132fc7a9 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 @@ constructor( .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 dea581083cb7..dd6b2646afd1 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 @@ constructor( .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 8dd3379a2978..73fb5583ab3e 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 @@ object MediaControlViewBinder { } } - private suspend fun bindMediaCard( + suspend fun bindMediaCard( viewHolder: MediaViewHolder, viewController: MediaViewController, viewModel: MediaPlayerViewModel, @@ -333,7 +333,7 @@ object MediaControlViewBinder { } } } - updateSeekBarVisibility(viewController.expandedLayout, isSeekBarEnabled = false) + updateSeekBarVisibility(viewController.expandedLayout, viewController.isSeekBarEnabled) } private fun bindButtonCommon( @@ -472,6 +472,7 @@ object MediaControlViewBinder { 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 fe13da6c3a74..bd4d43531339 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 @@ object MediaRecommendationsViewBinder { } } - 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 d2dd2893df53..0478178e71d6 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 android.widget.LinearLayout 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.lifecycle.repeatWhenAttached 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( } } ) - 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 @@ constructor( } } + 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 @@ constructor( 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 @@ constructor( systemClock, debugLogger, ) - updatePlayerToState(newRecs.mediaViewController, noAnimation = true) + updateViewControllerToState(newRecs.mediaViewController, noAnimation = true) reorderAllPlayers(curVisibleMediaKey) updatePageIndicator() mediaFrame.requiresRemeasuring = true @@ -905,6 +1052,10 @@ constructor( } 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 @@ constructor( } } + 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 @@ constructor( 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 @@ constructor( /** 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 @@ constructor( 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 @@ constructor( } } - private fun updatePlayerToState(viewController: MediaViewController, noAnimation: Boolean) { + private fun updateViewControllerToState( + viewController: MediaViewController, + noAnimation: Boolean + ) { viewController.setCurrentState( startLocation = currentStartLocation, endLocation = currentEndLocation, @@ -1123,18 +1321,31 @@ constructor( !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) } + } else { + controllerByViewModel.values.forEach { controller -> + if (animate) { + controller.animatePendingStateChange(duration, startDelay) + } + if (shouldCloseGuts && controller.isGutsVisible) { + controller.closeGuts(!animate) + } - mediaPlayer.mediaViewController.onLocationPreChange(desiredLocation) + controller.onLocationPreChange(desiredLocation) + } } mediaCarouselScrollHandler.showsSettingsButton = !it.showsOnlyActiveMedia mediaCarouselScrollHandler.falsingProtectionNeeded = it.falsingProtectionNeeded @@ -1150,7 +1361,11 @@ constructor( } 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 @@ constructor( } private fun onSwipeToDismiss() { + if (mediaFlags.isMediaControlsRefactorEnabled()) { + mediaCarouselViewModel.onSwipeToDismiss() + return + } MediaPlayerData.players().forEachIndexed { index, it -> if (it.mIsImpressed) { logSmartspaceCardReported( @@ -1319,6 +1538,7 @@ constructor( 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 5188132b571e..96a8239a2c60 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.statusbar.notification.collection.provider.VisualSta 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 @@ constructor( @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 @@ constructor( 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 52e49d6098f0..bc364c36a298 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.ColorScheme 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 @@ class MediaControlViewModel( .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 @@ class MediaControlViewModel( 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 5cd980441b4c..52c4bc54eab4 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.monet.Style 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 @@ constructor( 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 22b3f35803da..cef1e69e7b6a 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.core.view.GestureDetectorCompat 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 @@ private fun PlaybackState.computePosition(duration: Long): Long { 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 @@ constructor( 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/qrcodescanner/dagger/QRCodeScannerModule.kt b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt index d40112fd5660..3907a7240258 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 @@ interface QRCodeScannerModule { @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 4a8e33a99b25..2e52845ceb80 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 @@ sealed class TileSpec private constructor(open val spec: String) { 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/recordissue/RecordIssueModule.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt index d67cf4d3d098..26af9a71de7d 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 @@ interface RecordIssueModule { @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/shade/carrier/ShadeCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java index e3d2f7de0ed4..4b6dd8d00ae7 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 @@ public class ShadeCarrierGroupController { 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/smartspace/ui/binder/SmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/smartspace/ui/binder/SmartspaceViewBinder.kt new file mode 100644 index 000000000000..6c3d7dfc1e4f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/smartspace/ui/binder/SmartspaceViewBinder.kt @@ -0,0 +1,45 @@ +/* + * 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.smartspace.ui.binder + +import android.view.View +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.repeatOnLifecycle +import com.android.systemui.lifecycle.repeatWhenAttached +import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView +import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel +import kotlinx.coroutines.launch + +/** Binds the view and view-model for the smartspace. */ +object SmartspaceViewBinder { + + /** Binds the view and view-model for the smartspace. */ + fun bind( + smartspaceView: SmartspaceView, + viewModel: SmartspaceViewModel, + ) { + val view = smartspaceView as View + view.repeatWhenAttached { + repeatOnLifecycle(Lifecycle.State.CREATED) { + launch { + // Observe screen on/off changes + viewModel.isAwake.collect { isAwake -> smartspaceView.setScreenOn(isAwake) } + } + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/ui/viewmodel/SmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/smartspace/ui/viewmodel/SmartspaceViewModel.kt new file mode 100644 index 000000000000..417738332052 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/smartspace/ui/viewmodel/SmartspaceViewModel.kt @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.smartspace.ui.viewmodel + +import com.android.systemui.power.domain.interactor.PowerInteractor +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filter + +class SmartspaceViewModel +@AssistedInject +constructor( + powerInteractor: PowerInteractor, + @Assisted val surfaceName: String, +) { + + /** Screen on/off state */ + val isAwake: Flow<Boolean> = + powerInteractor.isAwake.filter { surfaceName != SURFACE_WEATHER_VIEW } + + @AssistedFactory + interface Factory { + fun create(surfaceName: String): SmartspaceViewModel + } + + companion object { + const val SURFACE_DATE_VIEW = "date_view" + const val SURFACE_WEATHER_VIEW = "weather_view" + const val SURFACE_GENERAL_VIEW = "general_view" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 09985f842185..7983db137e76 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.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; 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.ColorStateList; 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 @@ public class KeyguardIndicationController { 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 7a7cb7d3bfdb..c7952b64423d 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 @@ interface ConnectivityModule { 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 @@ interface ConnectivityModule { 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/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt index c29a64ed61b2..446a0d746227 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt @@ -40,6 +40,7 @@ import androidx.annotation.VisibleForTesting import com.android.keyguard.KeyguardUpdateMonitor import com.android.settingslib.Utils import com.android.systemui.Dumpable +import com.android.systemui.Flags.smartspaceLockscreenViewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main @@ -60,6 +61,8 @@ import com.android.systemui.settings.UserTracker import com.android.systemui.shared.regionsampling.RegionSampler import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DATE_SMARTSPACE_DATA_PLUGIN import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.WEATHER_SMARTSPACE_DATA_PLUGIN +import com.android.systemui.smartspace.ui.binder.SmartspaceViewBinder +import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.DeviceProvisionedController @@ -98,6 +101,7 @@ constructor( private val bypassController: KeyguardBypassController, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, private val wakefulnessLifecycle: WakefulnessLifecycle, + private val smartspaceViewModelFactory: SmartspaceViewModel.Factory, private val dumpManager: DumpManager, private val execution: Execution, @Main private val uiExecutor: Executor, @@ -333,7 +337,12 @@ constructor( throw RuntimeException("Cannot build date view when not decoupled") } - val view = buildView(parent, datePlugin) + val view = + buildView( + surfaceName = SmartspaceViewModel.SURFACE_DATE_VIEW, + parent = parent, + plugin = datePlugin + ) connectSession() return view @@ -352,7 +361,12 @@ constructor( throw RuntimeException("Cannot build weather view when not decoupled") } - val view = buildView(parent, weatherPlugin) + val view = + buildView( + surfaceName = SmartspaceViewModel.SURFACE_WEATHER_VIEW, + parent = parent, + plugin = weatherPlugin + ) connectSession() return view @@ -368,16 +382,23 @@ constructor( throw RuntimeException("Cannot build view when not enabled") } - val view = buildView(parent, plugin, configPlugin) + val view = + buildView( + surfaceName = SmartspaceViewModel.SURFACE_GENERAL_VIEW, + parent = parent, + plugin = plugin, + configPlugin = configPlugin + ) connectSession() return view } private fun buildView( - parent: ViewGroup, - plugin: BcSmartspaceDataPlugin?, - configPlugin: BcSmartspaceConfigPlugin? = null + surfaceName: String, + parent: ViewGroup, + plugin: BcSmartspaceDataPlugin?, + configPlugin: BcSmartspaceConfigPlugin? = null ): View? { if (plugin == null) { return null @@ -424,6 +445,14 @@ constructor( return (ssView as View).apply { setTag(R.id.tag_smartspace_view, Any()) addOnAttachStateChangeListener(stateChangeListener) + + if (smartspaceLockscreenViewmodel()) { + val viewModel = smartspaceViewModelFactory.create(surfaceName) + SmartspaceViewBinder.bind( + smartspaceView = ssView, + viewModel = viewModel, + ) + } } } @@ -466,7 +495,9 @@ constructor( configurationController.addCallback(configChangeListener) statusBarStateController.addCallback(statusBarStateListener) bypassController.registerOnBypassStateChangedListener(bypassStateChangedListener) - wakefulnessLifecycle.addObserver(wakefulnessLifecycleObserver) + if (!smartspaceLockscreenViewmodel()) { + wakefulnessLifecycle.addObserver(wakefulnessLifecycleObserver) + } datePlugin?.registerSmartspaceEventNotifier { e -> session?.notifySmartspaceEvent(e) } weatherPlugin?.registerSmartspaceEventNotifier { e -> session?.notifySmartspaceEvent(e) } @@ -509,7 +540,9 @@ constructor( configurationController.removeCallback(configChangeListener) statusBarStateController.removeCallback(statusBarStateListener) bypassController.unregisterOnBypassStateChangedListener(bypassStateChangedListener) - wakefulnessLifecycle.removeObserver(wakefulnessLifecycleObserver) + if (!smartspaceLockscreenViewmodel()) { + wakefulnessLifecycle.removeObserver(wakefulnessLifecycleObserver) + } session = null datePlugin?.registerSmartspaceEventNotifier(null) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/StatusBarIconViewBinder.kt index 2fdd2c6434cb..6b5642af3f10 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 @@ object StatusBarIconViewBinder { // 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 @@ object StatusBarIconViewBinder { 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 de0f24798427..57504b2649bf 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 @@ public class NotificationStackScrollLayout 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/pipeline/mobile/data/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt index 4f702d7534cb..d4b2dbff078b 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 @@ constructor( ) } + 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 b3885d247949..6803a9dc06fd 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,29 +142,23 @@ class MobileConnectionRepositoryImpl( 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 onSignalStrengthsChanged(signalStrength: SignalStrength) { - logger.logOnSignalStrengthsChanged(signalStrength, subId) - trySend(CallbackEvent.OnSignalStrengthChanged(signalStrength)) + override fun onCarrierNetworkChange(active: Boolean) { + logger.logOnCarrierNetworkChange(active, subId) + trySend(CallbackEvent.OnCarrierNetworkChange(active)) } - override fun onDataConnectionStateChanged( - dataState: Int, - networkType: Int - ) { - logger.logOnDataConnectionStateChanged(dataState, networkType, subId) - trySend(CallbackEvent.OnDataConnectionStateChanged(dataState)) + override fun onCarrierRoamingNtnModeChanged(active: Boolean) { + logger.logOnCarrierRoamingNtnModeChanged(active) + trySend(CallbackEvent.OnCarrierRoamingNtnModeChanged(active)) } override fun onDataActivity(direction: Int) { @@ -172,9 +166,17 @@ class MobileConnectionRepositoryImpl( trySend(CallbackEvent.OnDataActivity(direction)) } - override fun onCarrierNetworkChange(active: Boolean) { - logger.logOnCarrierNetworkChange(active, subId) - trySend(CallbackEvent.OnCarrierNetworkChange(active)) + override fun onDataEnabledChanged(enabled: Boolean, reason: Int) { + logger.logOnDataEnabledChanged(enabled, subId) + trySend(CallbackEvent.OnDataEnabledChanged(enabled)) + } + + override fun onDataConnectionStateChanged( + dataState: Int, + networkType: Int + ) { + logger.logOnDataConnectionStateChanged(dataState, networkType, subId) + trySend(CallbackEvent.OnDataConnectionStateChanged(dataState)) } override fun onDisplayInfoChanged( @@ -184,9 +186,14 @@ class MobileConnectionRepositoryImpl( 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 @@ class MobileConnectionRepositoryImpl( 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 @@ private fun Intent.carrierId(): Int = 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 @@ sealed interface CallbackEvent { 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 @@ data class TelephonyCallbackState( 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 db4e605dc9bb..08f973b05794 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 @@ interface PolicyModule { 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 @@ interface PolicyModule { instanceId = uiEventLogger.getNewInstanceId(), policy = QSTilePolicy.Restricted( - listOf( - DISALLOW_SHARE_LOCATION, - DISALLOW_CONFIG_LOCATION - ) + listOf(DISALLOW_SHARE_LOCATION, DISALLOW_CONFIG_LOCATION) ) ) @@ -321,6 +319,21 @@ interface PolicyModule { 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/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index d354fa2cac56..d6f0ef8df24e 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 @@ package com.android.keyguard; 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.BiometricManager; 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 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { 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 1e3b55695849..d01d57e18223 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.anyInt; 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 @@ import java.util.stream.Stream; @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 @@ public class TouchMonitorTest extends SysuiTestCase { mDisplayHelper = Mockito.mock(DisplayHelper.class); when(mDisplayHelper.getMaxBounds(anyInt(), anyInt())) .thenReturn(mDisplayBounds); - mMonitor = new TouchMonitor(mExecutor, mBackgroundExecutor, - mLifecycle, mInputFactory, mDisplayHelper, 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(); + 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(); - updateLifecycle(observer -> observer.first.onResume(observer.second)); + updateLifecycle(Lifecycle.State.RESUMED); // Capture creation request. final ArgumentCaptor<InputChannelCompat.InputEventListener> inputEventListenerCaptor = @@ -145,8 +179,8 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { } @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 @@ public class TouchMonitorTest extends SysuiTestCase { }).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 @@ public class TouchMonitorTest extends SysuiTestCase { }).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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 @@ public class TouchMonitorTest extends SysuiTestCase { 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 9e007e970a92..63b4ff791f76 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 @@ class ConfigurationInteractorTest : SysuiTestCase() { @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 @@ class ConfigurationInteractorTest : SysuiTestCase() { @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 @@ class ConfigurationInteractorTest : SysuiTestCase() { @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 @@ class ConfigurationInteractorTest : SysuiTestCase() { } @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 5581f0c0314f..431fef65e95b 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 @@ class BiometricMessageInteractorTest : SysuiTestCase() { faceAuthRepository.setAuthenticationStatus( HelpFaceAuthenticationStatus( msg = "Move left", - msgId = FaceManager.FACE_ACQUIRED_TOO_RIGHT, + msgId = FACE_ACQUIRED_TOO_RIGHT, ) ) @@ -293,7 +295,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { faceAuthRepository.setAuthenticationStatus( HelpFaceAuthenticationStatus( msg = "Move left", - msgId = FaceManager.FACE_ACQUIRED_TOO_RIGHT, + msgId = FACE_ACQUIRED_TOO_RIGHT, ) ) @@ -318,7 +320,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { faceAuthRepository.setAuthenticationStatus( HelpFaceAuthenticationStatus( msg = "Move left", - msgId = FaceManager.FACE_ACQUIRED_TOO_RIGHT, + msgId = FACE_ACQUIRED_TOO_RIGHT, ) ) @@ -333,10 +335,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { // 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 @@ class BiometricMessageInteractorTest : SysuiTestCase() { // 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 @@ class BiometricMessageInteractorTest : SysuiTestCase() { // 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 @@ class BiometricMessageInteractorTest : SysuiTestCase() { // 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 b3cfcf251a47..857af66cab16 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.broadcast.BroadcastSender 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.MediaFlags 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 @@ private val SMARTSPACE_INSTANCE_ID = InstanceId.fakeInstanceId(456)!! @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 @@ class MediaDataFilterImplTest : SysuiTestCase() { @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 @@ class MediaDataFilterImplTest : SysuiTestCase() { 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 ffb50c1ee3ff..1de7ee339c3e 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.broadcast.BroadcastDispatcher 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.media.controls.util.MediaUiEventLogger 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 @@ private fun <T> anyObject(): T { @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 @@ class MediaDataProcessorTest : SysuiTestCase() { @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 @@ class MediaDataProcessorTest : SysuiTestCase() { Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION, 1 ) + private val mediaFilterRepository: MediaFilterRepository = kosmos.mediaFilterRepository private lateinit var staticMockSession: MockitoSession @@ -210,7 +213,6 @@ class MediaDataProcessorTest : SysuiTestCase() { ) 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 c3daf8485634..0a5aace91481 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.dump.DumpManager 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.shared.model.MediaData 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 @@ class MediaCarouselControllerTest : SysuiTestCase() { 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 @@ class MediaCarouselControllerTest : SysuiTestCase() { mediaHostStatesManager, activityStarter, clock, + kosmos.testDispatcher, executor, bgExecutor, testDispatcher, @@ -162,6 +166,8 @@ class MediaCarouselControllerTest : SysuiTestCase() { 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 cb4ab64a48dd..e1c2d3f115ed 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.arch.core.executor.TaskExecutor 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 @@ import org.mockito.junit.MockitoJUnit @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 @@ public class SeekBarViewModelTest : SysuiTestCase() { @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 @@ public class SeekBarViewModelTest : SysuiTestCase() { @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/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt index 5abad61d90ad..63ce2330698a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt @@ -30,6 +30,7 @@ import android.net.Uri import android.os.Bundle import android.os.Handler import android.os.UserHandle +import android.platform.test.annotations.DisableFlags import android.provider.Settings import android.view.View import android.widget.FrameLayout @@ -49,11 +50,14 @@ import com.android.systemui.plugins.clocks.WeatherData import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener import com.android.systemui.settings.UserTracker +import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel +import com.android.systemui.smartspace.viewmodel.smartspaceViewModelFactory import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener +import com.android.systemui.testKosmos import com.android.systemui.util.concurrency.FakeExecution import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any @@ -182,6 +186,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { private lateinit var weatherSmartspaceView: SmartspaceView private lateinit var smartspaceView: SmartspaceView private lateinit var wakefulnessLifecycle: WakefulnessLifecycle + private lateinit var smartspaceViewModelFactory: SmartspaceViewModel.Factory private val clock = FakeSystemClock() private val executor = FakeExecutor(clock) @@ -234,6 +239,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { clock, dumpManager ) + smartspaceViewModelFactory = testKosmos().smartspaceViewModelFactory controller = LockscreenSmartspaceController( context, @@ -251,6 +257,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { keyguardBypassController, keyguardUpdateMonitor, wakefulnessLifecycle, + smartspaceViewModelFactory, dumpManager, execution, executor, @@ -785,6 +792,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { } @Test + @DisableFlags(com.android.systemui.Flags.FLAG_SMARTSPACE_LOCKSCREEN_VIEWMODEL) fun testWakefulnessLifecycleDispatch_wake_setsSmartspaceScreenOnTrue() { // Connect session connectSession() @@ -801,6 +809,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { } @Test + @DisableFlags(com.android.systemui.Flags.FLAG_SMARTSPACE_LOCKSCREEN_VIEWMODEL) fun testWakefulnessLifecycleDispatch_sleep_setsSmartspaceScreenOnFalse() { // Connect session connectSession() 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 9d1411625a8f..3695d8c151a2 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.ServiceState.STATE_OUT_OF_SERVICE 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 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { @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 b1df159cdefc..000000000000 --- 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 7dab5c24a52f..690bde7f5b47 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 6eae28f7c772..069995aa3fec 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 @@ val Kosmos.mediaCarouselViewModel by 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 b3fb15ff0c31..2f3d3c3e0489 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 @@ import com.android.systemui.media.controls.util.mediaUiEventLogger 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 d17dd6c518a4..0101961c9b72 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.flag.SceneContainerFlag 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 @@ class ShadeTestUtil constructor(val delegate: ShadeTestUtilDelegate) { /** 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 @@ class ShadeTestUtil constructor(val delegate: ShadeTestUtilDelegate) { 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 @@ class ShadeTestUtil constructor(val delegate: ShadeTestUtilDelegate) { 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 @@ interface ShadeTestUtilDelegate { 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 @@ class ShadeTestUtilLegacyImpl(val testScope: TestScope, val shadeRepository: Fak 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 @@ class ShadeTestUtilSceneImpl(val testScope: TestScope, val sceneInteractor: Scen } } + override fun setLockscreenShadeTracking(lockscreenShadeTracking: Boolean) { + isUserInputOngoing.value = lockscreenShadeTracking + } + private fun setIdleScene(scene: SceneKey) { sceneInteractor.changeScene(scene, "test") val transitionState = @@ -127,8 +179,8 @@ class ShadeTestUtilSceneImpl(val testScope: TestScope, val sceneInteractor: Scen 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/smartspace/viewmodel/SmartspaceViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/viewmodel/SmartspaceViewModelKosmos.kt new file mode 100644 index 000000000000..ebaf323696c8 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/viewmodel/SmartspaceViewModelKosmos.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.smartspace.viewmodel + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.power.domain.interactor.powerInteractor +import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel + +val Kosmos.smartspaceViewModelFactory by + Kosmos.Fixture { + object : SmartspaceViewModel.Factory { + override fun create(surfaceName: String): SmartspaceViewModel { + return SmartspaceViewModel( + powerInteractor = powerInteractor, + surfaceName = surfaceName + ) + } + } + } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 96228b242369..a6b78098fbf8 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 @@ public final class ActiveServices { 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; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 49f2c8b7c55c..c47e42dfd07e 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 @@ public class ActivityManagerService extends IActivityManager.Stub 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 @@ public class ActivityManagerService extends IActivityManager.Stub } @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 @@ public class ActivityManagerService extends IActivityManager.Stub } 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 bf4f34fd799f..5af9424a025c 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.DebugUtils; 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 @@ final class ActivityManagerShellCommand extends ShellCommand { 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 @@ final class ActivityManagerShellCommand extends ShellCommand { 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 @@ final class ActivityManagerShellCommand extends ShellCommand { "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,7 +1431,30 @@ final class ActivityManagerShellCommand extends ShellCommand { userId = user.id; } mInternal.mProcessList.getAppStartInfoTracker() - .clearHistoryProcessStartInfo(packageName, userId); + .clearHistoryProcessStartInfo(getNextArg(), userId); + return 0; + } + + int runStartInfoDetailedMonitoring(PrintWriter pw) throws RemoteException { + 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.getAppStartInfoTracker() + .configureDetailedMonitoring(pw, getNextArg(), userId); return 0; } @@ -1420,12 +1463,12 @@ final class ActivityManagerShellCommand extends ShellCommand { "runClearExitInfo()"); 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 +1478,8 @@ final class ActivityManagerShellCommand extends ShellCommand { } userId = user.id; } - mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(packageName, userId); + mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(getNextArg(), + userId); return 0; } @@ -4236,6 +4280,9 @@ final class ActivityManagerShellCommand extends ShellCommand { 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 @@ final class ActivityManagerShellCommand extends ShellCommand { 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 2be1fe26628e..376f65438e64 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.ArrayList; 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 @@ public final class AppStartInfoTracker { 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 @@ public final class AppStartInfoTracker { 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 @@ public final class AppStartInfoTracker { /** 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 @@ public final class AppStartInfoTracker { @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 @@ public final class AppStartInfoTracker { @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 @@ public final class AppStartInfoTracker { 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 @@ public final class AppStartInfoTracker { 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/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 9b72db8f5d6f..a289dd16170d 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 @@ public class OomAdjuster { } @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 08165275757e..a74c4896dd8c 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 com.android.server.wm.WindowProcessListener; 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 @@ class ProcessRecord implements WindowProcessListener { && !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 19be5f9a2623..fb63ec619918 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 @@ flag { 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 cd5d0c8dc3f2..ff1e5d5f91e6 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 @@ public class BiometricLogger { 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 8d3223537fb9..ef7abdd4645c 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.events.AuthenticationSucceededInfo; 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 @@ public class FaceAuthenticationClient 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 class FaceAuthenticationClient 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 6b99493f131b..559462a50f4f 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.common.ComponentInfo; 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 @@ public class Sensor { 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/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index a818eabe9597..816242df639d 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 @@ final class DreamController { 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/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java index e196dee41d1a..573116105dea 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java @@ -922,7 +922,7 @@ public class ContextHubService extends IContextHubService.Stub { } /** - * Handles a message deliveyr status from a Context Hub. + * Handles a message delivery status from a Context Hub. * * @param messageDeliveryStatus The message delivery status to deliver. */ diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index f981d791d383..399866728770 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 @@ public class MediaSessionService extends SystemService implements Monitor { } private void addUserEngagedSession(MediaSessionRecordImpl mediaSessionRecord) { + if (!Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange()) { + return; + } synchronized (mLock) { int uid = mediaSessionRecord.getUid(); mUserEngagedSessionsForFgs.putIfAbsent(uid, new HashSet<>()); @@ -673,6 +676,9 @@ public class MediaSessionService extends SystemService implements Monitor { } 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 36790ab99c28..2e25ad8cc73d 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 @@ final class InstallPackageHelper { (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/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index fde49d210f80..5fa8856f2940 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -129,6 +129,7 @@ public class Notifier { private final WindowManagerPolicy mPolicy; private final FaceDownDetector mFaceDownDetector; private final ScreenUndimDetector mScreenUndimDetector; + private final WakefulnessSessionObserver mWakefulnessSessionObserver; private final ActivityManagerInternal mActivityManagerInternal; private final InputManagerInternal mInputManagerInternal; private final InputMethodManagerInternal mInputMethodManagerInternal; @@ -197,6 +198,7 @@ public class Notifier { mPolicy = policy; mFaceDownDetector = faceDownDetector; mScreenUndimDetector = screenUndimDetector; + mWakefulnessSessionObserver = new WakefulnessSessionObserver(mContext, null); mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class); @@ -286,6 +288,8 @@ public class Notifier { } mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags); + + mWakefulnessSessionObserver.onWakeLockAcquired(flags); } public void onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource, @@ -386,6 +390,16 @@ public class Notifier { public void onWakeLockReleased(int flags, String tag, String packageName, int ownerUid, int ownerPid, WorkSource workSource, String historyTag, IWakeLockCallback callback) { + onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag, + callback, ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN); + } + + /** + * Called when a wake lock is released. + */ + public void onWakeLockReleased(int flags, String tag, String packageName, + int ownerUid, int ownerPid, WorkSource workSource, String historyTag, + IWakeLockCallback callback, int releaseReason) { if (DEBUG) { Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag + "\", packageName=" + packageName @@ -409,6 +423,8 @@ public class Notifier { } } mWakeLockLog.onWakeLockReleased(tag, ownerUid); + + mWakefulnessSessionObserver.onWakeLockReleased(flags, releaseReason); } /** Shows the keyguard without requesting the device to immediately lock. */ @@ -670,6 +686,8 @@ public class Notifier { interactivity.changeStartTime = eventTime; interactivity.isChanging = true; handleEarlyInteractiveChange(groupId); + mWakefulnessSessionObserver.onWakefulnessChangeStarted(groupId, wakefulness, + changeReason, eventTime); } } @@ -680,6 +698,7 @@ public class Notifier { */ public void onGroupRemoved(int groupId) { mInteractivityByGroupId.remove(groupId); + mWakefulnessSessionObserver.removePowerGroup(groupId); } /** @@ -693,6 +712,8 @@ public class Notifier { try { mBatteryStats.noteUserActivity(uid, event); + mWakefulnessSessionObserver.notifyUserActivity( + SystemClock.uptimeMillis(), displayGroupId, event); } catch (RemoteException ex) { // Ignore } @@ -798,6 +819,8 @@ public class Notifier { if (mWakeLockLog != null) { mWakeLockLog.dump(pw); } + + mWakefulnessSessionObserver.dump(pw); } private void updatePendingBroadcastLocked() { diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index eb1f7202f317..bbb59ce27f1a 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -231,7 +231,7 @@ public final class PowerManagerService extends SystemService // Default timeout in milliseconds. This is only used until the settings // provider populates the actual default value (R.integer.def_screen_off_timeout). - private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000; + static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000; private static final int DEFAULT_SLEEP_TIMEOUT = -1; // Screen brightness boost timeout. @@ -1417,8 +1417,9 @@ public final class PowerManagerService extends SystemService updateSettingsLocked(); if (mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled()) { mScreenTimeoutOverridePolicy = new ScreenTimeoutOverridePolicy(mContext, - mMinimumScreenOffTimeoutConfig, () -> { + mMinimumScreenOffTimeoutConfig, (releaseReason) -> { Message msg = mHandler.obtainMessage(MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS); + msg.arg1 = releaseReason; mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); }); } @@ -1827,6 +1828,12 @@ public final class PowerManagerService extends SystemService @GuardedBy("mLock") private void removeWakeLockNoUpdateLocked(WakeLock wakeLock, int index) { + removeWakeLockNoUpdateLocked(wakeLock, index, + ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN); + } + + @GuardedBy("mLock") + private void removeWakeLockNoUpdateLocked(WakeLock wakeLock, int index, int releaseReason) { mWakeLocks.remove(index); UidState state = wakeLock.mUidState; state.mNumWakeLocks--; @@ -1835,7 +1842,7 @@ public final class PowerManagerService extends SystemService mUidState.remove(state.mUid); } - notifyWakeLockReleasedLocked(wakeLock); + notifyWakeLockReleasedLocked(wakeLock, releaseReason); applyWakeLockFlagsOnReleaseLocked(wakeLock); mDirty |= DIRTY_WAKE_LOCKS; } @@ -2001,12 +2008,17 @@ public final class PowerManagerService extends SystemService @GuardedBy("mLock") private void notifyWakeLockReleasedLocked(WakeLock wakeLock) { + notifyWakeLockReleasedLocked(wakeLock, ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN); + } + + @GuardedBy("mLock") + private void notifyWakeLockReleasedLocked(WakeLock wakeLock, int releaseReason) { if (mSystemReady && wakeLock.mNotifiedAcquired) { wakeLock.mNotifiedAcquired = false; wakeLock.mAcquireTime = 0; mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid, - wakeLock.mWorkSource, wakeLock.mHistoryTag, wakeLock.mCallback); + wakeLock.mWorkSource, wakeLock.mHistoryTag, wakeLock.mCallback, releaseReason); notifyWakeLockLongFinishedLocked(wakeLock); } } @@ -5345,7 +5357,7 @@ public final class PowerManagerService extends SystemService handleAttentiveTimeout(); break; case MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS: - releaseAllOverrideWakeLocks(); + releaseAllOverrideWakeLocks(msg.arg1); break; } @@ -7269,7 +7281,7 @@ public final class PowerManagerService extends SystemService return false; } - private void releaseAllOverrideWakeLocks() { + private void releaseAllOverrideWakeLocks(int releaseReason) { synchronized (mLock) { final int size = mWakeLocks.size(); boolean change = false; @@ -7277,7 +7289,7 @@ public final class PowerManagerService extends SystemService final WakeLock wakeLock = mWakeLocks.get(i); if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) == PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) { - removeWakeLockNoUpdateLocked(wakeLock, i); + removeWakeLockNoUpdateLocked(wakeLock, i, releaseReason); change = true; } } diff --git a/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java b/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java index adde5189115c..dcb3c398db68 100644 --- a/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java +++ b/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java @@ -23,6 +23,7 @@ import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIG import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_DIM; import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE; +import android.annotation.IntDef; import android.content.Context; import android.os.PowerManager; import android.util.IndentingPrintWriter; @@ -31,6 +32,8 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * Policy that handle the screen timeout override wake lock behavior. @@ -50,25 +53,62 @@ final class ScreenTimeoutOverridePolicy { public static final int RELEASE_REASON_NON_INTERACTIVE = 1; /** - * Release reason code: Release because user activity occurred. + * Release reason code: Release because a screen lock is acquired. */ - public static final int RELEASE_REASON_USER_ACTIVITY = 2; + public static final int RELEASE_REASON_SCREEN_LOCK = 2; + /** - * Release reason code: Release because a screen lock is acquired. + * Release reason code: Release because user activity attention occurs. + */ + public static final int RELEASE_REASON_USER_ACTIVITY_ATTENTION = 3; + + /** + * Release reason code: Release because user activity other occurs. + */ + public static final int RELEASE_REASON_USER_ACTIVITY_OTHER = 4; + + /** + * Release reason code: Release because user activity button occurs. + */ + public static final int RELEASE_REASON_USER_ACTIVITY_BUTTON = 5; + + /** + * Release reason code: Release because user activity touch occurs. + */ + public static final int RELEASE_REASON_USER_ACTIVITY_TOUCH = 6; + + /** + * Release reason code: Release because user activity accessibility occurs. + */ + public static final int RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY = 7; + + /** + * @hide */ - public static final int RELEASE_REASON_SCREEN_LOCK = 3; + @IntDef(prefix = { "RELEASE_REASON_" }, value = { + RELEASE_REASON_UNKNOWN, + RELEASE_REASON_NON_INTERACTIVE, + RELEASE_REASON_SCREEN_LOCK, + RELEASE_REASON_USER_ACTIVITY_ATTENTION, + RELEASE_REASON_USER_ACTIVITY_OTHER, + RELEASE_REASON_USER_ACTIVITY_BUTTON, + RELEASE_REASON_USER_ACTIVITY_TOUCH, + RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ReleaseReason{} // The screen timeout override config in milliseconds. private long mScreenTimeoutOverrideConfig; // The last reason that wake locks had been released by service. - private int mLastAutoReleaseReason = RELEASE_REASON_UNKNOWN; + private @ReleaseReason int mLastAutoReleaseReason = RELEASE_REASON_UNKNOWN; interface PolicyCallback { /** * Notify {@link PowerManagerService} to release all override wake locks. */ - void releaseAllScreenTimeoutOverrideWakelocks(); + void releaseAllScreenTimeoutOverrideWakelocks(@ReleaseReason int reason); } private PolicyCallback mPolicyCallback; @@ -110,11 +150,20 @@ final class ScreenTimeoutOverridePolicy { switch (event) { case PowerManager.USER_ACTIVITY_EVENT_ATTENTION: + releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_ATTENTION); + return; case PowerManager.USER_ACTIVITY_EVENT_OTHER: + releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_OTHER); + return; case PowerManager.USER_ACTIVITY_EVENT_BUTTON: + releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_BUTTON); + return; case PowerManager.USER_ACTIVITY_EVENT_TOUCH: + releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_TOUCH); + return; case PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY: - releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY); + releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY); + return; } } @@ -154,8 +203,8 @@ final class ScreenTimeoutOverridePolicy { + " (reason=" + mLastAutoReleaseReason + ")"); } - private void releaseAllWakeLocks(int reason) { - mPolicyCallback.releaseAllScreenTimeoutOverrideWakelocks(); + private void releaseAllWakeLocks(@ReleaseReason int reason) { + mPolicyCallback.releaseAllScreenTimeoutOverrideWakelocks(reason); mLastAutoReleaseReason = reason; logReleaseReason(); } diff --git a/services/core/java/com/android/server/power/WakefulnessSessionObserver.java b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java new file mode 100644 index 000000000000..d57cd5df41db --- /dev/null +++ b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java @@ -0,0 +1,595 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.power; + +import static android.os.PowerManager.USER_ACTIVITY_EVENT_OTHER; +import static android.os.PowerManagerInternal.isInteractive; + +import static com.android.server.power.PowerManagerService.DEFAULT_SCREEN_OFF_TIMEOUT; +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_NON_INTERACTIVE; +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_SCREEN_LOCK; +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN; +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY; +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_ATTENTION; +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_BUTTON; +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_OTHER; +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_TOUCH; + +import android.annotation.IntDef; +import android.app.ActivityManager; +import android.app.SynchronousUserSwitchObserver; +import android.content.Context; +import android.database.ContentObserver; +import android.os.Handler; +import android.os.PowerManager; +import android.os.PowerManagerInternal; +import android.os.RemoteException; +import android.os.SystemClock; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.IndentingPrintWriter; +import android.util.SparseArray; +import android.view.Display; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.FrameworkStatsLog; + +import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Observe the wakefulness session of the device, tracking the reason and the + * last user activity when the interactive state is off. + */ +public class WakefulnessSessionObserver { + private static final String TAG = "WakefulnessSessionObserver"; + + private static final int OFF_REASON_UNKNOWN = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__UNKNOWN; + private static final int OFF_REASON_TIMEOUT = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__TIMEOUT; + @VisibleForTesting + protected static final int OFF_REASON_POWER_BUTTON = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__POWER_BUTTON; + + /** + * Interactive off reason + * {@link android.os.statsd.power.ScreenInteractiveSessionReported.InteractiveStateOffReason}. + */ + @IntDef(prefix = {"OFF_REASON_"}, value = { + OFF_REASON_UNKNOWN, + OFF_REASON_TIMEOUT, + OFF_REASON_POWER_BUTTON + }) + @Retention(RetentionPolicy.SOURCE) + private @interface OffReason {} + + private static final int OVERRIDE_OUTCOME_UNKNOWN = FrameworkStatsLog + .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__UNKNOWN; + @VisibleForTesting + protected static final int OVERRIDE_OUTCOME_TIMEOUT_SUCCESS = FrameworkStatsLog + .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__TIMEOUT_SUCCESS; + @VisibleForTesting + protected static final int OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT = FrameworkStatsLog + .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__TIMEOUT_USER_INITIATED_REVERT; + private static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_API_CALL = FrameworkStatsLog + .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_CLIENT_API_CALL; + @VisibleForTesting + protected static final int OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION = FrameworkStatsLog + .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_USER_INTERACTION; + @VisibleForTesting + protected static final int OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON = FrameworkStatsLog + .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_POWER_BUTTON; + private static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT = FrameworkStatsLog + .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_CLIENT_DISCONNECTED; + private static final int OVERRIDE_OUTCOME_CANCEL_OTHER = FrameworkStatsLog + .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_OTHER; + + /** + * Override Outcome + * {@link android.os.statsd.power.ScreenTimeoutOverrideReported.OverrideOutcome}. + */ + @IntDef(prefix = {"OVERRIDE_OUTCOME_"}, value = { + OVERRIDE_OUTCOME_UNKNOWN, + OVERRIDE_OUTCOME_TIMEOUT_SUCCESS, + OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT, + OVERRIDE_OUTCOME_CANCEL_CLIENT_API_CALL, + OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION, + OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON, + OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT, + OVERRIDE_OUTCOME_CANCEL_OTHER + }) + @Retention(RetentionPolicy.SOURCE) + private @interface OverrideOutcome {} + + private static final int DEFAULT_USER_ACTIVITY = USER_ACTIVITY_EVENT_OTHER; + private static final long TIMEOUT_USER_INITIATED_REVERT_THRESHOLD_MILLIS = 5000L; + private static final long SEND_OVERRIDE_TIMEOUT_LOG_THRESHOLD_MILLIS = 1000L; + + private Context mContext; + private int mScreenOffTimeoutMs; + private int mOverrideTimeoutMs = 0; + @VisibleForTesting + protected final SparseArray<WakefulnessSessionPowerGroup> mPowerGroups = new SparseArray<>(); + @VisibleForTesting + protected WakefulnessSessionFrameworkStatsLogger mWakefulnessSessionFrameworkStatsLogger; + private final Clock mClock; + private final Object mLock = new Object(); + + public WakefulnessSessionObserver(Context context, Injector injector) { + if (injector == null) { + injector = new Injector(); + } + + mContext = context; + mWakefulnessSessionFrameworkStatsLogger = injector + .getWakefulnessSessionFrameworkStatsLogger(); + mClock = injector.getClock(); + updateSettingScreenOffTimeout(context); + + try { + final UserSwitchObserver observer = new UserSwitchObserver(); + ActivityManager.getService().registerUserSwitchObserver(observer, TAG); + } catch (RemoteException e) { + // Shouldn't happen since in-process. + } + + mOverrideTimeoutMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_screenTimeoutOverride); + + mContext.getContentResolver() + .registerContentObserver( + Settings.System.getUriFor(Settings.System.SCREEN_OFF_TIMEOUT), + false, + new ContentObserver(new Handler(mContext.getMainLooper())) { + @Override + public void onChange(boolean selfChange) { + updateSettingScreenOffTimeout(mContext); + } + }, + UserHandle.USER_ALL); + + mPowerGroups.append( + Display.DEFAULT_DISPLAY_GROUP, + new WakefulnessSessionPowerGroup(Display.DEFAULT_DISPLAY_GROUP)); + } + + /** + * Track the user activity event. + * + * @param eventTime Activity time, in uptime millis. + * @param powerGroupId Power Group Id for this user activity + * @param event Activity type as defined in {@link PowerManager}. {@link + * android.hardware.display.DisplayManagerInternal.DisplayPowerRequest} + */ + public void notifyUserActivity( + long eventTime, int powerGroupId, @PowerManager.UserActivityEvent int event) { + if (!mPowerGroups.contains(powerGroupId)) { + mPowerGroups.append(powerGroupId, new WakefulnessSessionPowerGroup(powerGroupId)); + } + mPowerGroups.get(powerGroupId).notifyUserActivity(eventTime, event); + } + + /** + * Track the system wakefulness + * + * @param powerGroupId Power Group Id for this wakefulness changes + * @param wakefulness Wakefulness as defined in {@link PowerManagerInternal} + * @param changeReason Reason of the go to sleep in + * {@link PowerManager.GoToSleepReason} or {@link PowerManager.WakeReason} + * @param eventTime timestamp of the wakefulness changes + */ + public void onWakefulnessChangeStarted(int powerGroupId, int wakefulness, int changeReason, + long eventTime) { + if (!mPowerGroups.contains(powerGroupId)) { + mPowerGroups.append(powerGroupId, new WakefulnessSessionPowerGroup(powerGroupId)); + } + mPowerGroups.get(powerGroupId).onWakefulnessChangeStarted(wakefulness, changeReason, + eventTime); + } + + /** + * Track the acquired wakelocks + * + * @param flags wakelocks to be acquired {@link PowerManager} + */ + public void onWakeLockAcquired(int flags) { + int maskedFlag = flags & PowerManager.WAKE_LOCK_LEVEL_MASK; + if (maskedFlag == PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) { + for (int idx = 0; idx < mPowerGroups.size(); idx++) { + mPowerGroups.valueAt(idx).acquireTimeoutOverrideWakeLock(); + } + } + } + + /** + * Track the released wakelocks + * + * @param flags wakelocks to be released {@link PowerManager} + * @param releaseReason the reason to release wakelock + * {@link ScreenTimeoutOverridePolicy.ReleaseReason} + */ + public void onWakeLockReleased(int flags, int releaseReason) { + int maskedFlag = flags & PowerManager.WAKE_LOCK_LEVEL_MASK; + if (maskedFlag == PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) { + for (int idx = 0; idx < mPowerGroups.size(); idx++) { + mPowerGroups.valueAt(idx).releaseTimeoutOverrideWakeLock(releaseReason); + } + } + } + + /** + * Remove the inactive power group + * + * @param powerGroupId Power Group Id that should be removed + */ + public void removePowerGroup(int powerGroupId) { + if (mPowerGroups.contains((powerGroupId))) { + mPowerGroups.delete(powerGroupId); + } + } + + void dump(PrintWriter writer) { + writer.println(); + writer.println("Wakefulness Session Observer:"); + writer.println("default timeout: " + mScreenOffTimeoutMs); + writer.println("override timeout: " + mOverrideTimeoutMs); + IndentingPrintWriter indentingPrintWriter = new IndentingPrintWriter(writer); + indentingPrintWriter.increaseIndent(); + for (int idx = 0; idx < mPowerGroups.size(); idx++) { + mPowerGroups.valueAt(idx).dump(indentingPrintWriter); + } + writer.println(); + } + + private void updateSettingScreenOffTimeout(Context context) { + synchronized (mLock) { + mScreenOffTimeoutMs = Settings.System.getIntForUser( + context.getContentResolver(), + Settings.System.SCREEN_OFF_TIMEOUT, + DEFAULT_SCREEN_OFF_TIMEOUT, + UserHandle.USER_CURRENT); + } + } + + private int getScreenOffTimeout() { + synchronized (mLock) { + return mScreenOffTimeoutMs; + } + } + + /** Screen Session by each power group */ + @VisibleForTesting + protected class WakefulnessSessionPowerGroup { + private static final long TIMEOUT_OFF_RESET_TIMESTAMP = -1; + + private int mPowerGroupId; + private int mCurrentWakefulness; + private boolean mIsInteractive = false; + // state on start timestamp: will be used in state off to calculate the duration of state on + private long mInteractiveStateOnStartTimestamp; + @VisibleForTesting + protected long mCurrentUserActivityTimestamp; + @VisibleForTesting + protected @PowerManager.UserActivityEvent int mCurrentUserActivityEvent; + @VisibleForTesting + protected long mPrevUserActivityTimestamp; + @VisibleForTesting + protected @PowerManager.UserActivityEvent int mPrevUserActivityEvent; + // to track the Override Timeout is set (that is, on SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) + private int mTimeoutOverrideWakeLockCounter = 0; + // The timestamp when Override Timeout is set to false + private @ScreenTimeoutOverridePolicy.ReleaseReason int mTimeoutOverrideReleaseReason; + // The timestamp when state off by timeout occurs + // will set TIMEOUT_OFF_RESET_TIMESTAMP if state on or state off by power button + private long mTimeoutOffTimestamp; + // The timestamp for the latest logTimeoutOverrideEvent calling + private long mSendOverrideTimeoutLogTimestamp; + + public WakefulnessSessionPowerGroup(int powerGroupId) { + mCurrentUserActivityEvent = DEFAULT_USER_ACTIVITY; + mCurrentUserActivityTimestamp = -1; + mPrevUserActivityEvent = DEFAULT_USER_ACTIVITY; + mPrevUserActivityTimestamp = -1; + mPowerGroupId = powerGroupId; + } + + public void notifyUserActivity(long eventTime, @PowerManager.UserActivityEvent int event) { + // only track when user activity changes + if (event == mCurrentUserActivityEvent) { + return; + } + mPrevUserActivityEvent = mCurrentUserActivityEvent; + mCurrentUserActivityEvent = event; + mPrevUserActivityTimestamp = mCurrentUserActivityTimestamp; + mCurrentUserActivityTimestamp = eventTime; + } + + public void onWakefulnessChangeStarted(int wakefulness, int changeReason, long eventTime) { + mCurrentWakefulness = wakefulness; + if (mIsInteractive == isInteractive(wakefulness)) { + return; + } + + mIsInteractive = isInteractive(wakefulness); + if (mIsInteractive) { + mInteractiveStateOnStartTimestamp = eventTime; + + // Log the outcome of screen timeout override (USER INITIATED REVERT), + // when user initiates to revert the screen off state in a short period. + if (mTimeoutOffTimestamp != TIMEOUT_OFF_RESET_TIMESTAMP) { + long offToOnDurationMs = eventTime - mTimeoutOffTimestamp; + if (offToOnDurationMs < TIMEOUT_USER_INITIATED_REVERT_THRESHOLD_MILLIS) { + mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent( + mPowerGroupId, + OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT, + mOverrideTimeoutMs, + getScreenOffTimeout()); + mSendOverrideTimeoutLogTimestamp = eventTime; + } + mTimeoutOffTimestamp = TIMEOUT_OFF_RESET_TIMESTAMP; + } + } else { + int lastUserActivity = mCurrentUserActivityEvent; + long lastUserActivityDurationMs = eventTime - mCurrentUserActivityTimestamp; + @OffReason int interactiveStateOffReason = OFF_REASON_UNKNOWN; + int reducedInteractiveStateOnDurationMs = 0; + + if (changeReason == PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON) { + interactiveStateOffReason = OFF_REASON_POWER_BUTTON; + + // Power Off will be triggered by USER_ACTIVITY_EVENT_BUTTON + // The metric wants to record the previous activity before EVENT_BUTTON + lastUserActivity = mPrevUserActivityEvent; + lastUserActivityDurationMs = eventTime - mPrevUserActivityTimestamp; + + if (isInOverrideTimeout() + || mTimeoutOverrideReleaseReason == RELEASE_REASON_USER_ACTIVITY_BUTTON + ) { + mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent( + mPowerGroupId, + OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON, + mOverrideTimeoutMs, + getScreenOffTimeout()); + mSendOverrideTimeoutLogTimestamp = eventTime; + mTimeoutOverrideReleaseReason = RELEASE_REASON_UNKNOWN; // reset the reason + } + } else if (changeReason == PowerManager.GO_TO_SLEEP_REASON_TIMEOUT) { + // Interactive Off reason is timeout + interactiveStateOffReason = OFF_REASON_TIMEOUT; + + lastUserActivity = mCurrentUserActivityEvent; + lastUserActivityDurationMs = eventTime - mCurrentUserActivityTimestamp; + + // Log the outcome of screen timeout override when the early screen + // timeout has been done successfully. + if (isInOverrideTimeout()) { + reducedInteractiveStateOnDurationMs = + getScreenOffTimeout() - mOverrideTimeoutMs; + + mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent( + mPowerGroupId, + OVERRIDE_OUTCOME_TIMEOUT_SUCCESS, + mOverrideTimeoutMs, + getScreenOffTimeout()); + mSendOverrideTimeoutLogTimestamp = eventTime; + + // Record a timestamp to track if the user initiates to revert from off + // state instantly + mTimeoutOffTimestamp = eventTime; + } + } + + long interactiveStateOnDurationMs = + eventTime - mInteractiveStateOnStartTimestamp; + mWakefulnessSessionFrameworkStatsLogger.logSessionEvent( + mPowerGroupId, + interactiveStateOffReason, + interactiveStateOnDurationMs, + lastUserActivity, + lastUserActivityDurationMs, + reducedInteractiveStateOnDurationMs); + } + } + + public void acquireTimeoutOverrideWakeLock() { + synchronized (mLock) { + mTimeoutOverrideWakeLockCounter++; + } + } + + public void releaseTimeoutOverrideWakeLock( + @ScreenTimeoutOverridePolicy.ReleaseReason int releaseReason) { + synchronized (mLock) { + mTimeoutOverrideWakeLockCounter--; + } + + if (!isInOverrideTimeout()) { + mTimeoutOverrideReleaseReason = releaseReason; + long now = mClock.uptimeMillis(); + + // Log the outcome of screen timeout override (USER INTERACTIVE or DISCONNECT), + // when early screen timeout be canceled. + // Note: Set the threshold to avoid sending this log repeatly after other outcomes. + long sendOverrideTimeoutLogDuration = now - mSendOverrideTimeoutLogTimestamp; + boolean sendOverrideTimeoutLogSoon = sendOverrideTimeoutLogDuration + < SEND_OVERRIDE_TIMEOUT_LOG_THRESHOLD_MILLIS; + if (!sendOverrideTimeoutLogSoon) { + @OverrideOutcome int outcome = OVERRIDE_OUTCOME_UNKNOWN; + switch (releaseReason) { + case RELEASE_REASON_USER_ACTIVITY_ATTENTION: + case RELEASE_REASON_USER_ACTIVITY_OTHER: + case RELEASE_REASON_USER_ACTIVITY_BUTTON: + case RELEASE_REASON_USER_ACTIVITY_TOUCH: + case RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY: + outcome = OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION; + break; + case RELEASE_REASON_SCREEN_LOCK: + case RELEASE_REASON_NON_INTERACTIVE: + outcome = OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT; + break; + default: + outcome = OVERRIDE_OUTCOME_UNKNOWN; + } + mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent( + mPowerGroupId, + outcome, + mOverrideTimeoutMs, + getScreenOffTimeout()); + } + } + } + + @VisibleForTesting + protected boolean isInOverrideTimeout() { + synchronized (mLock) { + return (mTimeoutOverrideWakeLockCounter > 0); + } + } + + void dump(IndentingPrintWriter writer) { + final long now = mClock.uptimeMillis(); + + writer.println("Wakefulness Session Power Group powerGroupId: " + mPowerGroupId); + writer.increaseIndent(); + writer.println("current wakefulness: " + mCurrentWakefulness); + writer.println("current user activity event: " + mCurrentUserActivityEvent); + final long currentUserActivityDurationMs = now - mCurrentUserActivityTimestamp; + writer.println("current user activity duration: " + currentUserActivityDurationMs); + writer.println("previous user activity event: " + mPrevUserActivityEvent); + final long prevUserActivityDurationMs = now - mPrevUserActivityTimestamp; + writer.println("previous user activity duration: " + prevUserActivityDurationMs); + writer.println("is in override timeout: " + isInOverrideTimeout()); + writer.decreaseIndent(); + } + } + + /** Log screen session atoms */ + protected static class WakefulnessSessionFrameworkStatsLogger { + public void logSessionEvent( + int powerGroupId, + @OffReason int interactiveStateOffReason, + long interactiveStateOnDurationMs, + @PowerManager.UserActivityEvent int userActivityEvent, + long lastUserActivityEventDurationMs, + int reducedInteractiveStateOnDurationMs) { + int logUserActivityEvent = convertToLogUserActivityEvent(userActivityEvent); + FrameworkStatsLog.write( + FrameworkStatsLog.SCREEN_INTERACTIVE_SESSION_REPORTED, + powerGroupId, + interactiveStateOffReason, + interactiveStateOnDurationMs, + logUserActivityEvent, + lastUserActivityEventDurationMs, + (long) reducedInteractiveStateOnDurationMs); + } + + public void logTimeoutOverrideEvent( + int powerGroupId, + @OverrideOutcome int overrideOutcome, + int overrideTimeoutMs, + int defaultTimeoutMs) { + FrameworkStatsLog.write( + FrameworkStatsLog.SCREEN_TIMEOUT_OVERRIDE_REPORTED, + powerGroupId, + overrideOutcome, + (long) overrideTimeoutMs, + (long) defaultTimeoutMs); + } + + private static final int USER_ACTIVITY_OTHER = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__OTHER; + + private static final int USER_ACTIVITY_BUTTON = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__BUTTON; + + private static final int USER_ACTIVITY_TOUCH = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__TOUCH; + + private static final int USER_ACTIVITY_ACCESSIBILITY = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__ACCESSIBILITY; + private static final int USER_ACTIVITY_ATTENTION = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__ATTENTION; + private static final int USER_ACTIVITY_FACE_DOWN = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__FACE_DOWN; + + private static final int USER_ACTIVITY_DEVICE_STATE = FrameworkStatsLog + .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__DEVICE_STATE; + + /** + * User Activity Event + * {@link android.os.statsd.power.ScreenInteractiveSessionReported.UserActivityEvent}. + */ + @IntDef(prefix = {"USER_ACTIVITY_"}, value = { + USER_ACTIVITY_OTHER, + USER_ACTIVITY_BUTTON, + USER_ACTIVITY_TOUCH, + USER_ACTIVITY_ACCESSIBILITY, + USER_ACTIVITY_ATTENTION, + USER_ACTIVITY_FACE_DOWN, + USER_ACTIVITY_DEVICE_STATE, + }) + @Retention(RetentionPolicy.SOURCE) + private @interface UserActivityEvent {} + + private @UserActivityEvent int convertToLogUserActivityEvent( + @PowerManager.UserActivityEvent int userActivity) { + switch (userActivity) { + case PowerManager.USER_ACTIVITY_EVENT_OTHER: + return USER_ACTIVITY_OTHER; + case PowerManager.USER_ACTIVITY_EVENT_BUTTON: + return USER_ACTIVITY_BUTTON; + case PowerManager.USER_ACTIVITY_EVENT_TOUCH: + return USER_ACTIVITY_TOUCH; + case PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY: + return USER_ACTIVITY_ACCESSIBILITY; + case PowerManager.USER_ACTIVITY_EVENT_ATTENTION: + return USER_ACTIVITY_ATTENTION; + case PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN: + return USER_ACTIVITY_FACE_DOWN; + case PowerManager.USER_ACTIVITY_EVENT_DEVICE_STATE: + return USER_ACTIVITY_DEVICE_STATE; + } + return USER_ACTIVITY_OTHER; + } + } + + /** To observe and do actions if users switch */ + private final class UserSwitchObserver extends SynchronousUserSwitchObserver { + @Override + public void onUserSwitching(int newUserId) throws RemoteException { + updateSettingScreenOffTimeout(mContext); + } + } + + @VisibleForTesting + interface Clock { + long uptimeMillis(); + } + + @VisibleForTesting + static class Injector { + WakefulnessSessionFrameworkStatsLogger getWakefulnessSessionFrameworkStatsLogger() { + return new WakefulnessSessionFrameworkStatsLogger(); + } + + Clock getClock() { + return SystemClock::uptimeMillis; + } + } +} 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 6e17fd3d8c87..4ddd54623e8c 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 @@ public final class HintManagerService extends SystemService { @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 @@ public final class HintManagerService extends SystemService { @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 @@ public final class HintManagerService extends SystemService { @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 @@ public final class HintManagerService extends SystemService { @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 @@ public final class HintManagerService extends SystemService { } 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 @@ public final class HintManagerService extends SystemService { } } - 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/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java index ad54efcd11d3..84c37180d93c 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 @@ abstract class Vibration { 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 8281ac1c9d28..09c24931d641 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 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { 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 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { /** 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 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } 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 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { 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 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { 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 fe4522acc148..c5683f31f3e7 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.view.RemoteAnimationDefinition; 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.KnownPackages; 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 @@ class ActivityClientController extends IActivityClientController.Stub { 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 @@ class ActivityClientController extends IActivityClientController.Stub { + ": 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 b3c43bc33edd..fc05d17cb5f2 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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { 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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { .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/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 622a80920526..6003c1b897b4 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 @@ class RootWindowContainer extends WindowContainer<DisplayContent> 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 @@ class RootWindowContainer extends WindowContainer<DisplayContent> 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 de7c0eb22321..616ab882745b 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.AnimationThread; 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 @@ public class WindowManagerService extends IWindowManager.Stub /** * 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 @@ public class WindowManagerService extends IWindowManager.Stub } } } + + 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/dreamservicetests/Android.bp b/services/tests/dreamservicetests/Android.bp index 86b3a6cc2b35..6369d4564bf2 100644 --- a/services/tests/dreamservicetests/Android.bp +++ b/services/tests/dreamservicetests/Android.bp @@ -18,7 +18,9 @@ android_test { "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 293ab7baa355..23314cdaf041 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 @@ package com.android.server.dreams; 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 @@ import org.junit.runner.RunWith; 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 @@ public class DreamServiceTest { 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 000000000000..ef85ba56769e --- /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 959078326f6b..cc69c1dbf999 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 @@ public class MockingOomAdjusterTests { 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 @@ public class MockingOomAdjusterTests { 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 @@ public class MockingOomAdjusterTests { 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/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java index 67409a424edb..5c74a800841f 100644 --- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java @@ -1067,7 +1067,7 @@ public class PowerManagerServiceTest { wakelockMap.remove((String) inv.getArguments()[1]); return null; }).when(mNotifierMock).onWakeLockReleased(anyInt(), anyString(), anyString(), anyInt(), - anyInt(), any(), any(), any()); + anyInt(), any(), any(), any(), anyInt()); // // TEST STARTS HERE @@ -2777,7 +2777,7 @@ public class PowerManagerServiceTest { mService.getBinderServiceInstance().releaseWakeLock(token, 0); verify(mNotifierMock).onWakeLockReleased(anyInt(), eq(tag), eq(packageName), anyInt(), - anyInt(), any(), any(), same(callback)); + anyInt(), any(), any(), same(callback), anyInt()); } /** @@ -2796,8 +2796,8 @@ public class PowerManagerServiceTest { when(callback1.asBinder()).thenReturn(callbackBinder1); mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName, null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, callback1); - verify(mNotifierMock).onWakeLockAcquired(anyInt(), eq(tag), eq(packageName), anyInt(), - anyInt(), any(), any(), same(callback1)); + verify(mNotifierMock).onWakeLockAcquired(anyInt(), eq(tag), eq(packageName), + anyInt(), anyInt(), any(), any(), same(callback1)); final IWakeLockCallback callback2 = Mockito.mock(IWakeLockCallback.class); final IBinder callbackBinder2 = Mockito.mock(Binder.class); @@ -2810,7 +2810,7 @@ public class PowerManagerServiceTest { mService.getBinderServiceInstance().releaseWakeLock(token, 0); verify(mNotifierMock).onWakeLockReleased(anyInt(), eq(tag), eq(packageName), anyInt(), - anyInt(), any(), any(), same(callback2)); + anyInt(), any(), any(), same(callback2), anyInt()); } @Test diff --git a/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java b/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java new file mode 100644 index 000000000000..698f094c8796 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java @@ -0,0 +1,323 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.power; + +import static android.os.PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON; +import static android.os.PowerManager.GO_TO_SLEEP_REASON_TIMEOUT; +import static android.os.PowerManager.WAKE_REASON_POWER_BUTTON; + +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN; +import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_TOUCH; +import static com.android.server.power.WakefulnessSessionObserver.OFF_REASON_POWER_BUTTON; +import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON; +import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION; +import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_TIMEOUT_SUCCESS; +import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; +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.Context; +import android.content.ContextWrapper; +import android.content.res.Resources; +import android.os.PowerManager; +import android.os.PowerManagerInternal; +import android.os.UserHandle; +import android.provider.Settings; +import android.test.mock.MockContentResolver; + +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.util.test.FakeSettingsProvider; +import com.android.server.testutils.OffsettableClock; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class WakefulnessSessionObserverTest { + private static final int DEFAULT_SCREEN_OFF_TIMEOUT_MS = 30000; + private static final int OVERRIDE_SCREEN_OFF_TIMEOUT_MS = 15000; + private WakefulnessSessionObserver mWakefulnessSessionObserver; + private Context mContext; + private OffsettableClock mTestClock; + @Mock + private WakefulnessSessionObserver.WakefulnessSessionFrameworkStatsLogger + mWakefulnessSessionFrameworkStatsLogger; + private WakefulnessSessionObserver.Injector mInjector = + new WakefulnessSessionObserver.Injector() { + @Override + WakefulnessSessionObserver.WakefulnessSessionFrameworkStatsLogger + getWakefulnessSessionFrameworkStatsLogger() { + return mWakefulnessSessionFrameworkStatsLogger; + } + @Override + WakefulnessSessionObserver.Clock getClock() { + return mTestClock::now; + } + }; + + @Before + public void setUp() { + mTestClock = new OffsettableClock.Stopped(); + + MockitoAnnotations.initMocks(this); + mContext = spy(new ContextWrapper( + InstrumentationRegistry.getInstrumentation().getTargetContext())); + doReturn(mContext).when(mContext).getApplicationContext(); + + final Resources res = spy(mContext.getResources()); + doReturn(OVERRIDE_SCREEN_OFF_TIMEOUT_MS).when(res).getInteger( + com.android.internal.R.integer.config_screenTimeoutOverride); + when(mContext.getResources()).thenReturn(res); + FakeSettingsProvider.clearSettingsProvider(); + MockContentResolver mockContentResolver = new MockContentResolver(); + mockContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); + when(mContext.getContentResolver()).thenReturn(mockContentResolver); + Settings.System.putIntForUser(mockContentResolver, Settings.System.SCREEN_OFF_TIMEOUT, + DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT); + + mWakefulnessSessionObserver = new WakefulnessSessionObserver(mContext, mInjector); + } + + @After + public void tearDown() { + FakeSettingsProvider.clearSettingsProvider(); + } + + @Test + public void testOnUserActivity_updateActivity() { + int firstActivity = PowerManager.USER_ACTIVITY_EVENT_BUTTON; + long firstActivityTimestamp = mTestClock.now(); + int powerGroupId = 1; + mWakefulnessSessionObserver.notifyUserActivity( + firstActivityTimestamp, powerGroupId, firstActivity); + assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId) + .mCurrentUserActivityEvent).isEqualTo(firstActivity); + + int newActivity = PowerManager.USER_ACTIVITY_EVENT_ATTENTION; + advanceTime(10L); + long newActivityTimestamp = mTestClock.now(); + mWakefulnessSessionObserver.notifyUserActivity( + newActivityTimestamp, powerGroupId, newActivity); + assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId) + .mCurrentUserActivityEvent).isEqualTo(newActivity); + assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId) + .mCurrentUserActivityTimestamp).isEqualTo(newActivityTimestamp); + assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId) + .mPrevUserActivityEvent).isEqualTo(firstActivity); + assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId) + .mPrevUserActivityTimestamp).isEqualTo(firstActivityTimestamp); + + int otherPowerGroupId = 2; + mWakefulnessSessionObserver.notifyUserActivity( + firstActivityTimestamp, otherPowerGroupId, firstActivity); + assertThat(mWakefulnessSessionObserver.mPowerGroups.get(otherPowerGroupId) + .mCurrentUserActivityEvent).isEqualTo(firstActivity); + assertThat(mWakefulnessSessionObserver.mPowerGroups.get(otherPowerGroupId) + .mCurrentUserActivityTimestamp).isEqualTo(firstActivityTimestamp); + } + + @Test + public void testOnWakeLockAcquired() { + mWakefulnessSessionObserver.onWakeLockAcquired(PowerManager.DOZE_WAKE_LOCK); + for (int idx = 0; idx < mWakefulnessSessionObserver.mPowerGroups.size(); idx++) { + assertThat(mWakefulnessSessionObserver.mPowerGroups.valueAt(idx).isInOverrideTimeout()) + .isFalse(); + } + + mWakefulnessSessionObserver.onWakeLockAcquired( + PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK); + for (int idx = 0; idx < mWakefulnessSessionObserver.mPowerGroups.size(); idx++) { + assertThat(mWakefulnessSessionObserver.mPowerGroups.valueAt(idx).isInOverrideTimeout()) + .isTrue(); + } + } + + @Test + public void testOnWakeLockReleased() { + mWakefulnessSessionObserver.onWakeLockReleased( + PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK, RELEASE_REASON_UNKNOWN); + for (int idx = 0; idx < mWakefulnessSessionObserver.mPowerGroups.size(); idx++) { + assertThat(mWakefulnessSessionObserver.mPowerGroups.valueAt(idx).isInOverrideTimeout()) + .isFalse(); + } + } + + @Test + public void testOnWakefulnessChangeStarted_onDozing_UserActivityAttention_OverrideTimeout() { + int powerGroupId = 1; + mWakefulnessSessionObserver.onWakefulnessChangeStarted( + powerGroupId, + PowerManagerInternal.WAKEFULNESS_AWAKE, + WAKE_REASON_POWER_BUTTON, + mTestClock.now()); + mWakefulnessSessionObserver.notifyUserActivity( + mTestClock.now(), powerGroupId, PowerManager.USER_ACTIVITY_EVENT_ATTENTION); + mWakefulnessSessionObserver.onWakeLockAcquired( + PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK); + mWakefulnessSessionObserver.onWakefulnessChangeStarted( + powerGroupId, + PowerManagerInternal.WAKEFULNESS_DOZING, + GO_TO_SLEEP_REASON_TIMEOUT, + mTestClock.now()); + + verify(mWakefulnessSessionFrameworkStatsLogger) + .logTimeoutOverrideEvent( + powerGroupId, // powerGroupId + OVERRIDE_OUTCOME_TIMEOUT_SUCCESS, // overrideOutcome + OVERRIDE_SCREEN_OFF_TIMEOUT_MS, // override timeout ms + DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default timeout ms + } + + @Test + public void testOnWakefulnessChangeStarted_onDozing_UserActivityButton() { + advanceTime(5000L); // reset current timestamp for new test case + int powerGroupId = 2; + mWakefulnessSessionObserver.onWakefulnessChangeStarted( + powerGroupId, + PowerManagerInternal.WAKEFULNESS_AWAKE, + WAKE_REASON_POWER_BUTTON, + mTestClock.now()); + + int userActivity = PowerManager.USER_ACTIVITY_EVENT_DEVICE_STATE; + long userActivityTime = mTestClock.now(); + mWakefulnessSessionObserver.notifyUserActivity( + userActivityTime, powerGroupId, userActivity); + long advancedTime = 10L; + advanceTime(advancedTime); + mWakefulnessSessionObserver.notifyUserActivity( + userActivityTime, powerGroupId, PowerManager.USER_ACTIVITY_EVENT_BUTTON); + mWakefulnessSessionObserver.onWakefulnessChangeStarted( + powerGroupId, + PowerManagerInternal.WAKEFULNESS_DOZING, + GO_TO_SLEEP_REASON_POWER_BUTTON, + mTestClock.now()); + + verify(mWakefulnessSessionFrameworkStatsLogger) + .logSessionEvent( + powerGroupId, // powerGroupId + OFF_REASON_POWER_BUTTON, // interactiveStateOffReason + advancedTime, // interactiveStateOnDurationMs + userActivity, // userActivity + advancedTime, // lastUserActivityEventDurationMs + 0); // reducedInteractiveStateOnDurationMs; + + verify(mWakefulnessSessionFrameworkStatsLogger, never()) + .logTimeoutOverrideEvent(anyInt(), anyInt(), anyInt(), anyInt()); + } + + @Test + public void testOnWakefulnessChangeStarted_onDozing_UserActivityButton_OverrideTimeout() { + int powerGroupId = 1; + mWakefulnessSessionObserver.onWakefulnessChangeStarted( + powerGroupId, + PowerManagerInternal.WAKEFULNESS_AWAKE, + WAKE_REASON_POWER_BUTTON, + mTestClock.now()); + mWakefulnessSessionObserver.onWakeLockAcquired( + PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK); + + int userActivity = PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY; + long userActivityTime = mTestClock.now(); + mWakefulnessSessionObserver.notifyUserActivity( + userActivityTime, powerGroupId, userActivity); + long advancedTime = 10L; + advanceTime(advancedTime); + mWakefulnessSessionObserver.notifyUserActivity( + userActivityTime, powerGroupId, PowerManager.USER_ACTIVITY_EVENT_BUTTON); + mWakefulnessSessionObserver.onWakefulnessChangeStarted( + powerGroupId, + PowerManagerInternal.WAKEFULNESS_DOZING, + GO_TO_SLEEP_REASON_POWER_BUTTON, + mTestClock.now()); + + verify(mWakefulnessSessionFrameworkStatsLogger) + .logTimeoutOverrideEvent( + powerGroupId, // powerGroupId + OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON, // overrideOutcome + OVERRIDE_SCREEN_OFF_TIMEOUT_MS, // override timeout ms + DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default timeout ms + + verify(mWakefulnessSessionFrameworkStatsLogger) + .logSessionEvent( + powerGroupId, // powerGroupId + OFF_REASON_POWER_BUTTON, // interactiveStateOffReason + advancedTime, // interactiveStateOnDurationMs + userActivity, // userActivity + advancedTime, // lastUserActivityEventDurationMs + 0); // reducedInteractiveStateOnDurationMs; + } + + @Test + public void testOnWakefulnessChangeStarted_inTimeoutOverride_onAwake_After_onDozing() { + int powerGroupId = 1; + mWakefulnessSessionObserver.onWakeLockAcquired( + PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK); + + mWakefulnessSessionObserver.onWakefulnessChangeStarted( + powerGroupId, PowerManagerInternal.WAKEFULNESS_DOZING, + GO_TO_SLEEP_REASON_TIMEOUT, mTestClock.now()); + // awake after dozing + advanceTime(10L); + mWakefulnessSessionObserver.onWakefulnessChangeStarted( + powerGroupId, PowerManagerInternal.WAKEFULNESS_AWAKE, + WAKE_REASON_POWER_BUTTON, mTestClock.now()); + + verify(mWakefulnessSessionFrameworkStatsLogger) + .logTimeoutOverrideEvent( + powerGroupId, // powerGroupId + OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT, // overrideOutcome + OVERRIDE_SCREEN_OFF_TIMEOUT_MS, // override timeout ms + DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default timeout ms + } + + @Test + public void testOnWakeLockReleased_UserActivityTouch() { + int powerGroupId = 0; + mWakefulnessSessionObserver.onWakeLockAcquired( + PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK); + advanceTime(5000L); + mWakefulnessSessionObserver.onWakeLockReleased( + PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK, + RELEASE_REASON_USER_ACTIVITY_TOUCH); + + verify(mWakefulnessSessionFrameworkStatsLogger) + .logTimeoutOverrideEvent( + powerGroupId, // powerGroupId + OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION, // overrideOutcome + OVERRIDE_SCREEN_OFF_TIMEOUT_MS, // override timeout ms + DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default timeout ms + } + + private void advanceTime(long timeMs) { + mTestClock.fastForward(timeMs); + } +} 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 dcf3dadcf5a3..7756edd68eda 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 @@ public class RootWindowContainerTests extends WindowTestsBase { // 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 43b424fab907..fb854c5bda68 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 @@ public class WindowOrganizerTests extends WindowTestsBase { 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 b00571585d00..40ad3122f2fb 100644 --- a/telephony/java/android/telephony/satellite/SatelliteManager.java +++ b/telephony/java/android/telephony/satellite/SatelliteManager.java @@ -959,6 +959,11 @@ public final class SatelliteManager { */ 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 @@ public final class SatelliteManager { 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 063088d54b45..03f3a68a573f 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 @@ class ShowImeOnAppStartWhenLaunchingAppFromOverviewTest(flicker: LegacyFlickerTe 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 b4e2758f4abe..4c8193990feb 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -227,56 +227,3 @@ genrule { ], }, } - -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/CompileTest/ && " + - "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/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt index 76bac9286a1f..16785d1d9598 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 @@ private fun ClassNodes.isAidlClass(className: String): Boolean { } /** + * 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 @@ private fun ClassNodes.isFeatureFlagsClass(className: String): Boolean { return className.endsWith("/Flags") || className.endsWith("/FeatureFlags") || className.endsWith("/FeatureFlagsImpl") + || className.endsWith("/CustomFeatureFlags") || className.endsWith("/FakeFeatureFlagsImpl"); } |