diff options
162 files changed, 2257 insertions, 1038 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java index 2e6b8bdb0ad4..fd2bb1347fd3 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java @@ -123,6 +123,7 @@ class Alarm { public AlarmManagerService.PriorityClass priorityClass; /** Broadcast options to use when delivering this alarm */ public Bundle mIdleOptions; + public boolean mUsingReserveQuota; Alarm(int type, long when, long requestedWhenElapsed, long windowLength, long interval, PendingIntent op, IAlarmListener rec, String listenerTag, WorkSource ws, int flags, @@ -151,6 +152,7 @@ class Alarm { mExactAllowReason = exactAllowReason; sourcePackage = (operation != null) ? operation.getCreatorPackage() : packageName; creatorUid = (operation != null) ? operation.getCreatorUid() : this.uid; + mUsingReserveQuota = false; } public static String makeTag(PendingIntent pi, String tag, int type) { @@ -340,6 +342,9 @@ class Alarm { TimeUtils.formatDuration(getWhenElapsed(), nowELAPSED, ipw); ipw.print(" maxWhenElapsed="); TimeUtils.formatDuration(mMaxWhenElapsed, nowELAPSED, ipw); + if (mUsingReserveQuota) { + ipw.print(" usingReserveQuota=true"); + } ipw.println(); if (alarmClock != null) { diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index 7baf80502a3c..0de0a1cf9c8e 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -213,6 +213,8 @@ public class AlarmManagerService extends SystemService { static final int RARE_INDEX = 3; static final int NEVER_INDEX = 4; + private static final long TEMPORARY_QUOTA_DURATION = INTERVAL_DAY; + private final Intent mBackgroundIntent = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND); @@ -282,6 +284,7 @@ public class AlarmManagerService extends SystemService { AppWakeupHistory mAppWakeupHistory; AppWakeupHistory mAllowWhileIdleHistory; AppWakeupHistory mAllowWhileIdleCompatHistory; + TemporaryQuotaReserve mTemporaryQuotaReserve; private final SparseLongArray mLastPriorityAlarmDispatch = new SparseLongArray(); private final SparseArray<RingBuffer<RemovedAlarm>> mRemovalHistory = new SparseArray<>(); ClockReceiver mClockReceiver; @@ -359,6 +362,133 @@ public class AlarmManagerService extends SystemService { boolean mAppStandbyParole; /** + * Holds information about temporary quota that can be allotted to apps to use as a "reserve" + * when they run out of their standard app-standby quota. + * This reserve only lasts for a fixed duration of time from when it was last replenished. + */ + static class TemporaryQuotaReserve { + + private static class QuotaInfo { + public int remainingQuota; + public long expirationTime; + public long lastUsage; + } + /** Map of {package, user} -> {quotaInfo} */ + private final ArrayMap<Pair<String, Integer>, QuotaInfo> mQuotaBuffer = new ArrayMap<>(); + + private long mMaxDuration; + + TemporaryQuotaReserve(long maxDuration) { + mMaxDuration = maxDuration; + } + + void replenishQuota(String packageName, int userId, int quota, long nowElapsed) { + if (quota <= 0) { + return; + } + final Pair<String, Integer> packageUser = Pair.create(packageName, userId); + QuotaInfo currentQuotaInfo = mQuotaBuffer.get(packageUser); + if (currentQuotaInfo == null) { + currentQuotaInfo = new QuotaInfo(); + mQuotaBuffer.put(packageUser, currentQuotaInfo); + } + currentQuotaInfo.remainingQuota = quota; + currentQuotaInfo.expirationTime = nowElapsed + mMaxDuration; + } + + /** Returns if the supplied package has reserve quota to fire at the given time. */ + boolean hasQuota(String packageName, int userId, long triggerElapsed) { + final Pair<String, Integer> packageUser = Pair.create(packageName, userId); + final QuotaInfo quotaInfo = mQuotaBuffer.get(packageUser); + + return quotaInfo != null && quotaInfo.remainingQuota > 0 + && triggerElapsed <= quotaInfo.expirationTime; + } + + /** + * Records quota usage of the given package at the given time and subtracts quota if + * required. + */ + void recordUsage(String packageName, int userId, long nowElapsed) { + final Pair<String, Integer> packageUser = Pair.create(packageName, userId); + final QuotaInfo quotaInfo = mQuotaBuffer.get(packageUser); + + if (quotaInfo == null) { + Slog.wtf(TAG, "Temporary quota being consumed at " + nowElapsed + + " but not found for package: " + packageName + ", user: " + userId); + return; + } + // Only consume quota if this usage is later than the last one recorded. This is + // needed as this can be called multiple times when a batch of alarms is delivered. + if (nowElapsed > quotaInfo.lastUsage) { + if (quotaInfo.remainingQuota <= 0) { + Slog.wtf(TAG, "Temporary quota being consumed at " + nowElapsed + + " but remaining only " + quotaInfo.remainingQuota + + " for package: " + packageName + ", user: " + userId); + } else if (quotaInfo.expirationTime < nowElapsed) { + Slog.wtf(TAG, "Temporary quota being consumed at " + nowElapsed + + " but expired at " + quotaInfo.expirationTime + + " for package: " + packageName + ", user: " + userId); + } else { + quotaInfo.remainingQuota--; + // We keep the quotaInfo entry even if remaining quota reduces to 0 as + // following calls can be made with nowElapsed <= lastUsage. The object will + // eventually be removed in cleanUpExpiredQuotas or reused in replenishQuota. + } + quotaInfo.lastUsage = nowElapsed; + } + } + + /** Clean up any quotas that have expired before the given time. */ + void cleanUpExpiredQuotas(long nowElapsed) { + for (int i = mQuotaBuffer.size() - 1; i >= 0; i--) { + final QuotaInfo quotaInfo = mQuotaBuffer.valueAt(i); + if (quotaInfo.expirationTime < nowElapsed) { + mQuotaBuffer.removeAt(i); + } + } + } + + void removeForUser(int userId) { + for (int i = mQuotaBuffer.size() - 1; i >= 0; i--) { + final Pair<String, Integer> packageUserKey = mQuotaBuffer.keyAt(i); + if (packageUserKey.second == userId) { + mQuotaBuffer.removeAt(i); + } + } + } + + void removeForPackage(String packageName, int userId) { + final Pair<String, Integer> packageUser = Pair.create(packageName, userId); + mQuotaBuffer.remove(packageUser); + } + + void dump(IndentingPrintWriter pw, long nowElapsed) { + pw.increaseIndent(); + for (int i = 0; i < mQuotaBuffer.size(); i++) { + final Pair<String, Integer> packageUser = mQuotaBuffer.keyAt(i); + final QuotaInfo quotaInfo = mQuotaBuffer.valueAt(i); + pw.print(packageUser.first); + pw.print(", u"); + pw.print(packageUser.second); + pw.print(": "); + if (quotaInfo == null) { + pw.print("--"); + } else { + pw.print("quota: "); + pw.print(quotaInfo.remainingQuota); + pw.print(", expiration: "); + TimeUtils.formatDuration(quotaInfo.expirationTime, nowElapsed, pw); + pw.print(" last used: "); + TimeUtils.formatDuration(quotaInfo.lastUsage, nowElapsed, pw); + } + pw.println(); + } + pw.decreaseIndent(); + } + } + + /** * A container to keep rolling window history of previous times when an alarm was sent to * a package. */ @@ -569,6 +699,8 @@ public class AlarmManagerService extends SystemService { @VisibleForTesting static final String KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = "kill_on_schedule_exact_alarm_revoked"; + @VisibleForTesting + static final String KEY_TEMPORARY_QUOTA_BUMP = "temporary_quota_bump"; private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; @@ -613,6 +745,8 @@ public class AlarmManagerService extends SystemService { private static final boolean DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = true; + private static final int DEFAULT_TEMPORARY_QUOTA_BUMP = 0; + // Minimum futurity of a new alarm public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY; @@ -702,6 +836,17 @@ public class AlarmManagerService extends SystemService { public boolean USE_TARE_POLICY = Settings.Global.DEFAULT_ENABLE_TARE == 1; + /** + * The amount of temporary reserve quota to give apps on receiving the + * {@link AppIdleStateChangeListener#triggerTemporaryQuotaBump(String, int)} callback + * from {@link com.android.server.usage.AppStandbyController}. + * <p> This quota adds on top of the standard standby bucket quota available to the app, and + * works the same way, i.e. each count of quota denotes one point in time when the app can + * receive any number of alarms together. + * This quota is tracked per package and expires after {@link #TEMPORARY_QUOTA_DURATION}. + */ + public int TEMPORARY_QUOTA_BUMP = DEFAULT_TEMPORARY_QUOTA_BUMP; + private long mLastAllowWhileIdleWhitelistDuration = -1; private int mVersion = 0; @@ -886,6 +1031,10 @@ public class AlarmManagerService extends SystemService { KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED, DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED); break; + case KEY_TEMPORARY_QUOTA_BUMP: + TEMPORARY_QUOTA_BUMP = properties.getInt(KEY_TEMPORARY_QUOTA_BUMP, + DEFAULT_TEMPORARY_QUOTA_BUMP); + break; default: if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) { // The quotas need to be updated in order, so we can't just rely @@ -1136,6 +1285,9 @@ public class AlarmManagerService extends SystemService { pw.print(Settings.Global.ENABLE_TARE, USE_TARE_POLICY); pw.println(); + pw.print(KEY_TEMPORARY_QUOTA_BUMP, TEMPORARY_QUOTA_BUMP); + pw.println(); + pw.decreaseIndent(); } @@ -1748,6 +1900,8 @@ public class AlarmManagerService extends SystemService { mAllowWhileIdleHistory = new AppWakeupHistory(INTERVAL_HOUR); mAllowWhileIdleCompatHistory = new AppWakeupHistory(INTERVAL_HOUR); + mTemporaryQuotaReserve = new TemporaryQuotaReserve(TEMPORARY_QUOTA_DURATION); + mNextWakeup = mNextNonWakeup = 0; // We have to set current TimeZone info to kernel @@ -2391,6 +2545,12 @@ public class AlarmManagerService extends SystemService { final int quotaForBucket = getQuotaForBucketLocked(standbyBucket); if (wakeupsInWindow >= quotaForBucket) { final long minElapsed; + if (mTemporaryQuotaReserve.hasQuota(sourcePackage, sourceUserId, nowElapsed)) { + // We will let this alarm go out as usual, but mark it so it consumes the quota + // at the time of delivery. + alarm.mUsingReserveQuota = true; + return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed); + } if (quotaForBucket <= 0) { // Just keep deferring indefinitely till the quota changes. minElapsed = nowElapsed + INDEFINITE_DELAY; @@ -2405,6 +2565,7 @@ public class AlarmManagerService extends SystemService { } } // wakeupsInWindow are less than the permitted quota, hence no deferring is needed. + alarm.mUsingReserveQuota = false; return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed); } @@ -3165,6 +3326,10 @@ public class AlarmManagerService extends SystemService { pw.println("App Alarm history:"); mAppWakeupHistory.dump(pw, nowELAPSED); + pw.println(); + pw.println("Temporary Quota Reserves:"); + mTemporaryQuotaReserve.dump(pw, nowELAPSED); + if (mPendingIdleUntil != null) { pw.println(); pw.println("Idle mode state:"); @@ -4573,6 +4738,7 @@ public class AlarmManagerService extends SystemService { } } deliverAlarmsLocked(triggerList, nowELAPSED); + mTemporaryQuotaReserve.cleanUpExpiredQuotas(nowELAPSED); if (mConstants.USE_TARE_POLICY) { reorderAlarmsBasedOnTare(triggerPackages); } else { @@ -4682,6 +4848,7 @@ public class AlarmManagerService extends SystemService { public static final int REFRESH_EXACT_ALARM_CANDIDATES = 11; public static final int TARE_AFFORDABILITY_CHANGED = 12; public static final int CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE = 13; + public static final int TEMPORARY_QUOTA_CHANGED = 14; AlarmHandler() { super(Looper.myLooper()); @@ -4747,6 +4914,7 @@ public class AlarmManagerService extends SystemService { } break; + case TEMPORARY_QUOTA_CHANGED: case APP_STANDBY_BUCKET_CHANGED: synchronized (mLock) { final ArraySet<Pair<String, Integer>> filterPackages = new ArraySet<>(); @@ -4958,6 +5126,7 @@ public class AlarmManagerService extends SystemService { mAppWakeupHistory.removeForUser(userHandle); mAllowWhileIdleHistory.removeForUser(userHandle); mAllowWhileIdleCompatHistory.removeForUser(userHandle); + mTemporaryQuotaReserve.removeForUser(userHandle); } return; case Intent.ACTION_UID_REMOVED: @@ -5006,6 +5175,7 @@ public class AlarmManagerService extends SystemService { mAllowWhileIdleHistory.removeForPackage(pkg, UserHandle.getUserId(uid)); mAllowWhileIdleCompatHistory.removeForPackage(pkg, UserHandle.getUserId(uid)); + mTemporaryQuotaReserve.removeForPackage(pkg, UserHandle.getUserId(uid)); removeLocked(uid, REMOVE_REASON_UNDEFINED); } else { // external-applications-unavailable case @@ -5040,6 +5210,30 @@ public class AlarmManagerService extends SystemService { mHandler.obtainMessage(AlarmHandler.APP_STANDBY_BUCKET_CHANGED, userId, -1, packageName) .sendToTarget(); } + + @Override + public void triggerTemporaryQuotaBump(String packageName, int userId) { + final int quotaBump; + synchronized (mLock) { + quotaBump = mConstants.TEMPORARY_QUOTA_BUMP; + } + if (quotaBump <= 0) { + return; + } + final int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId); + if (uid < 0 || UserHandle.isCore(uid)) { + return; + } + if (DEBUG_STANDBY) { + Slog.d(TAG, "Bumping quota temporarily for " + packageName + " for user " + userId); + } + synchronized (mLock) { + mTemporaryQuotaReserve.replenishQuota(packageName, userId, quotaBump, + mInjector.getElapsedRealtime()); + } + mHandler.obtainMessage(AlarmHandler.TEMPORARY_QUOTA_CHANGED, userId, -1, + packageName).sendToTarget(); + } } private final EconomyManagerInternal.AffordabilityChangeListener mAffordabilityChangeListener = @@ -5448,8 +5642,13 @@ public class AlarmManagerService extends SystemService { } } if (!isExemptFromAppStandby(alarm)) { - mAppWakeupHistory.recordAlarmForPackage(alarm.sourcePackage, - UserHandle.getUserId(alarm.creatorUid), nowELAPSED); + final int userId = UserHandle.getUserId(alarm.creatorUid); + if (alarm.mUsingReserveQuota) { + mTemporaryQuotaReserve.recordUsage(alarm.sourcePackage, userId, nowELAPSED); + } else { + mAppWakeupHistory.recordAlarmForPackage(alarm.sourcePackage, userId, + nowELAPSED); + } } final BroadcastStats bs = inflight.mBroadcastStats; bs.count++; diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 52e64e80e6d4..44dc28d2b0fa 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -2618,15 +2618,6 @@ public class PackageParser { return Build.VERSION_CODES.CUR_DEVELOPMENT; } - // STOPSHIP: hack for the pre-release SDK - if (platformSdkCodenames.length == 0 - && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( - targetCode)) { - Slog.w(TAG, "Package requires development platform " + targetCode - + ", returning current version " + Build.VERSION.SDK_INT); - return Build.VERSION.SDK_INT; - } - // Otherwise, we're looking at an incompatible pre-release SDK. if (platformSdkCodenames.length > 0) { outError[0] = "Requires development platform " + targetCode @@ -2698,15 +2689,6 @@ public class PackageParser { return Build.VERSION_CODES.CUR_DEVELOPMENT; } - // STOPSHIP: hack for the pre-release SDK - if (platformSdkCodenames.length == 0 - && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( - minCode)) { - Slog.w(TAG, "Package requires min development platform " + minCode - + ", returning current version " + Build.VERSION.SDK_INT); - return Build.VERSION.SDK_INT; - } - // Otherwise, we're looking at an incompatible pre-release SDK. if (platformSdkCodenames.length > 0) { outError[0] = "Requires development platform " + minCode diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java index 8cc4cdb955ca..3e1c5bb3d7ec 100644 --- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java @@ -316,15 +316,6 @@ public class FrameworkParsingPackageUtils { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } - // STOPSHIP: hack for the pre-release SDK - if (platformSdkCodenames.length == 0 - && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( - minCode)) { - Slog.w(TAG, "Parsed package requires min development platform " + minCode - + ", returning current version " + Build.VERSION.SDK_INT); - return input.success(Build.VERSION.SDK_INT); - } - // Otherwise, we're looking at an incompatible pre-release SDK. if (platformSdkCodenames.length > 0) { return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, @@ -377,27 +368,19 @@ public class FrameworkParsingPackageUtils { return input.success(targetVers); } - // If it's a pre-release SDK and the codename matches this platform, it - // definitely targets this SDK. - if (matchTargetCode(platformSdkCodenames, targetCode)) { - return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); - } - - // STOPSHIP: hack for the pre-release SDK - if (platformSdkCodenames.length == 0 - && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( - targetCode)) { - Slog.w(TAG, "Parsed package requires development platform " + targetCode - + ", returning current version " + Build.VERSION.SDK_INT); - return input.success(Build.VERSION.SDK_INT); - } - try { if (allowUnknownCodenames && UnboundedSdkLevel.isAtMost(targetCode)) { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } } catch (IllegalArgumentException e) { - return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, "Bad package SDK"); + // isAtMost() throws it when encountering an older SDK codename + return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, e.getMessage()); + } + + // If it's a pre-release SDK and the codename matches this platform, it + // definitely targets this SDK. + if (matchTargetCode(platformSdkCodenames, targetCode)) { + return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } // Otherwise, we're looking at an incompatible pre-release SDK. diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index a90eb88bc109..98a8cbd8a73c 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -2356,10 +2356,11 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <p>A subset of the available request keys that can be overridden for * physical devices backing a logical multi-camera.</p> * <p>This is a subset of android.request.availableRequestKeys which contains a list - * of keys that can be overridden using {@link CaptureRequest.Builder#setPhysicalCameraKey }. + * of keys that can be overridden using + * {@link android.hardware.camera2.CaptureRequest.Builder#setPhysicalCameraKey }. * The respective value of such request key can be obtained by calling - * {@link CaptureRequest.Builder#getPhysicalCameraKey }. Capture requests that contain - * individual physical device requests must be built via + * {@link android.hardware.camera2.CaptureRequest.Builder#getPhysicalCameraKey }. + * Capture requests that contain individual physical device requests must be built via * {@link android.hardware.camera2.CameraDevice#createCaptureRequest(int, Set)}.</p> * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p> * <p><b>Limited capability</b> - @@ -2759,7 +2760,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * </table> * <p>For applications targeting SDK version 31 or newer, if the mobile device declares to be * media performance class 12 or higher by setting - * {@link android.os.Build.VERSION_CODES.MEDIA_PERFORMANCE_CLASS } to be 31 or larger, + * {@link android.os.Build.VERSION#MEDIA_PERFORMANCE_CLASS } to be 31 or larger, * the primary camera devices (first rear/front camera in the camera ID list) will not * support JPEG sizes smaller than 1080p. If the application configures a JPEG stream * smaller than 1080p, the camera device will round up the JPEG image size to at least @@ -2833,7 +2834,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * </table> * <p>For applications targeting SDK version 31 or newer, if the mobile device doesn't declare * to be media performance class 12 or better by setting - * {@link android.os.Build.VERSION_CODES.MEDIA_PERFORMANCE_CLASS } to be 31 or larger, + * {@link android.os.Build.VERSION#MEDIA_PERFORMANCE_CLASS } to be 31 or larger, * or if the camera device isn't a primary rear/front camera, the minimum required output * stream configurations are the same as for applications targeting SDK version older than * 31.</p> @@ -2958,9 +2959,27 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * can provide.</p> * <p>Please reference the documentation for the image data destination to * check if it limits the maximum size for image data.</p> - * <p>The following table describes the minimum required output stream - * configurations based on the hardware level - * ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}):</p> + * <p>For applications targeting SDK version older than 31, the following table + * describes the minimum required output stream configurations based on the + * hardware level ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}): + * Format | Size | Hardware Level | Notes + * :-------------------------------------------------:|:--------------------------------------------:|:--------------:|:--------------: + * {@link android.graphics.ImageFormat#JPEG } | {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} (*1) | Any | + * {@link android.graphics.ImageFormat#JPEG } | 1920x1080 (1080p) | Any | if 1080p <= activeArraySize + * {@link android.graphics.ImageFormat#JPEG } | 1280x720 (720p) | Any | if 720p <= activeArraySize + * {@link android.graphics.ImageFormat#JPEG } | 640x480 (480p) | Any | if 480p <= activeArraySize + * {@link android.graphics.ImageFormat#JPEG } | 320x240 (240p) | Any | if 240p <= activeArraySize + * {@link android.graphics.ImageFormat#YUV_420_888 } | all output sizes available for JPEG | FULL | + * {@link android.graphics.ImageFormat#YUV_420_888 } | all output sizes available for JPEG, up to the maximum video size | LIMITED | + * {@link android.graphics.ImageFormat#PRIVATE } | same as YUV_420_888 | Any |</p> + * <p>For applications targeting SDK version 31 or newer, if the mobile device declares to be + * media performance class 12 or higher by setting + * {@link android.os.Build.VERSION#MEDIA_PERFORMANCE_CLASS } to be 31 or larger, + * the primary camera devices (first rear/front camera in the camera ID list) will not + * support JPEG sizes smaller than 1080p. If the application configures a JPEG stream + * smaller than 1080p, the camera device will round up the JPEG image size to at least + * 1080p. The requirements for IMPLEMENTATION_DEFINED and YUV_420_888 stay the same. + * This new minimum required output stream configurations are illustrated by the table below:</p> * <table> * <thead> * <tr> @@ -2984,32 +3003,38 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <td align="center">if 1080p <= activeArraySize</td> * </tr> * <tr> - * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td> - * <td align="center">1280x720 (720p)</td> - * <td align="center">Any</td> + * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td> + * <td align="center">{@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</td> + * <td align="center">FULL</td> + * <td align="center"></td> + * </tr> + * <tr> + * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td> + * <td align="center">1920x1080 (1080p)</td> + * <td align="center">FULL</td> + * <td align="center">if 1080p <= activeArraySize</td> + * </tr> + * <tr> + * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td> + * <td align="center">1280x720 (720)</td> + * <td align="center">FULL</td> * <td align="center">if 720p <= activeArraySize</td> * </tr> * <tr> - * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td> + * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td> * <td align="center">640x480 (480p)</td> - * <td align="center">Any</td> + * <td align="center">FULL</td> * <td align="center">if 480p <= activeArraySize</td> * </tr> * <tr> - * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td> - * <td align="center">320x240 (240p)</td> - * <td align="center">Any</td> - * <td align="center">if 240p <= activeArraySize</td> - * </tr> - * <tr> * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td> - * <td align="center">all output sizes available for JPEG</td> + * <td align="center">320x240 (240p)</td> * <td align="center">FULL</td> - * <td align="center"></td> + * <td align="center">if 240p <= activeArraySize</td> * </tr> * <tr> * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td> - * <td align="center">all output sizes available for JPEG, up to the maximum video size</td> + * <td align="center">all output sizes available for FULL hardware level, up to the maximum video size</td> * <td align="center">LIMITED</td> * <td align="center"></td> * </tr> @@ -3021,6 +3046,12 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * </tr> * </tbody> * </table> + * <p>For applications targeting SDK version 31 or newer, if the mobile device doesn't declare + * to be media performance class 12 or better by setting + * {@link android.os.Build.VERSION#MEDIA_PERFORMANCE_CLASS } to be 31 or larger, + * or if the camera device isn't a primary rear/front camera, the minimum required output + * stream configurations are the same as for applications targeting SDK version older than + * 31.</p> * <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} and {@link android.hardware.camera2.CameraDevice#createCaptureSession } for additional mandatory * stream configurations on a per-capability basis.</p> * <p>*1: For JPEG format, the sizes may be restricted by below conditions:</p> diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java index cf611fb3adcf..0f6010fffcb6 100644 --- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java @@ -854,7 +854,7 @@ public final class CameraExtensionCharacteristics { Class<CaptureRequest.Key<?>> crKeyTyped = (Class<CaptureRequest.Key<?>>) crKey; ret.addAll(requestChars.getAvailableKeyList(CaptureRequest.class, crKeyTyped, - requestKeys, /*includeSynthetic*/ false)); + requestKeys, /*includeSynthetic*/ true)); } // Jpeg quality and orientation must always be supported @@ -929,7 +929,7 @@ public final class CameraExtensionCharacteristics { Class<CaptureResult.Key<?>> crKeyTyped = (Class<CaptureResult.Key<?>>)crKey; ret.addAll(resultChars.getAvailableKeyList(CaptureResult.class, crKeyTyped, - resultKeys, /*includeSynthetic*/ false)); + resultKeys, /*includeSynthetic*/ true)); // Jpeg quality, orientation and sensor timestamp must always be supported if (!ret.contains(CaptureResult.JPEG_QUALITY)) { diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index b505395a091a..69c6ba9a0f43 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -559,18 +559,21 @@ public final class DisplayManager { * @see #DISPLAY_CATEGORY_PRESENTATION */ public Display[] getDisplays(String category) { - final int[] displayIds = mGlobal.getDisplayIds(); + boolean includeDisabledDisplays = (category != null + && category.equals(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)); + final int[] displayIds = mGlobal.getDisplayIds(includeDisabledDisplays); synchronized (mLock) { try { - if (category == null - || DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED.equals(category)) { - addAllDisplaysLocked(mTempDisplays, displayIds); - } else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) { + if (category != null && category.equals(DISPLAY_CATEGORY_PRESENTATION)) { addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI); addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_EXTERNAL); addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY); addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_VIRTUAL); addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_INTERNAL); + } else if ((category == null + || DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED.equals(category))) { + // All displays requested. + addAllDisplaysLocked(mTempDisplays, displayIds); } return mTempDisplays.toArray(new Display[mTempDisplays.size()]); } finally { diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index 74356ddecc76..da3a5802ee55 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -206,6 +206,16 @@ public final class DisplayManagerGlobal { */ @UnsupportedAppUsage public int[] getDisplayIds() { + return getDisplayIds(/* includeDisabledDisplays= */ false); + } + + /** + * Gets all valid logical display ids and invalid ones if specified. + * + * @return An array containing all display ids. + */ + @UnsupportedAppUsage + public int[] getDisplayIds(boolean includeDisabledDisplays) { try { synchronized (mLock) { if (USE_CACHE) { @@ -214,7 +224,8 @@ public final class DisplayManagerGlobal { } } - int[] displayIds = mDm.getDisplayIds(); + int[] displayIds = + mDm.getDisplayIds(includeDisabledDisplays); if (USE_CACHE) { mDisplayIdCache = displayIds; } diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl index ca3e58094400..a4115d178f6f 100644 --- a/core/java/android/hardware/display/IDisplayManager.aidl +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -36,7 +36,7 @@ import android.view.Surface; interface IDisplayManager { @UnsupportedAppUsage DisplayInfo getDisplayInfo(int displayId); - int[] getDisplayIds(); + int[] getDisplayIds(boolean includeDisabled); boolean isUidPresentOnDisplay(int uid, int displayId); diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java index e5dab0539a8e..0418a4bb9f80 100644 --- a/core/java/android/os/BaseBundle.java +++ b/core/java/android/os/BaseBundle.java @@ -31,6 +31,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; import java.io.Serializable; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Set; import java.util.function.BiFunction; @@ -102,7 +103,7 @@ public class BaseBundle { /* * If mParcelledData is non-null, then mMap will be null and the * data are stored as a Parcel containing a Bundle. When the data - * are unparcelled, mParcelledData willbe set to null. + * are unparcelled, mParcelledData will be set to null. */ @UnsupportedAppUsage volatile Parcel mParcelledData = null; @@ -112,6 +113,19 @@ public class BaseBundle { */ private boolean mParcelledByNative; + /* + * Flag indicating if mParcelledData is only referenced in this bundle. + * mParcelledData could be referenced by other bundles if mMap contains lazy values, + * and bundle data is copied to another bundle using putAll or the copy constructors. + */ + boolean mOwnsLazyValues = true; + + /* + * As mParcelledData is set to null when it is unparcelled, we keep a weak reference to + * it to aid in recycling it. Do not use this reference otherwise. + */ + private WeakReference<Parcel> mWeakParcelledData = null; + /** * The ClassLoader used when unparcelling data from mParcelledData. */ @@ -200,6 +214,9 @@ public class BaseBundle { mClassLoader = from.mClassLoader; if (from.mMap != null) { + mOwnsLazyValues = false; + from.mOwnsLazyValues = false; + if (!deep) { mMap = new ArrayMap<>(from.mMap); } else { @@ -434,6 +451,9 @@ public class BaseBundle { mMap = map; if (recycleParcel) { recycleParcel(parcelledData); + mWeakParcelledData = null; + } else { + mWeakParcelledData = new WeakReference<>(parcelledData); } mParcelledByNative = false; mParcelledData = null; @@ -575,6 +595,10 @@ public class BaseBundle { */ public void clear() { unparcel(); + if (mOwnsLazyValues && mWeakParcelledData != null) { + recycleParcel(mWeakParcelledData.get()); + mWeakParcelledData = null; + } mMap.clear(); } diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index cf28c1639fac..7e355d95cdb3 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -301,6 +301,8 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { public void putAll(Bundle bundle) { unparcel(); bundle.unparcel(); + mOwnsLazyValues = false; + bundle.mOwnsLazyValues = false; mMap.putAll(bundle.mMap); // FD state is now known if and only if both bundles already knew diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 7e264cea46bb..536a0ac6403b 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -41,11 +41,13 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.SystemClock; +import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; import android.view.SurfaceControl.Transaction; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityEmbeddedConnection; +import android.window.SurfaceSyncer; import com.android.internal.view.SurfaceCallbackHelper; @@ -204,6 +206,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall private int mSurfaceFlags = SurfaceControl.HIDDEN; + private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer(); + private final ArraySet<Integer> mSyncIds = new ArraySet<>(); + /** * Transaction that should be used from the render thread. This transaction is only thread safe * with other calls directly from the render thread. @@ -1018,7 +1023,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall if (shouldSyncBuffer) { handleSyncBufferCallback(callbacks, syncBufferTransactionCallback); } else { - redrawNeededAsync(callbacks, this::onDrawFinished); + handleSyncNoBuffer(callbacks); } } } @@ -1061,7 +1066,23 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall syncBufferCallback.onBufferReady(t); onDrawFinished(); })); + } + + private void handleSyncNoBuffer(SurfaceHolder.Callback[] callbacks) { + final int syncId = mSurfaceSyncer.setupSync(this::onDrawFinished); + mSurfaceSyncer.addToSync(syncId, syncBufferCallback -> redrawNeededAsync(callbacks, + () -> { + syncBufferCallback.onBufferReady(null); + synchronized (mSyncIds) { + mSyncIds.remove(syncId); + } + })); + + mSurfaceSyncer.markSyncReady(syncId); + synchronized (mSyncIds) { + mSyncIds.add(syncId); + } } private void redrawNeededAsync(SurfaceHolder.Callback[] callbacks, @@ -1070,6 +1091,21 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks); } + /** + * @hide + */ + @Override + public void surfaceSyncStarted() { + ViewRootImpl viewRoot = getViewRootImpl(); + if (viewRoot != null) { + synchronized (mSyncIds) { + for (int syncId : mSyncIds) { + viewRoot.mergeSync(syncId, mSurfaceSyncer); + } + } + } + } + private static class SyncBufferTransactionCallback { private final CountDownLatch mCountDownLatch = new CountDownLatch(1); private Transaction mTransaction; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index ad3379f4c46e..f163530f997b 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2048,6 +2048,7 @@ public final class ViewRootImpl implements ViewParent, void surfaceCreated(Transaction t); void surfaceReplaced(Transaction t); void surfaceDestroyed(); + default void surfaceSyncStarted() {}; } private final ArrayList<SurfaceChangedCallback> mSurfaceChangedCallbacks = new ArrayList<>(); @@ -2082,6 +2083,12 @@ public final class ViewRootImpl implements ViewParent, } } + private void notifySurfaceSyncStarted() { + for (int i = 0; i < mSurfaceChangedCallbacks.size(); i++) { + mSurfaceChangedCallbacks.get(i).surfaceSyncStarted(); + } + } + /** * @return child layer with the same bounds as its parent {@code mSurface} and cropped to the * surface insets. If the layer does not exist, it is created. @@ -3541,6 +3548,7 @@ public final class ViewRootImpl implements ViewParent, Log.d(mTag, "Setup new sync id=" + mSyncId); } mSurfaceSyncer.addToSync(mSyncId, mSyncTarget); + notifySurfaceSyncStarted(); } private void notifyContentCatpureEvents() { @@ -10965,4 +10973,11 @@ public final class ViewRootImpl implements ViewParent, scheduleTraversals(); } } + + void mergeSync(int syncId, SurfaceSyncer otherSyncer) { + if (!isInLocalSync()) { + return; + } + mSurfaceSyncer.merge(mSyncId, syncId, otherSyncer); + } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index e745b8cf769b..23393ffe885c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -4781,12 +4781,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * TextView is {@link Layout#BREAK_STRATEGY_HIGH_QUALITY}, and the default value for * EditText is {@link Layout#BREAK_STRATEGY_SIMPLE}, the latter to avoid the * text "dancing" when being edited. - * <p/> + * <p> * Enabling hyphenation with either using {@link Layout#HYPHENATION_FREQUENCY_NORMAL} or * {@link Layout#HYPHENATION_FREQUENCY_FULL} while line breaking is set to one of * {@link Layout#BREAK_STRATEGY_BALANCED}, {@link Layout#BREAK_STRATEGY_HIGH_QUALITY} * improves the structure of text layout however has performance impact and requires more time - * to do the text layout. + * to do the text layout.</p> + * <p> + * Compared with {@link #setLineBreakStyle(int)}, line break style with different strictness is + * evaluated in the ICU to identify the potential breakpoints. In + * {@link #setBreakStrategy(int)}, line break strategy handles the post processing of ICU's line + * break result. It aims to evaluate ICU's breakpoints and break the lines based on the + * constraint. + * </p> * * @attr ref android.R.styleable#TextView_breakStrategy * @see #getBreakStrategy() diff --git a/core/java/android/window/SurfaceSyncer.java b/core/java/android/window/SurfaceSyncer.java index 0e011bb0d0b3..e6eb07162a3b 100644 --- a/core/java/android/window/SurfaceSyncer.java +++ b/core/java/android/window/SurfaceSyncer.java @@ -117,13 +117,18 @@ public class SurfaceSyncer { */ public int setupSync(@NonNull Consumer<Transaction> syncRequestComplete) { synchronized (mSyncSetLock) { - mIdCounter++; + final int syncId = mIdCounter++; if (DEBUG) { - Log.d(TAG, "setupSync " + mIdCounter); + Log.d(TAG, "setupSync " + syncId); } - SyncSet syncSet = new SyncSet(mIdCounter, syncRequestComplete); - mSyncSets.put(mIdCounter, syncSet); - return mIdCounter; + SyncSet syncSet = new SyncSet(syncId, transaction -> { + synchronized (mSyncSetLock) { + mSyncSets.remove(syncId); + } + syncRequestComplete.accept(transaction); + }); + mSyncSets.put(syncId, syncSet); + return syncId; } } @@ -138,7 +143,6 @@ public class SurfaceSyncer { SyncSet syncSet; synchronized (mSyncSetLock) { syncSet = mSyncSets.get(syncId); - mSyncSets.remove(syncId); } if (syncSet == null) { Log.e(TAG, "Failed to find syncSet for syncId=" + syncId); @@ -148,6 +152,31 @@ public class SurfaceSyncer { } /** + * Merge another SyncSet into the specified syncId. + * @param syncId The current syncId to merge into + * @param otherSyncId The other syncId to be merged + * @param otherSurfaceSyncer The other SurfaceSyncer where the otherSyncId is from + */ + public void merge(int syncId, int otherSyncId, SurfaceSyncer otherSurfaceSyncer) { + SyncSet syncSet; + synchronized (mSyncSetLock) { + syncSet = mSyncSets.get(syncId); + } + + SyncSet otherSyncSet = otherSurfaceSyncer.getAndValidateSyncSet(otherSyncId); + if (otherSyncSet == null) { + return; + } + + if (DEBUG) { + Log.d(TAG, + "merge id=" + otherSyncId + " from=" + otherSurfaceSyncer + " into id=" + syncId + + " from" + this); + } + syncSet.merge(otherSyncSet); + } + + /** * Add a SurfaceView to a sync set. This is different than {@link #addToSync(int, View)} because * it requires the caller to notify the start and finish drawing in order to sync. * @@ -199,8 +228,7 @@ public class SurfaceSyncer { if (DEBUG) { Log.d(TAG, "addToSync id=" + syncId); } - syncSet.addSyncableSurface(syncTarget); - return true; + return syncSet.addSyncableSurface(syncTarget); } /** @@ -284,14 +312,21 @@ public class SurfaceSyncer { private final Set<SyncTarget> mSyncTargets = new ArraySet<>(); private final int mSyncId; - private final Consumer<Transaction> mSyncRequestCompleteCallback; + @GuardedBy("mLock") + private Consumer<Transaction> mSyncRequestCompleteCallback; + + @GuardedBy("mLock") + private final Set<SyncSet> mMergedSyncSets = new ArraySet<>(); + + @GuardedBy("mLock") + private boolean mFinished; private SyncSet(int syncId, Consumer<Transaction> syncRequestComplete) { mSyncId = syncId; mSyncRequestCompleteCallback = syncRequestComplete; } - void addSyncableSurface(SyncTarget syncTarget) { + boolean addSyncableSurface(SyncTarget syncTarget) { SyncBufferCallback syncBufferCallback = new SyncBufferCallback() { @Override public void onBufferReady(Transaction t) { @@ -306,10 +341,16 @@ public class SurfaceSyncer { }; synchronized (mLock) { + if (mSyncReady) { + Log.e(TAG, "Sync " + mSyncId + " was already marked as ready. No more " + + "SyncTargets can be added."); + return false; + } mPendingSyncs.add(syncBufferCallback.hashCode()); mSyncTargets.add(syncTarget); } syncTarget.onReadyToSync(syncBufferCallback); + return true; } void markSyncReady() { @@ -321,10 +362,11 @@ public class SurfaceSyncer { @GuardedBy("mLock") private void checkIfSyncIsComplete() { - if (!mSyncReady || !mPendingSyncs.isEmpty()) { + if (!mSyncReady || !mPendingSyncs.isEmpty() || !mMergedSyncSets.isEmpty()) { if (DEBUG) { Log.d(TAG, "Syncable is not complete. mSyncReady=" + mSyncReady - + " mPendingSyncs=" + mPendingSyncs.size()); + + " mPendingSyncs=" + mPendingSyncs.size() + " mergedSyncs=" + + mMergedSyncSets.size()); } return; } @@ -338,6 +380,7 @@ public class SurfaceSyncer { } mSyncTargets.clear(); mSyncRequestCompleteCallback.accept(mTransaction); + mFinished = true; } /** @@ -349,6 +392,50 @@ public class SurfaceSyncer { mTransaction.merge(t); } } + + public void updateCallback(Consumer<Transaction> transactionConsumer) { + synchronized (mLock) { + if (mFinished) { + Log.e(TAG, "Attempting to merge SyncSet " + mSyncId + " when sync is" + + " already complete"); + transactionConsumer.accept(new Transaction()); + } + + final Consumer<Transaction> oldCallback = mSyncRequestCompleteCallback; + mSyncRequestCompleteCallback = transaction -> { + oldCallback.accept(new Transaction()); + transactionConsumer.accept(transaction); + }; + } + } + + /** + * Merge a SyncSet into this SyncSet. Since SyncSets could still have pending SyncTargets, + * we need to make sure those can still complete before the mergeTo syncSet is considered + * complete. + * + * We keep track of all the merged SyncSets until they are marked as done, and then they + * are removed from the set. This SyncSet is not considered done until all the merged + * SyncSets are done. + * + * When the merged SyncSet is complete, it will invoke the original syncRequestComplete + * callback but send an empty transaction to ensure the changes are applied early. This + * is needed in case the original sync is relying on the callback to continue processing. + * + * @param otherSyncSet The other SyncSet to merge into this one. + */ + public void merge(SyncSet otherSyncSet) { + synchronized (mLock) { + mMergedSyncSets.add(otherSyncSet); + } + otherSyncSet.updateCallback(transaction -> { + synchronized (mLock) { + mMergedSyncSets.remove(otherSyncSet); + mTransaction.merge(transaction); + checkIfSyncIsComplete(); + } + }); + } } /** diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java index b7f6a615a452..bf265689c0e0 100644 --- a/core/java/com/android/internal/app/PlatLogoActivity.java +++ b/core/java/com/android/internal/app/PlatLogoActivity.java @@ -103,6 +103,7 @@ public class PlatLogoActivity extends Activity { mBg.padding = 0.5f * dp; mBg.minR = 1 * dp; layout.setBackground(mBg); + layout.setOnLongClickListener(mBg); setContentView(layout); } @@ -291,8 +292,8 @@ public class PlatLogoActivity extends Activity { return true; case MotionEvent.ACTION_UP: - if (mOverrideMinute == 0 && (mOverrideHour % 12) == 0) { - Log.v(TAG, "12:00 let's gooooo"); + if (mOverrideMinute == 0 && (mOverrideHour % 12) == 1) { + Log.v(TAG, "13:00"); performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); launchNextStage(false); } @@ -302,18 +303,45 @@ public class PlatLogoActivity extends Activity { } } + private static final String[][] EMOJI_SETS = { + {"🍇", "🍈", "🍉", "🍊", "🍋", "🍌", "🍍", "🥭", "🍎", "🍏", "🍐", "🍑", + "🍒", "🍓", "🫐", "🥝"}, + {"😺", "😸", "😹", "😻", "😼", "😽", "🙀", "😿", "😾"}, + {"😀", "😃", "😄", "😁", "😆", "😅", "🤣", "😂", "🙂", "🙃", "🫠", "😉", "😊", + "😇", "🥰", "😍", "🤩", "😘", "😗", "☺️", "😚", "😙", "🥲", "😋", "😛", "😜", + "🤪", "😝", "🤑", "🤗", "🤭", "🫢", "🫣", "🤫", "🤔", "🫡", "🤐", "🤨", "😐", + "😑", "😶", "🫥", "😏", "😒", "🙄", "😬", "🤥", "😌", "😔", "😪", "🤤", "😴", + "😷"}, + { "🤩", "😍", "🥰", "😘", "🥳", "🥲", "🥹" }, + { "🫠" }, + {"💘", "💝", "💖", "💗", "💓", "💞", "💕", "❣", "💔", "❤", "🧡", "💛", + "💚", "💙", "💜", "🤎", "🖤", "🤍"}, + // {"👁", "️🫦", "👁️"}, // this one is too much + {"👽", "🛸", "✨", "🌟", "💫", "🚀", "🪐", "🌙", "⭐", "🌍"}, + {"🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"}, + {"🐙", "🪸", "🦑", "🦀", "🦐", "🐡", "🦞", "🐠", "🐟", "🐳", "🐋", "🐬", "🫧", "🌊", + "🦈"}, + {"🙈", "🙉", "🙊", "🐵", "🐒"}, + {"♈", "♉", "♊", "♋", "♌", "♍", "♎", "♏", "♐", "♑", "♒", "♓"}, + {"🕛", "🕧", "🕐", "🕜", "🕑", "🕝", "🕒", "🕞", "🕓", "🕟", "🕔", "🕠", "🕕", "🕡", + "🕖", "🕢", "🕗", "🕣", "🕘", "🕤", "🕙", "🕥", "🕚", "🕦"}, + {"🌺", "🌸", "💮", "🏵️", "🌼", "🌿"}, + {"🐢", "✨", "🌟", "👑"} + }; + static class Bubble { public float x, y, r; public int color; + public String text = null; } - class BubblesDrawable extends Drawable { + class BubblesDrawable extends Drawable implements View.OnLongClickListener { private static final int MAX_BUBBS = 2000; private final int[] mColorIds = { - android.R.color.system_accent1_400, - android.R.color.system_accent1_500, - android.R.color.system_accent1_600, + android.R.color.system_accent3_400, + android.R.color.system_accent3_500, + android.R.color.system_accent3_600, android.R.color.system_accent2_400, android.R.color.system_accent2_500, @@ -322,6 +350,8 @@ public class PlatLogoActivity extends Activity { private int[] mColors = new int[mColorIds.length]; + private int mEmojiSet = -1; + private final Bubble[] mBubbs = new Bubble[MAX_BUBBS]; private int mNumBubbs; @@ -342,17 +372,34 @@ public class PlatLogoActivity extends Activity { @Override public void draw(Canvas canvas) { + if (getLevel() == 0) return; final float f = getLevel() / 10000f; mPaint.setStyle(Paint.Style.FILL); + mPaint.setTextAlign(Paint.Align.CENTER); int drawn = 0; for (int j = 0; j < mNumBubbs; j++) { if (mBubbs[j].color == 0 || mBubbs[j].r == 0) continue; - mPaint.setColor(mBubbs[j].color); - canvas.drawCircle(mBubbs[j].x, mBubbs[j].y, mBubbs[j].r * f, mPaint); + if (mBubbs[j].text != null) { + mPaint.setTextSize(mBubbs[j].r * 1.75f); + canvas.drawText(mBubbs[j].text, mBubbs[j].x, + mBubbs[j].y + mBubbs[j].r * f * 0.6f, mPaint); + } else { + mPaint.setColor(mBubbs[j].color); + canvas.drawCircle(mBubbs[j].x, mBubbs[j].y, mBubbs[j].r * f, mPaint); + } drawn++; } } + public void chooseEmojiSet() { + mEmojiSet = (int) (Math.random() * EMOJI_SETS.length); + final String[] emojiSet = EMOJI_SETS[mEmojiSet]; + for (int j = 0; j < mBubbs.length; j++) { + mBubbs[j].text = emojiSet[(int) (Math.random() * emojiSet.length)]; + } + invalidateSelf(); + } + @Override protected boolean onLevelChange(int level) { invalidateSelf(); @@ -423,6 +470,13 @@ public class PlatLogoActivity extends Activity { public int getOpacity() { return TRANSLUCENT; } + + @Override + public boolean onLongClick(View v) { + if (getLevel() == 0) return false; + chooseEmojiSet(); + return true; + } } } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 36a3c5c84ed2..40429c609150 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -1501,7 +1501,10 @@ public class ResolverActivity extends Activity implements : R.string.miniresolver_use_personal_browser); findViewById(R.id.use_same_profile_browser).setOnClickListener( - v -> safelyStartActivity(sameProfileResolveInfo)); + v -> { + safelyStartActivity(sameProfileResolveInfo); + finish(); + }); findViewById(R.id.button_open).setOnClickListener(v -> { Intent intent = otherProfileResolveInfo.getResolvedIntent(); @@ -1510,6 +1513,7 @@ public class ResolverActivity extends Activity implements } safelyStartActivityAsUser(otherProfileResolveInfo, inactiveAdapter.mResolverListController.getUserHandle()); + finish(); }); } diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index 3436b9e75c65..9b583be547c3 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -113,6 +113,24 @@ public class SystemConfig { final ArrayList<SplitPermissionInfo> mSplitPermissions = new ArrayList<>(); + private static boolean isAtLeastSdkLevel(String version) { + try { + return UnboundedSdkLevel.isAtLeast(version); + } catch (IllegalArgumentException e) { + // UnboundedSdkLevel throws when it sees a known old codename + return false; + } + } + + private static boolean isAtMostSdkLevel(String version) { + try { + return UnboundedSdkLevel.isAtMost(version); + } catch (IllegalArgumentException e) { + // UnboundedSdkLevel throws when it sees a known old codename + return true; + } + } + public static final class SharedLibraryEntry { public final String name; public final String filename; @@ -180,9 +198,9 @@ public class SystemConfig { // - onBootclasspathBefore is set and we are before that SDK canBeSafelyIgnored = (this.onBootclasspathSince != null - && UnboundedSdkLevel.isAtLeast(this.onBootclasspathSince)) + && isAtLeastSdkLevel(this.onBootclasspathSince)) || (this.onBootclasspathBefore != null - && !UnboundedSdkLevel.isAtLeast(this.onBootclasspathBefore)); + && !isAtLeastSdkLevel(this.onBootclasspathBefore)); } } @@ -885,11 +903,9 @@ public class SystemConfig { + parser.getPositionDescription()); } else { boolean allowedMinSdk = - minDeviceSdk == null || UnboundedSdkLevel.isAtLeast( - minDeviceSdk); + minDeviceSdk == null || isAtLeastSdkLevel(minDeviceSdk); boolean allowedMaxSdk = - maxDeviceSdk == null || UnboundedSdkLevel.isAtMost( - maxDeviceSdk); + maxDeviceSdk == null || isAtMostSdkLevel(maxDeviceSdk); final boolean exists = new File(lfile).exists(); if (allowedMinSdk && allowedMaxSdk && exists) { String bcpSince = parser.getAttributeValue(null, diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index e52da0fd6787..7439b2f0921f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -6628,7 +6628,7 @@ android:process=":ui"> </activity> <activity android:name="com.android.internal.app.PlatLogoActivity" - android:theme="@style/Theme.DeviceDefault.Wallpaper.NoTitleBar" + android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden" android:icon="@drawable/platlogo" android:process=":ui"> diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml index f816d0c41349..da214868ca05 100644 --- a/core/res/res/drawable-nodpi/platlogo.xml +++ b/core/res/res/drawable-nodpi/platlogo.xml @@ -19,17 +19,27 @@ Copyright (C) 2021 The Android Open Source Project android:viewportWidth="24" xmlns:android="http://schemas.android.com/apk/res/android"> <path - android:pathData="M11 0.51a2.06 2.06 0 0 1 2 0l0.58 0.37a4.15 4.15 0 0 0 2.23 0.55l0.69-0.06a2.07 2.07 0 0 1 1.81 0.95l0.33 0.6a4.14 4.14 0 0 0 1.72 1.52l0.64 0.27a2 2 0 0 1 1.16 1.68l0 0.69A4.12 4.12 0 0 0 23 9.23l0.44 0.53a2.06 2.06 0 0 1 0.24 2l-0.3 0.62a4.14 4.14 0 0 0-0.27 2.28l0.14 0.68a2.08 2.08 0 0 1-0.72 1.91l-0.56 0.41a4 4 0 0 0-1.3 1.89l-0.19 0.66A2.06 2.06 0 0 1 19 21.58l-0.68 0.11a4.09 4.09 0 0 0-2 1.07l-0.48 0.5a2.08 2.08 0 0 1-2 0.49l-0.65-0.23a4.28 4.28 0 0 0-2.3 0l-0.65 0.23a2.08 2.08 0 0 1-2-0.49l-0.48-0.5a4 4 0 0 0-2-1.07L5 21.58A2.06 2.06 0 0 1 3.5 20.23l-0.19-0.66A4 4 0 0 0 2 17.68l-0.56-0.41a2.08 2.08 0 0 1-0.72-1.91l0.14-0.68A4.14 4.14 0 0 0 0.6 12.4l-0.3-0.62a2.06 2.06 0 0 1 0.24-2L1 9.23A4.16 4.16 0 0 0 1.8 7.08l0-0.69A2 2 0 0 1 3 4.71l0.64-0.27A4.14 4.14 0 0 0 5.34 2.92l0.33-0.6a2.07 2.07 0 0 1 1.81-0.95l0.69 0.06A4.15 4.15 0 0 0 10.4 0.88Z" - android:fillColor="@android:color/system_accent3_400" + android:fillColor="@android:color/system_accent1_400" + android:pathData="M11,0.3c0.6,-0.3 1.4,-0.3 2,0l0.6,0.4c0.7,0.4 1.4,0.6 2.2,0.6l0.7,-0.1c0.7,0 1.4,0.3 1.8,0.9l0.3,0.6c0.4,0.7 1,1.2 1.7,1.5L21,4.5c0.7,0.3 1.1,0.9 1.2,1.7v0.7C22.2,7.7 22.5,8.4 23,9l0.4,0.5c0.4,0.6 0.5,1.3 0.2,2l-0.3,0.6c-0.3,0.7 -0.4,1.5 -0.3,2.3l0.1,0.7c0.1,0.7 -0.2,1.4 -0.7,1.9L22,17.5c-0.6,0.5 -1.1,1.1 -1.3,1.9L20.5,20c-0.2,0.7 -0.8,1.2 -1.5,1.4l-0.7,0.1c-0.8,0.2 -1.4,0.5 -2,1.1l-0.5,0.5c-0.5,0.5 -1.3,0.7 -2,0.5l-0.6,-0.2c-0.8,-0.2 -1.5,-0.2 -2.3,0l-0.6,0.2c-0.7,0.2 -1.5,0 -2,-0.5l-0.5,-0.5c-0.5,-0.5 -1.2,-0.9 -2,-1.1L5,21.4c-0.7,-0.2 -1.3,-0.7 -1.5,-1.4l-0.2,-0.7C3.1,18.6 2.6,18 2,17.5l-0.6,-0.4c-0.6,-0.5 -0.8,-1.2 -0.7,-1.9l0.1,-0.7c0.1,-0.8 0,-1.6 -0.3,-2.3l-0.3,-0.6c-0.3,-0.7 -0.2,-1.4 0.2,-2L1,9c0.5,-0.6 0.7,-1.4 0.8,-2.2V6.2C1.9,5.5 2.3,4.8 3,4.5l0.6,-0.3c0.7,-0.3 1.3,-0.9 1.7,-1.5l0.3,-0.6c0.4,-0.6 1.1,-1 1.8,-0.9l0.7,0.1c0.8,0 1.6,-0.2 2.2,-0.6L11,0.3z" /> <path - android:pathData="M12.34 6.53h4.05l-2 4.05a3.95 3.95 0 0 1-0.57 7.85 4.1 4.1 0 0 1-1.45-0.27" - android:strokeColor="@android:color/system_accent1_800" - android:strokeWidth="2"/> + android:pathData="M6.3,6.5l3,0l0,12.2" + android:strokeWidth="2.22" + android:strokeColor="@android:color/system_accent3_800" + /> + <path + android:pathData="M12.3,6.5h4l-2,4c2.2,0.3 3.6,2.4 3.3,4.5c-0.3,1.9 -1.9,3.3 -3.8,3.3c-0.5,0 -1,-0.1 -1.4,-0.3" + android:strokeWidth="2.22" + android:strokeColor="@android:color/system_accent3_800" + /> <path - android:pathData="M12.34 6.53h4.05l-2 4.05a3.95 3.95 0 0 1-0.57 7.85 4.1 4.1 0 0 1-1.45-0.27" + android:pathData="M6.3,6.5l3,0l0,12.2" + android:strokeWidth="0.56" android:strokeColor="@android:color/system_neutral1_100" - android:strokeWidth="0.5"/> - + /> + <path + android:pathData="M12.3,6.5h4l-2,4c2.2,0.3 3.6,2.4 3.3,4.5c-0.3,1.9 -1.9,3.3 -3.8,3.3c-0.5,0 -1,-0.1 -1.4,-0.3" + android:strokeWidth="0.56" + android:strokeColor="@android:color/system_neutral1_100" + /> </vector> - diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml index a9af187ee930..c382a6577857 100644 --- a/core/res/res/layout/autofill_fill_dialog.xml +++ b/core/res/res/layout/autofill_fill_dialog.xml @@ -27,7 +27,8 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" - android:paddingTop="24dp" + android:layout_marginTop="@dimen/autofill_save_outer_top_margin" + android:layout_marginBottom="24dp" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" android:orientation="vertical"> @@ -44,6 +45,7 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" + android:layout_marginTop="16dp" android:paddingStart="@dimen/autofill_save_inner_padding" android:paddingEnd="@dimen/autofill_save_inner_padding" android:visibility="gone" /> @@ -55,38 +57,30 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" - android:paddingStart="@dimen/autofill_save_inner_padding" - android:paddingEnd="@dimen/autofill_save_inner_padding" android:visibility="gone" + android:paddingBottom="24dp" android:layout_marginStart="24dp" - android:layout_marginEnd="24dp" - android:background="@drawable/autofill_dataset_picker_background"/> + android:layout_marginEnd="24dp" /> - <LinearLayout + <ListView + android:id="@+id/autofill_dialog_list" + android:layout_weight="1" android:layout_width="fill_parent" - android:layout_height="wrap_content" + android:layout_height="0dp" + android:paddingBottom="24dp" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" - android:theme="@style/Theme.DeviceDefault.AutofillHalfScreenDialogList" - android:orientation="vertical"> - <ListView - android:id="@+id/autofill_dialog_list" - android:layout_weight="1" - android:layout_width="fill_parent" - android:layout_height="0dp" - android:drawSelectorOnTop="true" - android:clickable="true" - android:divider="@drawable/list_divider_material" - android:background="@drawable/autofill_dataset_picker_background" - android:visibility="gone"/> - </LinearLayout> + android:clipToPadding="false" + android:drawSelectorOnTop="true" + android:clickable="true" + android:divider="@null" + android:visibility="gone" /> <com.android.internal.widget.ButtonBarLayout android:layout_width="match_parent" android:layout_height="48dp" android:layout_gravity="end" - android:clipToPadding="false" - android:layout_marginTop="32dp" + android:layout_marginTop="8dp" android:layout_marginBottom="18dp" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml index 5381017c26d6..fd08241deb3a 100644 --- a/core/res/res/layout/autofill_save.xml +++ b/core/res/res/layout/autofill_save.xml @@ -29,7 +29,6 @@ android:layout_marginTop="@dimen/autofill_save_outer_top_margin" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" - android:elevation="@dimen/autofill_elevation" android:background="?android:attr/colorSurface" android:gravity="center_horizontal" android:orientation="vertical"> @@ -52,6 +51,7 @@ android:layout_height="wrap_content" android:text="@string/autofill_save_title" android:layout_marginTop="16dp" + android:paddingBottom="24dp" android:gravity="center" android:textAppearance="@style/AutofillSaveUiTitle"> </TextView> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 8cf7e8ad6920..144ef6f2b325 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1611,7 +1611,7 @@ <string name="default_audio_route_category_name" msgid="5241740395748134483">"سیستم"</string> <string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"بلوتوثهای صوتی"</string> <string name="wireless_display_route_description" msgid="8297563323032966831">"صفحه نمایش بیسیم"</string> - <string name="media_route_button_content_description" msgid="2299223698196869956">"ارسال محتوا"</string> + <string name="media_route_button_content_description" msgid="2299223698196869956">"پخش محتوا"</string> <string name="media_route_chooser_title" msgid="6646594924991269208">"برقراری ارتباط با دستگاه"</string> <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"فرستادن محتوای صفحه به دستگاه"</string> <string name="media_route_chooser_searching" msgid="6119673534251329535">"درحال جستجوی دستگاهها…"</string> @@ -2133,7 +2133,7 @@ <string name="resolver_work_tab" msgid="2690019516263167035">"کاری"</string> <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"نمای شخصی"</string> <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"نمای کاری"</string> - <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"سرپرست سیستم آن را مسدود کرده است"</string> + <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"سرپرست فناوری اطلاعات آن را مسدود کرده است"</string> <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"نمیتوان این محتوا را با برنامههای کاری همرسانی کرد"</string> <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"نمیتوان این محتوا را با برنامههای کاری باز کرد"</string> <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"نمیتوان این محتوا را با برنامههای شخصی همرسانی کرد"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 5d9275ee1879..b0576b856b34 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1709,7 +1709,7 @@ <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"หากต้องการสลับระหว่างฟีเจอร์ต่างๆ ให้ใช้ 3 นิ้วเลื่อนขึ้นแล้วค้างไว้"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"การขยาย"</string> <string name="user_switched" msgid="7249833311585228097">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string> - <string name="user_switching_message" msgid="1912993630661332336">"กำลังเปลี่ยนเป็น <xliff:g id="NAME">%1$s</xliff:g>…"</string> + <string name="user_switching_message" msgid="1912993630661332336">"กำลังเปลี่ยนเป็น<xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"กำลังออกจากระบบ <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="owner_name" msgid="8713560351570795743">"เจ้าของ"</string> <string name="guest_name" msgid="8502103277839834324">"ผู้ใช้ชั่วคราว"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 54c3490740e5..2fc6da80dea9 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -5658,6 +5658,9 @@ <!-- Determines whether SafetyCenter feature is enabled. --> <bool name="config_enableSafetyCenter">true</bool> + <!-- Config for whether Safety Protection is enabled. --> + <bool name="config_safetyProtectionEnabled">false</bool> + <!-- Flag indicating if help links for Settings app should be enabled. --> <bool name="config_settingsHelpLinksEnabled">false</bool> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index bb36ededc581..b754100a3ed6 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -873,7 +873,7 @@ <dimen name="autofill_save_title_start_padding">8dp</dimen> <dimen name="autofill_save_scroll_view_top_margin">16dp</dimen> <dimen name="autofill_save_button_bar_padding">16dp</dimen> - <dimen name="autofill_dialog_corner_radius">28dp</dimen> + <dimen name="autofill_dialog_corner_radius">24dp</dimen> <!-- Max height of the the autofill save custom subtitle as a fraction of the screen width/height --> <dimen name="autofill_save_custom_subtitle_max_height">20%</dimen> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 96e8de0d2d64..4e7e20ca10b0 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4738,6 +4738,8 @@ <java-symbol type="bool" name="config_enableSafetyCenter" /> + <java-symbol type="bool" name="config_safetyProtectionEnabled" /> + <java-symbol type="string" name="config_devicePolicyManagementUpdater" /> <java-symbol type="string" name="config_deviceSpecificDeviceStatePolicyProvider" /> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 7ea32a6d8f86..41e23647a6a4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -76,6 +76,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.util.Slog; +import android.view.Choreographer; import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationRunner; import android.view.RemoteAnimationAdapter; @@ -1124,6 +1125,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mDividerFadeInAnimator.cancel(); return; } + transaction.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId()); transaction.setAlpha(dividerLeash, (float) animation.getAnimatedValue()); transaction.apply(); }); @@ -1216,17 +1218,23 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Override public void onLayoutPositionChanging(SplitLayout layout) { - mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t, false /* applyResizingOffset */)); + final SurfaceControl.Transaction t = mTransactionPool.acquire(); + t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId()); + updateSurfaceBounds(layout, t, false /* applyResizingOffset */); + t.apply(); + mTransactionPool.release(t); } @Override public void onLayoutSizeChanging(SplitLayout layout) { - mSyncQueue.runInSync(t -> { - setResizingSplits(true /* resizing */); - updateSurfaceBounds(layout, t, true /* applyResizingOffset */); - mMainStage.onResizing(getMainStageBounds(), t); - mSideStage.onResizing(getSideStageBounds(), t); - }); + final SurfaceControl.Transaction t = mTransactionPool.acquire(); + t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId()); + setResizingSplits(true /* resizing */); + updateSurfaceBounds(layout, t, true /* applyResizingOffset */); + mMainStage.onResizing(getMainStageBounds(), t); + mSideStage.onResizing(getSideStageBounds(), t); + t.apply(); + mTransactionPool.release(t); } @Override diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 04549b2d46f4..b1aeebecbfec 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -124,7 +124,7 @@ <string name="bluetooth_profile_sap" msgid="8304170950447934386">"دسترسی سیمکارت"</string> <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"صدای HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string> <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"صدای HD"</string> - <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"سمعکها"</string> + <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"سمعک"</string> <string name="bluetooth_profile_le_audio" msgid="5158149987518342036">"LE_AUDIO"</string> <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"به سمعک متصل شد"</string> <string name="bluetooth_le_audio_profile_summary_connected" msgid="3162538609379333442">"متصل به LE_AUDIO"</string> @@ -144,7 +144,7 @@ <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"استفاده برای تلفن صوتی"</string> <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"استفاده برای انتقال فایل"</string> <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"استفاده برای چاپ"</string> - <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"استفاده برای سمعکها"</string> + <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"استفاده کردن برای سمعک"</string> <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"استفاده برای LE_AUDIO"</string> <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"مرتبطسازی"</string> <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"مرتبطسازی"</string> @@ -184,7 +184,7 @@ <string name="launch_defaults_some" msgid="3631650616557252926">"بعضی پیشفرضها تنظیم شدهاند"</string> <string name="launch_defaults_none" msgid="8049374306261262709">"پیشفرضی تنظیم نشده است"</string> <string name="tts_settings" msgid="8130616705989351312">"تنظیمات متن به گفتار"</string> - <string name="tts_settings_title" msgid="7602210956640483039">"خروجی تبدیل متن به گفتار"</string> + <string name="tts_settings_title" msgid="7602210956640483039">"خروجی نوشتار به گفتار"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"سرعت گفتار"</string> <string name="tts_default_rate_summary" msgid="3781937042151716987">"سرعتی که متن خوانده میشود"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"زیر و بمی صدا"</string> @@ -643,7 +643,7 @@ <string name="dream_complication_title_date" msgid="8661176085446135789">"تاریخ"</string> <string name="dream_complication_title_weather" msgid="598609151677172783">"آبوهوا"</string> <string name="dream_complication_title_aqi" msgid="4587552608957834110">"کیفیت هوا"</string> - <string name="dream_complication_title_cast_info" msgid="4038776652841885084">"اطلاعات ارسال محتوا"</string> + <string name="dream_complication_title_cast_info" msgid="4038776652841885084">"اطلاعات پخش محتوا"</string> <string name="avatar_picker_title" msgid="8492884172713170652">"انتخاب عکس نمایه"</string> <string name="default_user_icon_description" msgid="6554047177298972638">"نماد کاربر پیشفرض"</string> <string name="physical_keyboard_title" msgid="4811935435315835220">"صفحهکلید فیزیکی"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 8c3f1fad8211..861c1833fdf9 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -371,7 +371,7 @@ <string name="show_hw_layers_updates" msgid="5268370750002509767">"Atualizações de camadas de hardware"</string> <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Piscar camadas de hardware em verde ao atualizar"</string> <string name="debug_hw_overdraw" msgid="8944851091008756796">"Depurar overdraw da GPU"</string> - <string name="disable_overlays" msgid="4206590799671557143">"Desativar sobreposição HW"</string> + <string name="disable_overlays" msgid="4206590799671557143">"Desativar sobreposição de HW"</string> <string name="disable_overlays_summary" msgid="1954852414363338166">"Sempre usar a GPU para composição de tela"</string> <string name="simulate_color_space" msgid="1206503300335835151">"Simular espaço de cores"</string> <string name="enable_opengl_traces_title" msgid="4638773318659125196">"Ativar rastream. OpenGL"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 8c3f1fad8211..861c1833fdf9 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -371,7 +371,7 @@ <string name="show_hw_layers_updates" msgid="5268370750002509767">"Atualizações de camadas de hardware"</string> <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Piscar camadas de hardware em verde ao atualizar"</string> <string name="debug_hw_overdraw" msgid="8944851091008756796">"Depurar overdraw da GPU"</string> - <string name="disable_overlays" msgid="4206590799671557143">"Desativar sobreposição HW"</string> + <string name="disable_overlays" msgid="4206590799671557143">"Desativar sobreposição de HW"</string> <string name="disable_overlays_summary" msgid="1954852414363338166">"Sempre usar a GPU para composição de tela"</string> <string name="simulate_color_space" msgid="1206503300335835151">"Simular espaço de cores"</string> <string name="enable_opengl_traces_title" msgid="4638773318659125196">"Ativar rastream. OpenGL"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java index 1804e86a98f0..c829bc316246 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java @@ -33,6 +33,7 @@ import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_SELECTED; +import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.Drawable; import android.media.MediaRoute2Info; @@ -268,6 +269,20 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { } /** + * Checks if route's volume is fixed, if true, we should disable volume control for the device. + * + * @return route for this device is fixed. + */ + @SuppressLint("NewApi") + public boolean isVolumeFixed() { + if (mRouteInfo == null) { + Log.w(TAG, "RouteInfo is empty, regarded as volume fixed."); + return true; + } + return mRouteInfo.getVolumeHandling() == MediaRoute2Info.PLAYBACK_VOLUME_FIXED; + } + + /** * Transfer MediaDevice for media * * @return result of transfer media @@ -439,7 +454,7 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { * Check if it is muting expected device * @return {@code true} if it is muting expected device, otherwise return {@code false} */ - protected boolean isMutingExpectedDevice() { + public boolean isMutingExpectedDevice() { return false; } diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt index 8e34c4757f37..b3dd95553ed0 100644 --- a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt +++ b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt @@ -435,7 +435,7 @@ class ColorScheme( val h = "H${hct.hue.roundToInt().toString().padEnd(width)}" val c = "C${hct.chroma.roundToInt().toString().padEnd(width)}" val t = "T${CamUtils.lstarFromInt(color).roundToInt().toString().padEnd(width)}" - val hex = Integer.toHexString(color).replaceRange(0, 2, "").uppercase() + val hex = Integer.toHexString(color and 0xffffff).padStart(6, '0').uppercase() return "$h$c$t = #$hex" } diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index e48e45593ebf..32848fd4b2cb 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Teks is gekopieer"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Prent is gekopieer"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Inhoud is gekopieer"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Knipbordredigeerder"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Knipbord"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Prentvoorskou"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"wysig"</string> <string name="add" msgid="81036585205287996">"Voeg by"</string> <string name="manage_users" msgid="1823875311934643849">"Bestuur gebruikers"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Sleep na verdeelde skerm word nie vir hierdie kennisgewing gesteun nie."</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 1991259744ce..f2d56b2c3c84 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"ካሜራ"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"ስልክ"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"የድምጽ እርዳታ"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"የኪስ ቦርሳ"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"የQR ኮድ መቃኛ"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"ክፈት"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"መሣሪያ ተቆልፏል"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"ጽሁፍ ተቀድቷል"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"ምስል ተቀድቷል"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"ይዘት ተቀድቷል"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"የቅንጥብ ሰሌዳ አርታዒ"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"የቅንጥብ ሰሌዳ"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"የምስል ቅድመ-እይታ"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"አርትዕ"</string> <string name="add" msgid="81036585205287996">"አክል"</string> <string name="manage_users" msgid="1823875311934643849">"ተጠቃሚዎችን ያስተዳድሩ"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ይህ ማሳወቂያ ወደ Splitscreen መጎተትን አይደግፍም።"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 9bb455e5a4a8..ad1a34d26f25 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -973,14 +973,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"تم نسخ النص."</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"تم نسخ الصورة."</string> <string name="clipboard_content_copied" msgid="144452398567828145">"تم نسخ المحتوى."</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"محرِّر الحافظة"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"الحافظة"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"معاينة الصورة"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"التعديل"</string> <string name="add" msgid="81036585205287996">"إضافة"</string> <string name="manage_users" msgid="1823875311934643849">"إدارة المستخدمين"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"لا يتيح هذا الإشعار السحب لتقسيم الشاشة."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 8286ee611f87..173a33e7e88d 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"পাঠ প্ৰতিলিপি কৰা হ’ল"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"প্ৰতিচ্ছবি প্ৰতিলিপি কৰা হ’ল"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"সমল প্ৰতিলিপি কৰা হ’ল"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"ক্লিপব’ৰ্ড সম্পাদক"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"ক্লিপব’ৰ্ড"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"প্ৰতিচ্ছবিৰ পূৰ্বদৰ্শন"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"সম্পাদনা কৰক"</string> <string name="add" msgid="81036585205287996">"যোগ দিয়ক"</string> <string name="manage_users" msgid="1823875311934643849">"ব্যৱহাৰকাৰী পৰিচালনা কৰক"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"এই জাননীটোৱে টানি আনি এৰাৰ পৰা বিভাজিত স্ক্ৰীন সমৰ্থন নকৰে।"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 1620056aab42..f1a3c69eed5d 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Mətn kopyalanıb"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Şəkil Kopyalanıb"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Məzmun kopyalanıb"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Mübadilə Buferi Redaktoru"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Mübadilə buferi"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Şəkil önizləməsi"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"redaktə"</string> <string name="add" msgid="81036585205287996">"Əlavə edin"</string> <string name="manage_users" msgid="1823875311934643849">"İstifadəçiləri idarə edin"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildiriş Ayrılmış ekrana sürüşdürməyi dəstəkləmir."</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index e18316fcd9f9..615a7090b21b 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -952,14 +952,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Tekst je kopiran"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Slika je kopirana"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Sadržaj je kopiran"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Uređivač privremene memorije"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Privremena memorija"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Pregled slike"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"izmenite"</string> <string name="add" msgid="81036585205287996">"Dodaj"</string> <string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obaveštenje ne podržava prevlačenje na podeljeni ekran."</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 5ea3a8c14fce..63010288e71c 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -959,14 +959,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Тэкст скапіраваны"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Відарыс скапіраваны"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Змесціва скапіравана"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Рэдактар буфера абмену"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Буфер абмену"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Папярэдні прагляд відарыса"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"змяніць"</string> <string name="add" msgid="81036585205287996">"Дадаць"</string> <string name="manage_users" msgid="1823875311934643849">"Кіраванне карыстальнікамі"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Гэта апавяшчэнне нельга перацягнуць на падзелены экран."</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index add650d80748..6e1b68ca7d5f 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Текстът е копиран"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Изображението е копирано"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Съдържанието е копирано"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Редактор на буферната памет"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Буферна памет"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Визуализация на изображението"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"редактиране"</string> <string name="add" msgid="81036585205287996">"Добавяне"</string> <string name="manage_users" msgid="1823875311934643849">"Управление на потребителите"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Това известие не поддържа плъзгане за разделяне на екрана."</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index a9e95f16b642..9138408de0db 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"টেক্সট কপি করা হয়েছে"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"ছবি কপি করা হয়েছে"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"কন্টেন্ট কপি করা হয়েছে"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"ক্লিপবোর্ড এডিটর"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"ক্লিপবোর্ড"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"ছবির প্রিভিউ"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"এডিট করতে"</string> <string name="add" msgid="81036585205287996">"যোগ করুন"</string> <string name="manage_users" msgid="1823875311934643849">"ব্যবহারকারীদের ম্যানেজ করুন"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"স্প্লিটস্ক্রিন মোডে এই বিজ্ঞপ্তি টেনে আনা যাবে না।"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index e814a5c745db..e8857ad070aa 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"El text s\'ha copiat"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"La imatge s\'ha copiat"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"El contingut s\'ha copiat"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor del porta-retalls"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Porta-retalls"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Previsualització de la imatge"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"editar"</string> <string name="add" msgid="81036585205287996">"Afegeix"</string> <string name="manage_users" msgid="1823875311934643849">"Gestiona els usuaris"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Aquesta notificació no es pot arrossegar a la pantalla dividida."</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 69de3b5adcb6..f46f82ab2eba 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -959,14 +959,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Text byl zkopírován"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Obrázek byl zkopírován"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Obsah byl zkopírován"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor schránky"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Schránka"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Náhled obrázku"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"upravit"</string> <string name="add" msgid="81036585205287996">"Přidat"</string> <string name="manage_users" msgid="1823875311934643849">"Správa uživatelů"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Toto oznámení nepodporuje přetažení na rozdělenou obrazovku."</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 8b2ef4e273de..dbbd74f8d889 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -372,7 +372,7 @@ <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Din organisation ejer denne enhed og overvåger muligvis netværkstrafikken"</string> <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ejer denne enhed og overvåger muligvis netværkstrafikken"</string> <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Denne enhed er leveret af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> - <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Denne enhed tilhører din organisation, og den har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> + <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Denne enhed tilhører din organisation, og den har forbindelse til internettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, og den har forbindelse til nettet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string> <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enhed tilhører din organisation"</string> <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string> @@ -382,8 +382,8 @@ <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan overvåge netværkstrafik på din arbejdsprofil"</string> <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Din it-administrator kan se netværksaktivitet på din arbejdsprofil"</string> <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Netværket kan være overvåget"</string> - <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Denne enhed har forbindelse til nettet via VPN-forbindelser"</string> - <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Dine arbejdsapps har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> + <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Denne enhed har forbindelse til internettet via VPN-forbindelser"</string> + <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Dine arbejdsapps har forbindelse til internettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Dine personlige apps har forbindelse til internettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Denne enhed har forbindelse til internettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Denne enhed er leveret af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> @@ -401,9 +401,9 @@ <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Der er installeret et nøglecenter på denne enhed. Din sikre netværkstrafik kan overvåges eller ændres."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Din administrator har aktiveret netværksregistrering, som overvåger trafik på din enhed."</string> <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Din administrator har aktiveret netværkslogging, som overvåger trafik på din arbejdsprofil, men ikke på din personlige profil."</string> - <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Denne enhed har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din netværksaktivitet, herunder mails og browserdata, er synlig for din it-administrator."</string> - <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Denne enhed har forbindelse til nettet via <xliff:g id="VPN_APP_0">%1$s</xliff:g> og <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Din netværksaktivitet, herunder mails og browserdata, er synlig for din it-administrator."</string> - <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Dine arbejdsapps har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din netværksaktivitet i arbejdsapps, herunder mails og browserdata, er synlig for din it-administrator og VPN-udbyder."</string> + <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Denne enhed har forbindelse til internettet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din netværksaktivitet, herunder mails og browserdata, er synlig for din it-administrator."</string> + <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Denne enhed har forbindelse til internettet via <xliff:g id="VPN_APP_0">%1$s</xliff:g> og <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Din netværksaktivitet, herunder mails og browserdata, er synlig for din it-administrator."</string> + <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Dine arbejdsapps har forbindelse til internettet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din netværksaktivitet i arbejdsapps, herunder mails og browserdata, er synlig for din it-administrator og VPN-udbyder."</string> <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Dine personlige apps har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din netværksaktivitet, herunder mails og browserdata, er synlig for din VPN-udbyder."</string> <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string> <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Åbn VPN-indstillinger"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Teksten blev kopieret"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Billedet blev kopieret"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Indholdet blev kopieret"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Redigeringsværktøj til udklipsholder"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Udklipsholder"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Forhåndsvisning af billede"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"redigere"</string> <string name="add" msgid="81036585205287996">"Tilføj"</string> <string name="manage_users" msgid="1823875311934643849">"Administrer brugere"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Denne notifikation kan ikke trækkes til en opdelt skærm."</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 52b22090f261..f78662508959 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Text kopiert"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Bild kopiert"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Inhalt kopiert"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Zwischenablage bearbeiten"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Zwischenablage"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Bildvorschau"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"bearbeiten"</string> <string name="add" msgid="81036585205287996">"Hinzufügen"</string> <string name="manage_users" msgid="1823875311934643849">"Nutzer verwalten"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Diese Benachrichtigung lässt sich nicht auf einen geteilten Bildschirm ziehen."</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index e3b85817394d..8e0e47c2e53e 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Se copió el texto"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Se copió la imagen"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Se copió el contenido"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor de portapapeles"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Portapapeles"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Vista previa de la imagen"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"editar"</string> <string name="add" msgid="81036585205287996">"Agregar"</string> <string name="manage_users" msgid="1823875311934643849">"Administrar usuarios"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación no admite arrastrar entre pantallas divididas."</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index f2f4bbb463ed..220f2651af43 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"Cámara"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"Teléfono"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Asistente voz"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"Cartera"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Escáner de códigos QR"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"Desbloquear"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Texto copiado"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Imagen copiada"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Contenido copiado"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor del portapapeles"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Portapapeles"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Vista previa de la imagen"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"editar"</string> <string name="add" msgid="81036585205287996">"Añadir"</string> <string name="manage_users" msgid="1823875311934643849">"Gestionar usuarios"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación no se puede arrastrar a la pantalla dividida."</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 9bd5f0ad7b66..0cefc93c81ed 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"Kaamera"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Häälabi"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"Rahakott"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR-koodi skanner"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"Luku avamine"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"Seade on lukustatud"</string> @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"Kuva demorežiim"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string> <string name="status_bar_alarm" msgid="87160847643623352">"Äratus"</string> - <string name="wallet_title" msgid="5369767670735827105">"Rahakott"</string> + <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Seadistage kiirem ja turvalisem viis telefoniga ostmiseks"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Kuva kõik"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Puudutage avamiseks"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Tekst kopeeriti"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Pilt kopeeriti"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Sisu kopeeriti"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Lõikelaua sisu muutmine"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Lõikelaud"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Pildi eelvaade"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"muutmine"</string> <string name="add" msgid="81036585205287996">"Lisa"</string> <string name="manage_users" msgid="1823875311934643849">"Kasutajate haldamine"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"See märguanne ei toeta jagatud ekraanikuvale lohistamist."</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 896f7a0d63a0..fc760977d58c 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -406,7 +406,7 @@ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Laneko aplikazioak <xliff:g id="VPN_APP">%1$s</xliff:g> bidez daude konektatuta Internetera. IKT saileko administratzaileak eta VPNaren hornitzaileak laneko aplikazioen bidez egiten dituzun sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko dituzte."</string> <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Aplikazio pertsonalak <xliff:g id="VPN_APP">%1$s</xliff:g> bidez daude konektatuta Internetera. IKT saileko administratzaileak sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko ditu."</string> <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string> - <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Ireki VPN ezarpenak"</string> + <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Ireki VPN sarearen ezarpenak"</string> <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Zure gurasoak kudeatzen du gailua. Zure gurasoak gailuko informazioa ikusi eta kudea dezake; besteak beste, zer aplikazio erabiltzen dituzun, zure kokapena zein den eta pantaila aurrean zenbat eta noiz egoten zaren."</string> <string name="legacy_vpn_name" msgid="4174223520162559145">"VPNa"</string> <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent bidez desblokeatuta"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 06a14f2dee95..5676865ecffa 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -78,7 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"دوباره نماگرفت بگیرید"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"نماگرفت ذخیره نمیشود"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"برنامه یا سازمان شما اجازه نمیدهند نماگرفت بگیرید."</string> - <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"سرپرست سیستم گرفتن نماگرفت را مسدود کرده است"</string> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"سرپرست فناوری اطلاعات گرفتن نماگرفت را مسدود کرده است"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"ویرایش"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"ویرایش نماگرفت"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"همرسانی نماگرفت"</string> @@ -353,10 +353,10 @@ <string name="user_remove_user_title" msgid="9124124694835811874">"کاربر حذف شود؟"</string> <string name="user_remove_user_message" msgid="6702834122128031833">"همه برنامهها و دادههای این کاربر حذف میشود."</string> <string name="user_remove_user_remove" msgid="8387386066949061256">"حذف"</string> - <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> به همه اطلاعاتی که روی صفحهنمایش قابلمشاهد است و هنگام ضبط کردن یا ارسال محتوا از دستگاهتان پخش میشود دسترسی خواهد داشت. این شامل اطلاعاتی مانند گذرواژهها، جزئیات پرداخت، عکسها، پیامها، و صداهایی که پخش میکنید میشود."</string> - <string name="media_projection_dialog_service_text" msgid="958000992162214611">"سرویس ارائهدهنده این عملکرد به همه اطلاعاتی که روی صفحهنمایش قابلمشاهد است و هنگام ضبط کردن یا ارسال محتوا از دستگاهتان پخش میشود دسترسی خواهد داشت. این شامل اطلاعاتی مانند گذرواژهها، جزئیات پرداخت، عکسها، پیامها، و صداهایی که پخش میکنید میشود."</string> - <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ضبط یا ارسال محتوا شروع شود؟"</string> - <string name="media_projection_dialog_title" msgid="3316063622495360646">"ضبط یا ارسال محتوا با <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> شروع شود؟"</string> + <string name="media_projection_dialog_text" msgid="1755705274910034772">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> به همه اطلاعاتی که روی صفحهنمایش قابلمشاهد است و هنگام ضبط کردن یا پخش محتوا از دستگاهتان پخش میشود دسترسی خواهد داشت. این شامل اطلاعاتی مانند گذرواژهها، جزئیات پرداخت، عکسها، پیامها، و صداهایی که پخش میکنید میشود."</string> + <string name="media_projection_dialog_service_text" msgid="958000992162214611">"سرویس ارائهدهنده این عملکرد به همه اطلاعاتی که روی صفحهنمایش قابلمشاهد است و هنگام ضبط کردن یا پخش محتوا از دستگاهتان پخش میشود دسترسی خواهد داشت. این شامل اطلاعاتی مانند گذرواژهها، جزئیات پرداخت، عکسها، پیامها، و صداهایی که پخش میکنید میشود."</string> + <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"ضبط یا پخش محتوا شروع شود؟"</string> + <string name="media_projection_dialog_title" msgid="3316063622495360646">"ضبط یا پخش محتوا با <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> شروع شود؟"</string> <string name="clear_all_notifications_text" msgid="348312370303046130">"پاک کردن همه موارد"</string> <string name="manage_notifications_text" msgid="6885645344647733116">"مدیریت"</string> <string name="manage_notifications_history_text" msgid="57055985396576230">"سابقه"</string> @@ -380,7 +380,7 @@ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"این دستگاه متعلق به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> است و ازطریق چند VPN به اینترنت متصل شده است"</string> <string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"ممکن است سازمان شما ترافیک شبکه را در نمایه کاریتان پایش کند"</string> <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ممکن است ترافیک شبکه را در نمایه کاری شما پایش کند"</string> - <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"سرپرست سیستم میتواند فعالیت شبکه نمایه کاری را ببیند"</string> + <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"سرپرست فناوری اطلاعات میتواند فعالیت شبکه نمایه کاری را ببیند"</string> <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ممکن است شبکه پایش شود"</string> <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"این دستگاه ازطریق چند VPN به اینترنت متصل شده است"</string> <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"برنامههای کاریتان ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است"</string> @@ -401,9 +401,9 @@ <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"مرجع گواهینامهای در این دستگاه نصب شده است. ممکن است ترافیک امن شبکه شما پایش یا تغییر داده شود."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"سرپرست سیستم شما گزارشگیری از شبکه را (که ترافیک دستگاه شما را پایش میکند) روشن کرده است."</string> <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"سرپرست شما گزارشگیری شبکه را که بر ترافیک نمایه کاریتان نظارت میکند، اما بر ترافیک نمایه شخصیتان نظارت نمیکند روشن کرده است."</string> - <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"این دستگاه ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است. سرپرست سیستم شما میتواند فعالیت شبکه شما را (ازجمله ایمیلها و دادههای مرور) ببیند."</string> - <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"این دستگاه ازطریق <xliff:g id="VPN_APP_0">%1$s</xliff:g> و <xliff:g id="VPN_APP_1">%2$s</xliff:g> به اینترنت متصل شده است. سرپرست سیستم شما میتواند فعالیت شبکه شما را (ازجمله ایمیلها و دادههای مرور) ببیند."</string> - <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"برنامههای کاریتان ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است. ارائهدهنده VPN و سرپرست سیستم شما میتوانند فعالیت شبکه شما در برنامههای کاری را (ازجمله ایمیلها و دادههای مرور) ببینند."</string> + <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"این دستگاه ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است. سرپرست فناوری اطلاعات شما میتواند فعالیت شبکه شما را (ازجمله ایمیلها و دادههای مرور) ببیند."</string> + <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"این دستگاه ازطریق <xliff:g id="VPN_APP_0">%1$s</xliff:g> و <xliff:g id="VPN_APP_1">%2$s</xliff:g> به اینترنت متصل شده است. سرپرست فناوری اطلاعات شما میتواند فعالیت شبکه شما را (ازجمله ایمیلها و دادههای مرور) ببیند."</string> + <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"برنامههای کاریتان ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است. ارائهدهنده VPN و سرپرست فناوری اطلاعات شما میتوانند فعالیت شبکه شما در برنامههای کاری را (ازجمله ایمیلها و دادههای مرور) ببینند."</string> <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"برنامههای شخصیتان ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است. ارائهدهنده VPN شما میتواند فعالیت شبکه شما را (ازجمله ایمیلها و دادههای مرور) ببیند."</string> <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string> <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"باز کردن تنظیمات VPN"</string> @@ -553,7 +553,7 @@ <string name="keyboard_key_dpad_right" msgid="6282105433822321767">"راست"</string> <string name="keyboard_key_dpad_center" msgid="4079412840715672825">"مرکز"</string> <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string> - <string name="keyboard_key_space" msgid="6980847564173394012">"فاصله"</string> + <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string> <string name="keyboard_key_enter" msgid="8633362970109751646">"ورود"</string> <string name="keyboard_key_backspace" msgid="4095278312039628074">"پسبر"</string> <string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"پخش/مکث"</string> @@ -843,7 +843,7 @@ <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"مرتبط کردن دستگاه جدید"</string> <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"برای ارسال محتوای این جلسه، لطفاً برنامه را باز کنید."</string> <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"برنامه ناشناس"</string> - <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"توقف ارسال محتوا"</string> + <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"توقف پخش محتوا"</string> <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"دستگاههای دردسترس برای خروجی صدا."</string> <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"میزان صدا"</string> <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"همهفرتستی چطور کار میکند"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"نوشتار کپی شد"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"تصویر کپی شد"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"محتوا کپی شد"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"ویرایشگر بریدهدان"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"بریدهدان"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"پیشنمای تصویر"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"ویرایش کردن"</string> <string name="add" msgid="81036585205287996">"افزودن"</string> <string name="manage_users" msgid="1823875311934643849">"مدیریت کاربران"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"این اعلان از تنظیم کشیدن برای دو نیمه کردن صفحه پشتیبانی نمیکند."</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index c811d2251691..d1cdb9f0fb19 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Teksti kopioitu"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Kuva kopioitu"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Sisältö kopioitu"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Leikepöydän muokkaaja"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Leikepöytä"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Kuvan esikatselu"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"muokkaa"</string> <string name="add" msgid="81036585205287996">"Lisää"</string> <string name="manage_users" msgid="1823875311934643849">"Ylläpidä käyttäjiä"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Ilmoitus ei tue jaetulle näytölle vetämistä."</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 1c728869f102..db37f776688b 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Texte copié"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Image copiée"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Contenu copié"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Éditeur du presse-papiers"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Presse-papiers"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Aperçu de l\'image"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"modifier"</string> <string name="add" msgid="81036585205287996">"Ajouter"</string> <string name="manage_users" msgid="1823875311934643849">"Gérer les utilisateurs"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Cette notification ne prend pas en charge le partage d\'écran par glissement."</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index d0d781f867f5..dc708e8b8f1d 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Texte copié"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Image copiée"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Contenu copié"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Éditeur du presse-papiers"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Presse-papiers"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Aperçu de l\'image"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"modifier"</string> <string name="add" msgid="81036585205287996">"Ajouter"</string> <string name="manage_users" msgid="1823875311934643849">"Gérer les utilisateurs"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Impossible de faire glisser cette notification vers l\'écran partagé."</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 1718992e90fc..e64891850f44 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Texto copiado"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Imaxe copiada"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Contido copiado"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor do portapapeis"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Portapapeis"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Vista previa da imaxe"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"editar"</string> <string name="add" msgid="81036585205287996">"Engadir"</string> <string name="manage_users" msgid="1823875311934643849">"Xestionar usuarios"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación non pode arrastrarse á pantalla dividida."</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 4fc38431ca15..c015403d52f1 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"કૅમેરા"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"ફોન"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"વૉઇસ સહાય"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"વૉલેટ"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR કોડ સ્કૅનર"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"અનલૉક કરો"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"ડિવાઇસ લૉક કરેલું છે"</string> @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"ડેમો મોડ બતાવો"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"ઇથરનેટ"</string> <string name="status_bar_alarm" msgid="87160847643623352">"અલાર્મ"</string> - <string name="wallet_title" msgid="5369767670735827105">"વૉલેટ"</string> + <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"તમારા ફોન વડે વધુ ઝડપી તેમજ સુરક્ષિત ખરીદીઓ કરવાની રીત સેટઅપ કરી લો"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"બધું બતાવો"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"ખોલવા માટે ટૅપ કરો"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"ટેક્સ્ટ કૉપિ કરી"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"છબી કૉપિ કરી"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"કન્ટેન્ટ કૉપિ કર્યું"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"ક્લિપબોર્ડ એડિટર"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"ક્લિપબોર્ડ"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"છબીનો પ્રીવ્યૂ"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"ફેરફાર કરો"</string> <string name="add" msgid="81036585205287996">"ઉમેરો"</string> <string name="manage_users" msgid="1823875311934643849">"વપરાશકર્તાઓને મેનેજ કરો"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"આ નોટિફિકેશન તેને સ્પ્લિટસ્ક્રીનમાં ખેંચવાની સુવિધાને સપોર્ટ કરતું નથી."</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 440b3768a8ba..0ca56fc60038 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"टेक्स्ट कॉपी किया गया"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"इमेज कॉपी की गई"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"कॉन्टेंट कॉपी किया गया"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"क्लिपबोर्ड एडिटर"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"क्लिपबोर्ड"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"इमेज की झलक"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"बदलाव करें"</string> <string name="add" msgid="81036585205287996">"जोड़ें"</string> <string name="manage_users" msgid="1823875311934643849">"उपयोगकर्ताओं को मैनेज करें"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"इस सूचना को स्प्लिट स्क्रीन मोड में, खींचा और छोड़ा नहीं जा सकता."</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 330363a8f713..e34a08e624af 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -465,7 +465,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži demo način"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string> <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string> - <string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string> + <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Postavite aplikaciju za bržu i sigurniju kupnju telefonom"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Prikaži sve"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Dodirnite za otvaranje"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index c2e2acef73bf..271b1ebecb3c 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Szöveg másolva"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Kép másolva"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Tartalom másolva"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Vágólapszerkesztő"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Vágólap"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Kép előnézete"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"szerkesztés"</string> <string name="add" msgid="81036585205287996">"Hozzáadás"</string> <string name="manage_users" msgid="1823875311934643849">"Felhasználók kezelése"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Az értesítés nem támogatja a megosztott képernyőre való áthúzást."</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 6c9732175ccd..1c8a35140a6a 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Տեքստը պատճենվեց"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Պատկերը պատճենվեց"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Բովանդակությունը պատճենվեց"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Սեղմատախտակի խմբագրիչ"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Սեղմատախտակ"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Պատկերի նախադիտում"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"փոփոխել"</string> <string name="add" msgid="81036585205287996">"Ավելացնել"</string> <string name="manage_users" msgid="1823875311934643849">"Օգտատերերի կառավարում"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Այս ծանուցումը հնարավոր չէ քաշել տրոհված էկրանի մեկ հատվածից մյուսը։"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 0eb5ef3563c4..cf36c608e436 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Teks disalin"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Gambar disalin"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Konten disalin"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor Papan Klip"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Papan klip"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Pratinjau gambar"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"mengedit"</string> <string name="add" msgid="81036585205287996">"Tambahkan"</string> <string name="manage_users" msgid="1823875311934643849">"Kelola pengguna"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Notifikasi ini tidak mendukung fitur tarik ke Layar terpisah."</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 372dd1cb6c98..c786d0d79c06 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Texti afritaður"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Mynd afrituð"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Efni afritað"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Klippiborðsritill"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Klippiborð"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Forskoðun myndar"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"breyta"</string> <string name="add" msgid="81036585205287996">"Bæta við"</string> <string name="manage_users" msgid="1823875311934643849">"Stjórna notendum"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Þessi tilkynning styður ekki að draga yfir á skiptan skjá."</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index e0af9980d6c8..7065f7fcadeb 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Testo copiato"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Immagine copiata"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Contenuti copiati"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor di appunti"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Appunti"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Anteprima immagine"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"modificare"</string> <string name="add" msgid="81036585205287996">"Aggiungi"</string> <string name="manage_users" msgid="1823875311934643849">"Gestisci utenti"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Non è possibile trascinare questa notifica tra le due parti dello schermo diviso."</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 8b45531fc3e0..aa8f6cb3a895 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -468,7 +468,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"הצגת מצב הדגמה"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"אתרנט"</string> <string name="status_bar_alarm" msgid="87160847643623352">"התראה"</string> - <string name="wallet_title" msgid="5369767670735827105">"ארנק"</string> + <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"מגדירים אמצעי תשלום ונהנים מביצוע מהיר ומאובטח יותר של רכישות באמצעות הטלפון"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"הצגת הכול"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"יש להקיש לפתיחה"</string> @@ -959,14 +959,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"הטקסט הועתק"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"התמונה הועתקה"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"התוכן הועתק"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"עורך הלוח"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"לוח"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"תצוגה מקדימה של תמונה"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"עריכה"</string> <string name="add" msgid="81036585205287996">"הוספה"</string> <string name="manage_users" msgid="1823875311934643849">"ניהול משתמשים"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ההתראה הזו לא תומכת בגרירה למסך מפוצל."</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index b0171dec8195..20bdf5f87923 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Мәтін көшірілді."</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Сурет көшірілді."</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Мазмұн көшірілді."</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Буфер редакторы"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Буфер"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Суретті алдын ала көру"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"өзгерту"</string> <string name="add" msgid="81036585205287996">"Қосу"</string> <string name="manage_users" msgid="1823875311934643849">"Пайдаланушыларды басқару"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Бұл хабарландыруды бөлінген экранға сүйреп апару мүмкін емес."</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 9aacc3b88451..eb2f68d95173 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"បានចម្លងអត្ថបទ"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"បានចម្លងរូបភាព"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"បានចម្លងខ្លឹមសារ"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"កម្មវិធីកែឃ្លីបបត"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"ឃ្លីបបត"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"មើលរូបភាពសាកល្បង"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"កែ"</string> <string name="add" msgid="81036585205287996">"បញ្ចូល"</string> <string name="manage_users" msgid="1823875311934643849">"គ្រប់គ្រងអ្នកប្រើប្រាស់"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ការជូនដំណឹងនេះមិនអាចឱ្យអូសដើម្បីបំបែកអេក្រង់បានទេ។"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 6aef3bd5a165..a32652e06789 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"ಪಠ್ಯವನ್ನು ನಕಲಿಸಲಾಗಿದೆ"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"ಚಿತ್ರವನ್ನು ನಕಲಿಸಲಾಗಿದೆ"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"ವಿಷಯವನ್ನು ನಕಲಿಸಲಾಗಿದೆ"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"ಕ್ಲಿಪ್ಬೋರ್ಡ್ ಎಡಿಟರ್"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"ಕ್ಲಿಪ್ಬೋರ್ಡ್"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"ಚಿತ್ರದ ಪೂರ್ವವೀಕ್ಷಣೆ"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"ಎಡಿಟ್ ಮಾಡಿ"</string> <string name="add" msgid="81036585205287996">"ಸೇರಿಸಿ"</string> <string name="manage_users" msgid="1823875311934643849">"ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಿ"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ಗೆ ಡ್ರ್ಯಾಗ್ ಮಾಡುವುದನ್ನು ಈ ಅಧಿಸೂಚನೆಯು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 899bca353b05..b14e9e8701e1 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"텍스트 복사됨"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"이미지 복사됨"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"콘텐츠 복사됨"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"클립보드 편집기"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"클립보드"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"이미지 미리보기"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"수정"</string> <string name="add" msgid="81036585205287996">"추가"</string> <string name="manage_users" msgid="1823875311934643849">"사용자 관리"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"드래그하여 화면을 분할하는 기능이 지원되지 않는 알림입니다."</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index deaeb431936b..11cdc7d7b6df 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"Демо режимин көрсөтүү"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string> <string name="status_bar_alarm" msgid="87160847643623352">"Ойготкуч"</string> - <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> + <string name="wallet_title" msgid="5369767670735827105">"Капчык"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Телефонуңуз менен тез жана коопсуз сатып алуу үчүн жөндөңүз"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Баарын көрсөтүү"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Ачуу үчүн таптап коюңуз"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Текст көчүрүлдү"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Сүрөт көчүрүлдү"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Мазмун көчүрүлдү"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Алмашуу буферин түзөткүч"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Алмашуу буфери"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Сүрөттү алдын ала көрүү"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"түзөтүү"</string> <string name="add" msgid="81036585205287996">"Кошуу"</string> <string name="manage_users" msgid="1823875311934643849">"Колдонуучуларды башкаруу"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Бул билдирмени бөлүнгөн экранда сүйрөөгө болбойт."</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 780e4c7f324b..cb86e04c2100 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"ກ້ອງ"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"ໂທລະສັບ"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ຊ່ວຍເຫຼືອທາງສຽງ"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"ກະເປົາ"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"ຕົວສະແກນລະຫັດ QR"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"ປົດລັອກ"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"ອຸປະກອນຖືກລັອກໄວ້"</string> @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"ສະແດງໂຫມດສາທິດ"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"ອີເທເນັດ"</string> <string name="status_bar_alarm" msgid="87160847643623352">"ໂມງປຸກ"</string> - <string name="wallet_title" msgid="5369767670735827105">"ກະເປົາ"</string> + <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"ຕັ້ງຄ່າເພື່ອຊື້ດ້ວຍໂທລະສັບຂອງທ່ານໄດ້ໄວຂຶ້ນ ແລະ ປອດໄພຂຶ້ນ"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"ສະແດງທັງໝົດ"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"ແຕະເພື່ອເປີດ"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"ສຳເນົາຂໍ້ຄວາມແລ້ວ"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"ສຳເນົາຮູບແລ້ວ"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"ສຳເນົາເນື້ອຫາແລ້ວ"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"ຕົວແກ້ໄຂຄລິບບອດ"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"ຄລິບບອດ"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"ຕົວຢ່າງຮູບ"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"ແກ້ໄຂ"</string> <string name="add" msgid="81036585205287996">"ເພີ່ມ"</string> <string name="manage_users" msgid="1823875311934643849">"ຈັດການຜູ້ໃຊ້"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ການແຈ້ງເຕືອນນີ້ບໍ່ຮອງຮັບການລາກໄປໃສ່ Splitscreen."</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index b4d5bcaaabd0..0df0af28b03d 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"Fotoaparatas"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"Telefonas"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Voice Assist"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"Piniginė"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR kodų skaitytuvas"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"Atrakinti"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"Įrenginys užrakintas"</string> @@ -468,7 +468,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"Rodyti demonstraciniu režimu"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"Eternetas"</string> <string name="status_bar_alarm" msgid="87160847643623352">"Signalas"</string> - <string name="wallet_title" msgid="5369767670735827105">"Piniginė"</string> + <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Nustatykite, kad galėtumėte greičiau ir saugiau pirkti telefonu"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Rodyti viską"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Palieskite, kad atidarytumėte"</string> @@ -959,14 +959,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Tekstas nukopijuotas"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Vaizdas nukopijuotas"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Turinys nukopijuotas"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Iškarpinės redagavimo priemonė"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Iškarpinė"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Vaizdo peržiūra"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"redaguoti"</string> <string name="add" msgid="81036585205287996">"Pridėti"</string> <string name="manage_users" msgid="1823875311934643849">"Tvarkyti naudotojus"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Šio pranešimo vilkimas išskaidyto ekrano režimu nepalaikomas."</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index a74447a9d0aa..93824c823078 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -952,14 +952,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Teksts ir nokopēts"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Attēls ir nokopēts"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Saturs ir nokopēts"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Starpliktuves redaktors"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Starpliktuve"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Attēla priekšskatījums"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"rediģētu"</string> <string name="add" msgid="81036585205287996">"Pievienot"</string> <string name="manage_users" msgid="1823875311934643849">"Pārvaldīt lietotājus"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Šis paziņojums neatbalsta vilkšanu uz dalīto ekrānu."</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 68afb045b920..ba150a9159b2 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Текстот е копиран"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Сликата е копирана"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Содржините се копирани"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Уредувач на привремена меморија"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Привремена меморија"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Преглед на сликата"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"измени"</string> <string name="add" msgid="81036585205287996">"Додај"</string> <string name="manage_users" msgid="1823875311934643849">"Управувајте со корисниците"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Известувањево не поддржува влечење на поделен екран."</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index b453c8cd1d36..2fa1640a7aba 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"Камер"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"Утас"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Дуут туслах"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"Түрийвч"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR код сканнер"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"Тайлах"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"Төхөөрөмжийг түгжсэн"</string> @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"Демо горимыг харуулах"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"Этернет"</string> <string name="status_bar_alarm" msgid="87160847643623352">"Сэрүүлэг"</string> - <string name="wallet_title" msgid="5369767670735827105">"Түрийвч"</string> + <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Утсаараа илүү хурдан, аюулгүй худалдан авалт хийхийн тулд тохируулгыг авна уу"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Бүгдийг харуулах"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Нээх бол товшино уу"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 1d303eb0fb4e..835d08507c51 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"मजकूर कॉपी केला"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"इमेज कॉपी केली"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"आशय कॉपी केला"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"क्लिपबोर्ड संपादक"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"क्लिपबोर्ड"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"इमेजचे पूर्वावलोकन"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"संपादित करा"</string> <string name="add" msgid="81036585205287996">"जोडा"</string> <string name="manage_users" msgid="1823875311934643849">"वापरकर्ते व्यवस्थापित करा"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ही सूचना स्प्लिटस्क्रीनवर ड्रॅग करण्याला सपोर्ट करत नाही."</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 778244331cf8..c4f30e5d6d0d 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Teks disalin"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Imej disalin"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Kandungan disalin"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor Papan Klip"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Papan klip"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Pratonton imej"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"edit"</string> <string name="add" msgid="81036585205287996">"Tambah"</string> <string name="manage_users" msgid="1823875311934643849">"Urus pengguna"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Pemberitahuan ini tidak menyokong penyeretan ke Skrin pisah."</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index ed509e231815..ae0eb50ab160 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -90,7 +90,7 @@ <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ဘယ်ဘက်အနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string> <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ညာဘက်အနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string> <string name="screenrecord_name" msgid="2596401223859996572">"ဖန်သားပြင် ရိုက်ကူးမှု"</string> - <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ဖန်သားပြင်ရိုက်ကူးနေသည်"</string> + <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"စကရင်ရိုက်ကူးမှု အပြီးသတ်နေသည်"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string> <string name="screenrecord_start_label" msgid="1750350278888217473">"စတင် ရိုက်ကူးမလား။"</string> <string name="screenrecord_description" msgid="1123231719680353736">"ရိုက်ကူးနေစဉ်အတွင်း Android စနစ်သည် သင့်ဖန်သားပြင်ပေါ်တွင် မြင်နိုင်သော (သို့) သင့်စက်ပစ္စည်းတွင် ဖွင့်ထားသော အရေးကြီးသည့် အချက်အလက်များကို ရိုက်ယူနိုင်သည်။ ၎င်းတွင် စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ ဓာတ်ပုံ၊ မက်ဆေ့ဂျ်နှင့် အသံများ ပါဝင်သည်။"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"စာသားကို မိတ္တူကူးပြီးပြီ"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"ပုံ ကူးပြီးပြီ"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"အကြောင်းအရာများကို ကူးယူပြီးပါပြီ"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"ကလစ်ဘုတ် တည်းဖြတ်စနစ်"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"ကလစ်ဘုတ်"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"ပုံအစမ်းကြည့်ခြင်း"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"တည်းဖြတ်ရန်"</string> <string name="add" msgid="81036585205287996">"ထည့်ရန်"</string> <string name="manage_users" msgid="1823875311934643849">"အသုံးပြုသူများ စီမံရန်"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ဤအကြောင်းကြားချက်သည် ‘မျက်နှာပြင်ခွဲ၍ပြသမှု’ သို့ ဖိဆွဲခြင်းကို မပံ့ပိုးပါ။"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 5f3bc0a0e413..e6324f416ae9 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Teksten er kopiert"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Bildet er kopiert"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Innholdet er kopiert"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Utklippstavleredigerer"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Utklippstavle"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Forhåndsvisning av bilde"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"redigere"</string> <string name="add" msgid="81036585205287996">"Legg til"</string> <string name="manage_users" msgid="1823875311934643849">"Administrer brukere"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Dette varselet støtter ikke at du drar det til en delt skjerm."</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index c9c5b06c42f1..a18cae414c8c 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"क्यामेरा"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"फोन"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"आवाज सहायता"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"वालेट"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR कोड स्क्यानर"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"खोल्नुहोस्"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"यन्त्र लक गरिएको छ"</string> @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"डेमो मोड देखाउनुहोस्"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"इथरनेट"</string> <string name="status_bar_alarm" msgid="87160847643623352">"अलार्म"</string> - <string name="wallet_title" msgid="5369767670735827105">"वालेट"</string> + <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"फोनमार्फत अझ छिटो र थप सुरक्षित तरिकाले खरिद गर्न भुक्तानी विधि सेटअप गर्नुहोस्"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"सबै देखाइयोस्"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"खोल्न ट्याप गर्नुहोस्"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"टेक्स्ट कपी गरिएको छ"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"फोटो कपी गरिएको छ"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"सामग्री कपी गरिएको छ"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"क्लिपबोर्ड एडिटर"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"क्लिपबोर्ड"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"फोटोको प्रिभ्यू"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"सम्पादन गर्नुहोस्"</string> <string name="add" msgid="81036585205287996">"हाल्नुहोस्"</string> <string name="manage_users" msgid="1823875311934643849">"प्रयोगकर्ताहरूको व्यवस्थापन गर्नुहोस्"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"यो सूचना ड्र्याग गरेर स्प्लिटस्क्रिनमा लैजान मिल्दैन।"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 15d16152ac74..eaa4ca168e9c 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Tekst gekopieerd"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Afbeelding gekopieerd"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Content gekopieerd"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Klembordeditor"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Klembord"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Afbeeldingsvoorbeeld"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"bewerken"</string> <string name="add" msgid="81036585205287996">"Toevoegen"</string> <string name="manage_users" msgid="1823875311934643849">"Gebruikers beheren"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Deze melding biedt geen ondersteuning voor slepen naar het gesplitste scherm."</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index f5328302412d..99243d2e447d 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"ଟେକ୍ସଟ କପି କରାଯାଇଛି"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"ଇମେଜ କପି କରାଯାଇଛି"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"ବିଷୟବସ୍ତୁ କପି କରାଯାଇଛି"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"କ୍ଲିପବୋର୍ଡ ଏଡିଟର"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"କ୍ଲିପବୋର୍ଡ"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"ଇମେଜ ପ୍ରିଭ୍ୟୁ"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"ଏଡିଟ"</string> <string name="add" msgid="81036585205287996">"ଯୋଗ କରନ୍ତୁ"</string> <string name="manage_users" msgid="1823875311934643849">"ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ଏହି ବିଜ୍ଞପ୍ତି ସ୍ପ୍ଲିଟସ୍କ୍ରିନକୁ ଡ୍ରାଗ କରିବାକୁ ସମର୍ଥନ କରେ ନାହିଁ।"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 60bc19eb47c1..a4631d8b1d36 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -959,14 +959,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Tekst został skopiowany"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Zdjęcie zostało skopiowane"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Treści zostały skopiowane"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Edytor schowka"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Schowek"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Podgląd obrazu"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"edytować"</string> <string name="add" msgid="81036585205287996">"Dodaj"</string> <string name="manage_users" msgid="1823875311934643849">"Zarządzaj użytkownikami"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"To powiadomienie nie obsługuje dzielenia ekranu przez przeciąganie."</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index cd69f86b107c..09591cb82d8c 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -384,8 +384,8 @@ <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"A rede pode ser monitorada"</string> <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Este dispositivo está conectado à Internet usando VPNs"</string> <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Seus apps de trabalho estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Seus apps pessoais estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Este dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> + <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Apps pessoais conectados à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gerenciamento de dispositivos"</string> <string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string> @@ -404,7 +404,7 @@ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI."</string> <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Seu dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Seus apps de trabalho estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede em apps de trabalho, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI e o provedor de VPN."</string> - <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Seus apps pessoais estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o provedor de VPN."</string> + <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Seus apps pessoais estão conectados à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. As atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o provedor de VPN."</string> <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string> <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Abrir configurações de VPN"</string> <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerenciado pelo seu pai/mãe, que pode ver e gerenciar informações como os apps que você usa, sua localização e seu tempo de uso."</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index cd69f86b107c..09591cb82d8c 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -384,8 +384,8 @@ <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"A rede pode ser monitorada"</string> <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Este dispositivo está conectado à Internet usando VPNs"</string> <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Seus apps de trabalho estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Seus apps pessoais estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> - <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Este dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> + <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Apps pessoais conectados à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> + <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string> <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gerenciamento de dispositivos"</string> <string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string> @@ -404,7 +404,7 @@ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI."</string> <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Seu dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Seus apps de trabalho estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede em apps de trabalho, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI e o provedor de VPN."</string> - <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Seus apps pessoais estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o provedor de VPN."</string> + <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Seus apps pessoais estão conectados à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. As atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o provedor de VPN."</string> <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string> <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Abrir configurações de VPN"</string> <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerenciado pelo seu pai/mãe, que pode ver e gerenciar informações como os apps que você usa, sua localização e seu tempo de uso."</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 961798e67a3b..19a2bb9049e0 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -952,14 +952,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Textul a fost copiat"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Imaginea a fost copiată"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Conținutul a fost copiat"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor de clipboard"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Clipboard"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Previzualizarea imaginii"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"editați"</string> <string name="add" msgid="81036585205287996">"Adăugați"</string> <string name="manage_users" msgid="1823875311934643849">"Gestionați utilizatorii"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Notificarea nu acceptă tragerea pe ecranul împărțit."</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index d08835750526..bd907ef52165 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -959,14 +959,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Текст скопирован"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Изображение скопировано"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Данные скопированы"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Редактор буфера обмена"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Буфер обмена"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Предварительный просмотр изображения"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"изменить"</string> <string name="add" msgid="81036585205287996">"Добавить"</string> <string name="manage_users" msgid="1823875311934643849">"Управление пользователями"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Это уведомление нельзя перетаскивать между частями разделенного экрана."</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 7d9944f8538d..13795a3975e4 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"පෙළ පිටපත් කරන ලදී"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"රූපය පිටපත් කරන ලදි"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"අන්තර්ගතය පිටපත් කරන ලදි"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"පසුරු පුවරු සංස්කාරක"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"පසුරු පුවරුව"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"රූප පෙරදසුන"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"සංස්කරණය"</string> <string name="add" msgid="81036585205287996">"එක් කරන්න"</string> <string name="manage_users" msgid="1823875311934643849">"පරිශීලකයන් කළමනාකරණය කරන්න"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"මෙම දැනුම්දීම බෙදුම් තිරය වෙත ඇද ගෙන යාමට සහාය නොදක්වයි."</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index a6868d59a3da..8ec4eefb0169 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -959,14 +959,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Besedilo je kopirano"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Slika je kopirana"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Vsebina je kopirana"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Urejevalnik odložišča"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Odložišče"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Predogled slike"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"urejanje"</string> <string name="add" msgid="81036585205287996">"Dodaj"</string> <string name="manage_users" msgid="1823875311934643849">"Upravljanje uporabnikov"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"To obvestilo ne podpira vlečenja v razdeljen zaslon."</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 2834960efff6..c6a06bbe01e5 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"Telefoni"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Ndihma zanore"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"Portofoli"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Skaneri i kodeve QR"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"Shkyç"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"Pajisja është e kyçur"</string> @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"Shfaq modalitetin e demonstrimit"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"Eternet"</string> <string name="status_bar_alarm" msgid="87160847643623352">"Alarmi"</string> - <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> + <string name="wallet_title" msgid="5369767670735827105">"Portofoli"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Konfiguro për të kryer pagesa më të shpejta dhe më të sigurta përmes telefonit"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Shfaqi të gjitha"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Trokit për ta hapur"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Teksti u kopjua"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Imazhi u kopjua"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Përmbajtja u kopjua"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Modifikuesi i \"Kujtesës së fragmenteve\""</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Kujtesa e fragmenteve"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Pamja paraprake e imazhit"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"për të modifikuar"</string> <string name="add" msgid="81036585205287996">"Shto"</string> <string name="manage_users" msgid="1823875311934643849">"Menaxho përdoruesit"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Ky njoftim nuk mbështet zvarritjen në \"Ekranin e ndarë\"."</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index f0d7f840c7c5..50299de6051f 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -952,14 +952,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Текст је копиран"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Слика је копирана"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Садржај је копиран"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Уређивач привремене меморије"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Привремена меморија"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Преглед слике"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"измените"</string> <string name="add" msgid="81036585205287996">"Додај"</string> <string name="manage_users" msgid="1823875311934643849">"Управљаjте корисницима"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Ово обавештење не подржава превлачење на подељени екран."</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index c45b1e53e398..12bf290c9db2 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Texten har kopierats"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Bilden har kopierats"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Innehållet har kopierats"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Redigerare för urklipp"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Urklipp"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Bildförhandsgranskning"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"redigera"</string> <string name="add" msgid="81036585205287996">"Lägg till"</string> <string name="manage_users" msgid="1823875311934643849">"Hantera användare"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Det går inte att dra den här aviseringen till delad skärm."</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index c462c34e129e..25543fec8251 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Maandishi yamenakiliwa"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Picha imenakiliwa"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Maudhui yamenakiliwa"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Kihariri cha Ubao wa kunakili"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Ubao wa kunakili"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Onyesho la kukagua picha"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"ubadilishe"</string> <string name="add" msgid="81036585205287996">"Weka"</string> <string name="manage_users" msgid="1823875311934643849">"Dhibiti watumiaji"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Arifa hii hairuhusu kuburuta kwenye Skrini iliyogawanyika."</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 4423009beec0..f6cab3a8a62e 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"வார்த்தைகள் நகலெடுக்கப்பட்டன"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"படம் நகலெடுக்கப்பட்டது"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"உள்ளடக்கம் நகலெடுக்கப்பட்டது"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"கிளிப்போர்டு எடிட்டர்"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"கிளிப்போர்டு"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"படத்தின் மாதிரிக்காட்சி"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"திருத்தும்"</string> <string name="add" msgid="81036585205287996">"சேர்"</string> <string name="manage_users" msgid="1823875311934643849">"பயனர்களை நிர்வகித்தல்"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"பிரிக்கப்பட்ட திரைக்குள் இந்த அறிவிப்பை இழுத்துவிட முடியாது."</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index cfdddde650af..bb6d4e55895b 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"టెక్స్ట్ కాపీ చేయబడింది"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"ఇమేజ్ కాపీ చేయబడింది"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"కంటెంట్ కాపీ చేయబడింది"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"క్లిప్ బోర్డ్ ఎడిటర్"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"క్లిప్ బోర్డ్"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"ఇమేజ్ ప్రివ్యూ"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"ఎడిట్"</string> <string name="add" msgid="81036585205287996">"జోడించండి"</string> <string name="manage_users" msgid="1823875311934643849">"యూజర్లను మేనేజ్ చేయండి"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"ఈ నోటిఫికేషన్ స్ప్లిట్స్క్రీన్కు లాగడానికి సపోర్ట్ చేయదు."</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 385ee12d05aa..134d3ab6e02b 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"คัดลอกข้อความแล้ว"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"คัดลอกรูปภาพแล้ว"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"คัดลอกเนื้อหาแล้ว"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"เครื่องมือแก้ไขคลิปบอร์ด"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"คลิปบอร์ด"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"ตัวอย่างรูปภาพ"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"แก้ไข"</string> <string name="add" msgid="81036585205287996">"เพิ่ม"</string> <string name="manage_users" msgid="1823875311934643849">"จัดการผู้ใช้"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"การแจ้งเตือนนี้ไม่รองรับการลากเพื่อแบ่งหน้าจอ"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 6bf3d8fb7eec..6ed62f3e86ef 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Nakopya ang text"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Nakopya ang larawan"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Nakopya ang content"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Editor ng Clipboard"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Clipboard"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Preview ng larawan"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"i-edit"</string> <string name="add" msgid="81036585205287996">"Magdagdag"</string> <string name="manage_users" msgid="1823875311934643849">"Pamahalaan ang mga user"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Hindi sinusuportahan ng notification na ito ang pag-drag sa Splitscreen."</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 9d3c922787e4..e3182e00e921 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Metin kopyalandı"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Resim kopyalandı"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"İçerik kopyalandı"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Pano Düzenleyici"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Pano"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Resim önizleme"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"düzenleyin"</string> <string name="add" msgid="81036585205287996">"Ekle"</string> <string name="manage_users" msgid="1823875311934643849">"Kullanıcıları yönet"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildirim, bölünmüş ekrana sürüklenmeyi desteklemiyor."</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 6f365895e5a7..53b09091a5ce 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -959,14 +959,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Текст скопійовано"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Зображення скопійовано"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Вміст скопійовано"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Редактор буфера обміну"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Буфер обміну"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Попередній перегляд зображення"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"змінити"</string> <string name="add" msgid="81036585205287996">"Додати"</string> <string name="manage_users" msgid="1823875311934643849">"Керувати користувачами"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Це сповіщення не підтримує режим розділеного екрана."</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 90b7a2a8beda..81640392abd7 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"کیمرا"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"فون"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"صوتی معاون"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"والٹ"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR کوڈ اسکینر"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"غیر مقفل کریں"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"آلہ مقفل کر دیا گیا"</string> @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"ڈیمو موڈ دکھائیں"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"ایتھرنیٹ"</string> <string name="status_bar_alarm" msgid="87160847643623352">"الارم"</string> - <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> + <string name="wallet_title" msgid="5369767670735827105">"والٹ"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"اپنے فون سے تیز تر مزید محفوظ خریداریاں کرنے کے لیے، سیٹ اپ مکمل کریں"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"سبھی دکھائیں"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"کھولنے کیلئے تھپتھپائیں"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"متن کاپی ہو گیا"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"تصویر کاپی ہو گئی"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"مواد کاپی ہو گیا"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"کلپ بورڈ ایڈیٹر"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"کلپ بورڈ"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"تصویر کا پیش منظر"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"ترمیم کریں"</string> <string name="add" msgid="81036585205287996">"شامل کریں"</string> <string name="manage_users" msgid="1823875311934643849">"صارفین کا نظم کریں"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"یہ اطلاع اسپلٹ اسکرین کو گھسیٹنے کو سپورٹ نہیں کرتا ہے۔"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 78203139cb9e..b115cfd36778 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Matndan nuxsa olindi"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Rasmdan nusxa olindi"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Kontentdan nusxa olindi."</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Vaqtinchalik xotira muharriri"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Vaqtinchalik xotira"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Rasmga razm solish"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"tahrir"</string> <string name="add" msgid="81036585205287996">"Kiritish"</string> <string name="manage_users" msgid="1823875311934643849">"Foydalanuvchilarni boshqarish"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildirishnoma ikkiga ajratilgan ekranda ishlamaydi."</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 26f1ec06bd8d..976fa405e932 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"相机"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"电话"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"语音助理"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"电子钱包"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"钱包"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"二维码扫描器"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"解锁"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"设备已锁定"</string> @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"显示演示模式"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"以太网"</string> <string name="status_bar_alarm" msgid="87160847643623352">"闹钟"</string> - <string name="wallet_title" msgid="5369767670735827105">"电子钱包"</string> + <string name="wallet_title" msgid="5369767670735827105">"钱包"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"开始设置,享受更加快捷安全的手机购物体验"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"全部显示"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"点按即可打开"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"文本已复制"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"图片已复制"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"内容已复制"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"剪贴板编辑器"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"剪贴板"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"图片预览"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"修改"</string> <string name="add" msgid="81036585205287996">"添加"</string> <string name="manage_users" msgid="1823875311934643849">"管理用户"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"此通知不支持拖动到分屏中。"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index e1b340233a05..51670937d187 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"已複製文字"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"已複製圖片"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"已複製內容"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"剪貼簿編輯器"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"剪貼簿"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"圖像預覽"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"編輯"</string> <string name="add" msgid="81036585205287996">"新增"</string> <string name="manage_users" msgid="1823875311934643849">"管理使用者"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"此通知無法拖曳到分割螢幕中。"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 996cff4fe355..3d472196d67f 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -118,7 +118,7 @@ <string name="accessibility_camera_button" msgid="2938898391716647247">"相機"</string> <string name="accessibility_phone_button" msgid="4256353121703100427">"電話"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"語音小幫手"</string> - <string name="accessibility_wallet_button" msgid="1458258783460555507">"電子錢包"</string> + <string name="accessibility_wallet_button" msgid="1458258783460555507">"錢包"</string> <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"QR 圖碼掃描器"</string> <string name="accessibility_unlock_button" msgid="122785427241471085">"解除鎖定"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"裝置已鎖定"</string> @@ -462,7 +462,7 @@ <string name="show_demo_mode" msgid="3677956462273059726">"顯示示範模式"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"乙太網路"</string> <string name="status_bar_alarm" msgid="87160847643623352">"鬧鐘"</string> - <string name="wallet_title" msgid="5369767670735827105">"電子錢包"</string> + <string name="wallet_title" msgid="5369767670735827105">"錢包"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"完成相關設定之後,就能以更快速安全的方式透過手機消費"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"顯示全部"</string> <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"輕觸即可開啟"</string> @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"已複製文字"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"已複製圖片"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"已複製內容"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"剪貼簿編輯器"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"剪貼簿"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"圖片預覽"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"編輯"</string> <string name="add" msgid="81036585205287996">"新增"</string> <string name="manage_users" msgid="1823875311934643849">"管理使用者"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"這項通知無法拖曳到分割畫面中。"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 74508bf08f7e..3e83354faa5c 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -945,14 +945,10 @@ <string name="clipboard_text_copied" msgid="5100836834278976679">"Umbhalo ukopishiwe"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"Umfanekiso ukopishiwe"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"Okuqukethwe kukopishiwe"</string> - <!-- no translation found for clipboard_editor (2971197550401892843) --> - <skip /> - <!-- no translation found for clipboard_overlay_window_name (6450043652167357664) --> - <skip /> - <!-- no translation found for clipboard_image_preview (2156475174343538128) --> - <skip /> - <!-- no translation found for clipboard_edit (4500155216174011640) --> - <skip /> + <string name="clipboard_editor" msgid="2971197550401892843">"Umhleli Webhodi Lokunameka"</string> + <string name="clipboard_overlay_window_name" msgid="6450043652167357664">"Ibhodi lokunamathisela"</string> + <string name="clipboard_image_preview" msgid="2156475174343538128">"Ukubuka kuqala kwesithombe"</string> + <string name="clipboard_edit" msgid="4500155216174011640">"hlela"</string> <string name="add" msgid="81036585205287996">"Faka"</string> <string name="manage_users" msgid="1823875311934643849">"Phatha abasebenzisi"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Lesi saziso asikusekeli ukuhudulela ku-Splitscreen."</string> diff --git a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt index 8ab1ab79355f..34164f3b7306 100644 --- a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt +++ b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt @@ -87,20 +87,21 @@ open class DisplayCutoutBaseView : View, RegionInterceptableView { fun onDisplayChanged(displayId: Int) { val oldMode: Display.Mode? = displayMode - displayMode = display.mode + val display: Display? = context.display + displayMode = display?.mode - if (displayUniqueId != context.display?.uniqueId) { - displayUniqueId = context.display?.uniqueId + if (displayUniqueId != display?.uniqueId) { + displayUniqueId = display?.uniqueId shouldDrawCutout = DisplayCutout.getFillBuiltInDisplayCutout( context.resources, displayUniqueId) } // Skip if display mode or cutout hasn't changed. if (!displayModeChanged(oldMode, displayMode) && - display.cutout == displayInfo.displayCutout) { + display?.cutout == displayInfo.displayCutout) { return } - if (displayId == display.displayId) { + if (displayId == display?.displayId) { updateCutout() updateProtectionBoundingPath() onUpdate() diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index 233f3648aeb3..6da2f50aac27 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -406,6 +406,15 @@ public class AuthContainerView extends LinearLayout } @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + if (!hasWindowFocus) { + Log.v(TAG, "Lost window focus, dismissing the dialog"); + animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED); + } + } + + @Override public void onAttachedToWindow() { super.onAttachedToWindow(); @@ -720,7 +729,7 @@ public class AuthContainerView extends LinearLayout final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL, + WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL, windowFlags, PixelFormat.TRANSLUCENT); lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 6fa71640ca5a..6e2dcae4728e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -24,7 +24,10 @@ import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.graphics.Point; import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.display.DisplayManager; @@ -333,6 +336,20 @@ public class UdfpsController implements DozeReceiver { return velocity > 750f; } + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (mOverlay != null + && mOverlay.getRequestReason() != REASON_AUTH_KEYGUARD + && Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) { + Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received, mRequestReason: " + + mOverlay.getRequestReason()); + mOverlay.cancel(); + hideUdfpsOverlay(); + } + } + }; + /** * Forwards touches to the udfps controller / view */ @@ -634,6 +651,11 @@ public class UdfpsController implements DozeReceiver { final UdfpsOverlayController mUdfpsOverlayController = new UdfpsOverlayController(); mFingerprintManager.setUdfpsOverlayController(mUdfpsOverlayController); + final IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + context.registerReceiver(mBroadcastReceiver, filter, + Context.RECEIVER_EXPORTED_UNAUDITED); + udfpsHapticsSimulator.setUdfpsController(this); udfpsShell.setUdfpsOverlayController(mUdfpsOverlayController); } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java index 24dfeafa0dec..f0ce30d2dc66 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -107,6 +107,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { @Override void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) { super.onBind(device, topMargin, bottomMargin, position); + boolean isMutingExpectedDeviceExist = mController.hasMutingExpectedDevice(); final boolean currentlyConnected = !mIncludeDynamicGroup && isCurrentlyConnected(device); boolean isCurrentSeekbarInvisible = mSeekBar.getVisibility() == View.GONE; @@ -146,7 +147,19 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { } } else { // Set different layout for each device - if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) { + if (device.isMutingExpectedDevice() + && !mController.isCurrentConnectedDeviceRemote()) { + mTitleIcon.setImageDrawable( + mContext.getDrawable(R.drawable.media_output_icon_volume)); + mTitleIcon.setColorFilter(mController.getColorItemContent()); + mTitleText.setTextColor(mController.getColorItemContent()); + setSingleLineLayout(getItemTitle(device), true /* bFocused */, + false /* showSeekBar */, + false /* showProgressBar */, false /* showStatus */); + initMutingExpectedDevice(); + mCurrentActivePosition = position; + mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); + } else if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) { setUpDeviceIcon(device); mStatusIcon.setImageDrawable( mContext.getDrawable(R.drawable.media_output_status_failed)); @@ -193,17 +206,26 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { mEndTouchArea.setImportantForAccessibility( View.IMPORTANT_FOR_ACCESSIBILITY_YES); setUpContentDescriptionForView(mEndTouchArea, true, device); - } else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) { - mTitleIcon.setImageDrawable( - mContext.getDrawable(R.drawable.media_output_icon_volume)); - mTitleIcon.setColorFilter(mController.getColorItemContent()); - mTitleText.setTextColor(mController.getColorItemContent()); - setSingleLineLayout(getItemTitle(device), true /* bFocused */, - true /* showSeekBar */, - false /* showProgressBar */, false /* showStatus */); - initSeekbar(device, isCurrentSeekbarInvisible); - setUpContentDescriptionForView(mContainerLayout, false, device); - mCurrentActivePosition = position; + } else if (!mController.hasAdjustVolumeUserRestriction() + && currentlyConnected) { + if (isMutingExpectedDeviceExist + && !mController.isCurrentConnectedDeviceRemote()) { + // mark as disconnected and set special click listener + setUpDeviceIcon(device); + setSingleLineLayout(getItemTitle(device), false /* bFocused */); + mContainerLayout.setOnClickListener(v -> cancelMuteAwaitConnection()); + } else { + mTitleIcon.setImageDrawable( + mContext.getDrawable(R.drawable.media_output_icon_volume)); + mTitleIcon.setColorFilter(mController.getColorItemContent()); + mTitleText.setTextColor(mController.getColorItemContent()); + setSingleLineLayout(getItemTitle(device), true /* bFocused */, + true /* showSeekBar */, + false /* showProgressBar */, false /* showStatus */); + initSeekbar(device, isCurrentSeekbarInvisible); + setUpContentDescriptionForView(mContainerLayout, false, device); + mCurrentActivePosition = position; + } } else if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) { setUpDeviceIcon(device); mCheckBox.setOnCheckedChangeListener(null); @@ -269,6 +291,11 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { notifyDataSetChanged(); } + private void cancelMuteAwaitConnection() { + mController.cancelMuteAwaitConnection(); + notifyDataSetChanged(); + } + private void setUpContentDescriptionForView(View view, boolean clickable, MediaDevice device) { view.setClickable(clickable); diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java index b407e76f1b11..ccc0a3db0611 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -309,6 +309,17 @@ public abstract class MediaOutputBaseAdapter extends }); } + void initMutingExpectedDevice() { + disableSeekBar(); + final Drawable backgroundDrawable = mContext.getDrawable( + R.drawable.media_output_item_background_active) + .mutate(); + backgroundDrawable.setColorFilter( + new PorterDuffColorFilter(mController.getColorConnectedItemBackground(), + PorterDuff.Mode.SRC_IN)); + mItemLayout.setBackground(backgroundDrawable); + } + void initSessionSeekbar() { disableSeekBar(); mSeekBar.setMax(mController.getSessionVolumeMax()); diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt index 31266b6dc8ec..38005db28cf6 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt @@ -17,6 +17,7 @@ package com.android.systemui.media.dialog import android.content.Context +import android.media.AudioManager import android.media.session.MediaSessionManager import android.view.View import com.android.internal.logging.UiEventLogger @@ -41,7 +42,8 @@ class MediaOutputBroadcastDialogFactory @Inject constructor( private val notifCollection: CommonNotifCollection, private val uiEventLogger: UiEventLogger, private val dialogLaunchAnimator: DialogLaunchAnimator, - private val nearbyMediaDevicesManagerOptional: Optional<NearbyMediaDevicesManager> + private val nearbyMediaDevicesManagerOptional: Optional<NearbyMediaDevicesManager>, + private val audioManager: AudioManager ) { var mediaOutputBroadcastDialog: MediaOutputBroadcastDialog? = null @@ -52,7 +54,7 @@ class MediaOutputBroadcastDialogFactory @Inject constructor( val controller = MediaOutputController(context, packageName, mediaSessionManager, lbm, starter, notifCollection, - dialogLaunchAnimator, nearbyMediaDevicesManagerOptional) + dialogLaunchAnimator, nearbyMediaDevicesManagerOptional, audioManager) val dialog = MediaOutputBroadcastDialog(context, aboveStatusBar, broadcastSender, controller) mediaOutputBroadcastDialog = dialog diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index 9329b1bfc2a3..42e9af846322 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -34,6 +34,7 @@ import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; +import android.media.AudioManager; import android.media.INearbyMediaDevicesUpdateCallback; import android.media.MediaMetadata; import android.media.MediaRoute2Info; @@ -112,6 +113,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, @VisibleForTesting final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); final List<MediaDevice> mCachedMediaDevices = new CopyOnWriteArrayList<>(); + private final AudioManager mAudioManager; private final NearbyMediaDevicesManager mNearbyMediaDevicesManager; private final Map<String, Integer> mNearbyDeviceInfoMap = new ConcurrentHashMap<>(); @@ -122,7 +124,6 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, Callback mCallback; @VisibleForTesting LocalMediaManager mLocalMediaManager; - private MediaOutputMetricLogger mMetricLogger; private int mColorItemContent; @@ -145,13 +146,15 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, lbm, ActivityStarter starter, CommonNotifCollection notifCollection, DialogLaunchAnimator dialogLaunchAnimator, - Optional<NearbyMediaDevicesManager> nearbyMediaDevicesManagerOptional) { + Optional<NearbyMediaDevicesManager> nearbyMediaDevicesManagerOptional, + AudioManager audioManager) { mContext = context; mPackageName = packageName; mMediaSessionManager = mediaSessionManager; mLocalBluetoothManager = lbm; mActivityStarter = starter; mNotifCollection = notifCollection; + mAudioManager = audioManager; InfoMediaManager imm = new InfoMediaManager(mContext, packageName, null, lbm); mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName); mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName); @@ -217,14 +220,14 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, return false; } - void setRefreshing(boolean refreshing) { - mIsRefreshing = refreshing; - } - boolean isRefreshing() { return mIsRefreshing; } + void setRefreshing(boolean refreshing) { + mIsRefreshing = refreshing; + } + void stop() { if (mMediaController != null) { mMediaController.unregisterCallback(mCb); @@ -275,6 +278,27 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, mMetricLogger.logOutputFailure(new ArrayList<>(mMediaDevices), reason); } + /** + * Checks if there's any muting expected device exist + */ + public boolean hasMutingExpectedDevice() { + return mAudioManager.getMutingExpectedDevice() != null; + } + + /** + * Cancels mute await connection action in follow up request + */ + public void cancelMuteAwaitConnection() { + if (mAudioManager.getMutingExpectedDevice() == null) { + return; + } + try { + mAudioManager.cancelMuteAwaitConnection(mAudioManager.getMutingExpectedDevice()); + } catch (Exception e) { + Log.d(TAG, "Unable to cancel mute await connection"); + } + } + Drawable getAppSourceIcon() { if (mPackageName.isEmpty()) { return null; @@ -471,12 +495,26 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, // For the first time building list, to make sure the top device is the connected // device. if (mMediaDevices.isEmpty()) { - final MediaDevice connectedMediaDevice = getCurrentConnectedMediaDevice(); + boolean needToHandleMutingExpectedDevice = + hasMutingExpectedDevice() && !isCurrentConnectedDeviceRemote(); + final MediaDevice connectedMediaDevice = + needToHandleMutingExpectedDevice ? null + : getCurrentConnectedMediaDevice(); if (connectedMediaDevice == null) { if (DEBUG) { - Log.d(TAG, "No connected media device."); + Log.d(TAG, "No connected media device or muting expected device exist."); + } + if (needToHandleMutingExpectedDevice) { + for (MediaDevice device : devices) { + if (device.isMutingExpectedDevice()) { + mMediaDevices.add(0, device); + } else { + mMediaDevices.add(device); + } + } + } else { + mMediaDevices.addAll(devices); } - mMediaDevices.addAll(devices); return; } for (MediaDevice device : devices) { @@ -516,6 +554,12 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } + boolean isCurrentConnectedDeviceRemote() { + MediaDevice currentConnectedMediaDevice = getCurrentConnectedMediaDevice(); + return currentConnectedMediaDevice != null && isActiveRemoteDevice( + currentConnectedMediaDevice); + } + List<MediaDevice> getGroupMediaDevices() { final List<MediaDevice> selectedDevices = getSelectedMediaDevice(); final List<MediaDevice> selectableDevices = getSelectableMediaDevice(); @@ -731,7 +775,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, void launchMediaOutputBroadcastDialog(View mediaOutputDialog, BroadcastSender broadcastSender) { MediaOutputController controller = new MediaOutputController(mContext, mPackageName, mMediaSessionManager, mLocalBluetoothManager, mActivityStarter, - mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager)); + mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), + mAudioManager); MediaOutputBroadcastDialog dialog = new MediaOutputBroadcastDialog(mContext, true, broadcastSender, controller); mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog); @@ -887,8 +932,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } boolean isVolumeControlEnabled(@NonNull MediaDevice device) { - return isPlayBackInfoLocal() - || device.getDeviceType() != MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE; + return (isPlayBackInfoLocal() + || device.getDeviceType() != MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE) + && !device.isVolumeFixed(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt index 0d7d60ac5923..36a46f067fb0 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt @@ -17,6 +17,7 @@ package com.android.systemui.media.dialog import android.content.Context +import android.media.AudioManager import android.media.session.MediaSessionManager import android.view.View import com.android.internal.logging.UiEventLogger @@ -41,7 +42,8 @@ class MediaOutputDialogFactory @Inject constructor( private val notifCollection: CommonNotifCollection, private val uiEventLogger: UiEventLogger, private val dialogLaunchAnimator: DialogLaunchAnimator, - private val nearbyMediaDevicesManagerOptional: Optional<NearbyMediaDevicesManager> + private val nearbyMediaDevicesManagerOptional: Optional<NearbyMediaDevicesManager>, + private val audioManager: AudioManager ) { companion object { var mediaOutputDialog: MediaOutputDialog? = null @@ -54,7 +56,7 @@ class MediaOutputDialogFactory @Inject constructor( val controller = MediaOutputController(context, packageName, mediaSessionManager, lbm, starter, notifCollection, - dialogLaunchAnimator, nearbyMediaDevicesManagerOptional) + dialogLaunchAnimator, nearbyMediaDevicesManagerOptional, audioManager) val dialog = MediaOutputDialog(context, aboveStatusBar, broadcastSender, controller, uiEventLogger) mediaOutputDialog = dialog diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 9de132f64d0b..41724ef62683 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -151,15 +151,17 @@ public class QSPanel extends LinearLayout implements Tunable { mHorizontalContentContainer.setClipChildren(true); mHorizontalContentContainer.setClipToPadding(false); // Don't clip on the top, that way, secondary pages tiles can animate up + // Clipping coordinates should be relative to this view, not absolute (parent coordinates) mHorizontalContentContainer.addOnLayoutChangeListener( (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - if (left != oldLeft || right != oldRight || bottom != oldBottom) { - mClippingRect.left = left; - mClippingRect.right = right; - mClippingRect.bottom = bottom; + if ((right - left) != (oldRight - oldLeft) + || ((bottom - top) != (oldBottom - oldTop))) { + mClippingRect.right = right - left; + mClippingRect.bottom = bottom - top; mHorizontalContentContainer.setClipBounds(mClippingRect); } }); + mClippingRect.left = 0; mClippingRect.top = -1000; mHorizontalContentContainer.setClipBounds(mClippingRect); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 8ce422ac93f8..5b6e5ce95b14 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -83,6 +83,8 @@ import android.view.accessibility.AccessibilityManager; import android.widget.Toast; import android.window.WindowContext; +import androidx.concurrent.futures.CallbackToFutureAdapter; + import com.android.internal.app.ChooserActivity; import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.PhoneWindow; @@ -254,7 +256,7 @@ public class ScreenshotController { private final WindowManager mWindowManager; private final WindowManager.LayoutParams mWindowLayoutParams; private final AccessibilityManager mAccessibilityManager; - private final MediaPlayer mCameraSound; + private final ListenableFuture<MediaPlayer> mCameraSound; private final ScrollCaptureClient mScrollCaptureClient; private final PhoneWindow mWindow; private final DisplayManager mDisplayManager; @@ -338,13 +340,7 @@ public class ScreenshotController { reloadAssets(); // Setup the Camera shutter sound - mCameraSound = MediaPlayer.create(mContext, - Uri.fromFile(new File(mContext.getResources().getString( - com.android.internal.R.string.config_cameraShutterSound))), null, - new AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) - .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) - .build(), AudioSystem.newAudioSessionId()); + mCameraSound = loadCameraSound(); mCopyBroadcastReceiver = new BroadcastReceiver() { @Override @@ -442,16 +438,32 @@ public class ScreenshotController { return mScreenshotView.isPendingSharedTransition(); } + // Any cleanup needed when the service is being destroyed. + void onDestroy() { + removeWindow(); + releaseMediaPlayer(); + releaseContext(); + mBgExecutor.shutdownNow(); + } + /** * Release the constructed window context. */ - void releaseContext() { + private void releaseContext() { mContext.unregisterReceiver(mCopyBroadcastReceiver); mContext.release(); - if (mCameraSound != null) { - mCameraSound.release(); + } + + private void releaseMediaPlayer() { + // Note that this may block if the sound is still being loaded (very unlikely) but we can't + // reliably release in the background because the service is being destroyed. + try { + MediaPlayer player = mCameraSound.get(); + if (player != null) { + player.release(); + } + } catch (InterruptedException | ExecutionException e) { } - mBgExecutor.shutdownNow(); } /** @@ -822,15 +834,42 @@ public class ScreenshotController { } } + private ListenableFuture<MediaPlayer> loadCameraSound() { + // The media player creation is slow and needs on the background thread. + return CallbackToFutureAdapter.getFuture((completer) -> { + mBgExecutor.execute(() -> { + MediaPlayer player = MediaPlayer.create(mContext, + Uri.fromFile(new File(mContext.getResources().getString( + com.android.internal.R.string.config_cameraShutterSound))), null, + new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .build(), AudioSystem.newAudioSessionId()); + completer.set(player); + }); + return "ScreenshotController#loadCameraSound"; + }); + } + + private void playCameraSound() { + mCameraSound.addListener(() -> { + try { + MediaPlayer player = mCameraSound.get(); + if (player != null) { + player.start(); + } + } catch (InterruptedException | ExecutionException e) { + } + }, mBgExecutor); + } + /** * Save the bitmap but don't show the normal screenshot UI.. just a toast (or notification on * failure). */ private void saveScreenshotAndToast(Consumer<Uri> finisher) { // Play the shutter sound to notify that we've taken a screenshot - if (mCameraSound != null) { - mCameraSound.start(); - } + playCameraSound(); saveScreenshotInWorkerThread( /* onComplete */ finisher, @@ -864,9 +903,7 @@ public class ScreenshotController { mScreenshotView.createScreenshotDropInAnimation(screenRect, showFlash); // Play the shutter sound to notify that we've taken a screenshot - if (mCameraSound != null) { - mCameraSound.start(); - } + playCameraSound(); if (DEBUG_ANIM) { Log.d(TAG, "starting post-screenshot animation"); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index 90e7631b4b03..32d82037efb9 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -153,8 +153,7 @@ public class TakeScreenshotService extends Service { public void onDestroy() { super.onDestroy(); if (mScreenshot != null) { - mScreenshot.removeWindow(); - mScreenshot.releaseContext(); + mScreenshot.onDestroy(); mScreenshot = null; } if (DEBUG_SERVICE) { diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt index c7a8fa22d1af..5e908d9cd29f 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt @@ -46,6 +46,8 @@ interface UserTracker : UserContentResolverProvider, UserContextProvider { /** * List of profiles associated with the current user. + * + * Quiet work profiles will still appear here, but will have the `QUIET_MODE` flag. */ val userProfiles: List<UserInfo> diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt index 80d5f1681a79..47bed461e371 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt @@ -108,8 +108,12 @@ class UserTrackerImpl internal constructor( val filter = IntentFilter().apply { addAction(Intent.ACTION_USER_SWITCHED) + // These get called when a managed profile goes in or out of quiet mode. addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) + addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) + addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED) + addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED) } context.registerReceiverForAllUsers(this, filter, null /* permission */, backgroundHandler) @@ -121,7 +125,10 @@ class UserTrackerImpl internal constructor( Intent.ACTION_USER_SWITCHED -> { handleSwitchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL)) } - Intent.ACTION_MANAGED_PROFILE_AVAILABLE, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE -> { + Intent.ACTION_MANAGED_PROFILE_AVAILABLE, + Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE, + Intent.ACTION_MANAGED_PROFILE_REMOVED, + Intent.ACTION_MANAGED_PROFILE_UNLOCKED -> { handleProfilesChanged() } } @@ -208,7 +215,7 @@ class UserTrackerImpl internal constructor( pw.println("Initialized: $initialized") if (initialized) { pw.println("userId: $userId") - val ids = userProfiles.map { it.id } + val ids = userProfiles.map { it.toFullString() } pw.println("userProfiles: $ids") } val list = synchronized(callbacks) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index 4fc347a09292..aedbd1b56622 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -158,13 +158,6 @@ public final class NotificationEntry extends ListEntry { private long initializationTime = -1; /** - * Whether or not this row represents a system notification. Note that if this is - * {@code null}, that means we were either unable to retrieve the info or have yet to - * retrieve the info. - */ - public Boolean mIsSystemNotification; - - /** * Has the user sent a reply through this Notification. */ private boolean hasSentReply; @@ -777,12 +770,28 @@ public final class NotificationEntry extends ListEntry { if (mSbn.getNotification().isMediaNotification()) { return true; } - if (mIsSystemNotification != null && mIsSystemNotification) { + if (!isBlockable()) { return true; } return false; } + /** + * Returns whether this row is considered blockable (i.e. it's not a system notif + * or is not in an allowList). + */ + public boolean isBlockable() { + if (getChannel() == null) { + return false; + } + if (getChannel().isImportanceLockedByCriticalDeviceFunction() + && !getChannel().isBlockable()) { + return false; + } + + return true; + } + private boolean shouldSuppressVisualEffect(int effect) { if (isExemptFromDndVisualSuppression()) { return false; @@ -858,15 +867,6 @@ public final class NotificationEntry extends ListEntry { } /** - * Whether or not this row represents a system notification. Note that if this is - * {@code null}, that means we were either unable to retrieve the info or have yet to - * retrieve the info. - */ - public Boolean isSystemNotification() { - return mIsSystemNotification; - } - - /** * Set this notification to be sensitive. * * @param sensitive true if the content of this notification is sensitive right now diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/DebugModeFilterProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/DebugModeFilterProvider.kt index a0c39c6daab4..fd5bae151550 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/DebugModeFilterProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/DebugModeFilterProvider.kt @@ -16,15 +16,13 @@ package com.android.systemui.statusbar.notification.collection.provider -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter import android.os.Build import android.util.Log import com.android.systemui.Dumpable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager +import com.android.systemui.statusbar.commandline.Command +import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.util.Assert import com.android.systemui.util.ListenerSet @@ -39,20 +37,19 @@ import javax.inject.Inject * The only configuration is a list of allowed packages. When this list is empty, the feature is * disabled. When SystemUI starts up, this feature is disabled. * - * To enabled filtering, provide the list of packages in a comma-separated list using the command: + * To enabled filtering, provide the space-separated list of packages using the command: * - * `$ adb shell am broadcast -a com.android.systemui.action.SET_NOTIF_DEBUG_MODE - * --esal allowed_packages <comma-separated-packages>` + * `$ adb shell cmd statusbar notif-filter allowed-pkgs <package> ...` * - * To disable filtering, send the action without a list: + * To disable filtering, send the command without any packages, or explicitly reset: * - * `$ adb shell am broadcast -a com.android.systemui.action.SET_NOTIF_DEBUG_MODE` + * `$ adb shell cmd statusbar notif-filter reset` * * NOTE: this feature only works on debug builds, and when the broadcaster is root. */ @SysUISingleton class DebugModeFilterProvider @Inject constructor( - private val context: Context, + private val commandRegistry: CommandRegistry, dumpManager: DumpManager ) : Dumpable { private var allowedPackages: List<String> = emptyList() @@ -74,10 +71,8 @@ class DebugModeFilterProvider @Inject constructor( val needsInitialization = listeners.isEmpty() listeners.addIfAbsent(listener) if (needsInitialization) { - val filter = IntentFilter().apply { addAction(ACTION_SET_NOTIF_DEBUG_MODE) } - val permission = NOTIF_DEBUG_MODE_PERMISSION - context.registerReceiver(mReceiver, filter, permission, null, Context.RECEIVER_EXPORTED) - Log.d(TAG, "Registered: $mReceiver") + commandRegistry.registerCommand("notif-filter") { NotifFilterCommand() } + Log.d(TAG, "Registered notif-filter command") } } @@ -100,30 +95,49 @@ class DebugModeFilterProvider @Inject constructor( } } - private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent?) { - val action = intent?.action - if (ACTION_SET_NOTIF_DEBUG_MODE == action) { - // TODO(b/235268992) remove - Log.d(TAG, "ACTION_SET_NOTIF_DEBUG_MODE enter") - allowedPackages = intent.extras?.getStringArrayList(EXTRA_ALLOWED_PACKAGES) - ?: emptyList() - Log.d(TAG, "Updated allowedPackages: $allowedPackages") - listeners.forEach(Runnable::run) - // TODO(b/235268992) remove - Log.d(TAG, "ACTION_SET_NOTIF_DEBUG_MODE leave") + companion object { + private const val TAG = "DebugModeFilterProvider" + } + + inner class NotifFilterCommand : Command { + override fun execute(pw: PrintWriter, args: List<String>) { + when (args.firstOrNull()) { + "reset" -> { + if (args.size > 1) { + return invalidCommand(pw, "Unexpected arguments for 'reset' command") + } + allowedPackages = emptyList() + } + "allowed-pkgs" -> { + allowedPackages = args.drop(1) + } + null -> return invalidCommand(pw, "Missing command") + else -> return invalidCommand(pw, "Unknown command: ${args.firstOrNull()}") + } + Log.d(TAG, "Updated allowedPackages: $allowedPackages") + if (allowedPackages.isEmpty()) { + pw.print("Resetting allowedPackages ... ") } else { - Log.d(TAG, "Malformed intent: $intent") + pw.print("Updating allowedPackages: $allowedPackages ... ") } + listeners.forEach(Runnable::run) + pw.println("DONE") } - } - companion object { - private const val TAG = "DebugModeFilterProvider" - private const val ACTION_SET_NOTIF_DEBUG_MODE = - "com.android.systemui.action.SET_NOTIF_DEBUG_MODE" - private const val NOTIF_DEBUG_MODE_PERMISSION = - "com.android.systemui.permission.NOTIF_DEBUG_MODE" - private const val EXTRA_ALLOWED_PACKAGES = "allowed_packages" + private fun invalidCommand(pw: PrintWriter, reason: String) { + pw.println("Error: $reason") + pw.println() + help(pw) + } + + override fun help(pw: PrintWriter) { + pw.println("Usage: adb shell cmd statusbar notif-filter <command>") + pw.println("Available commands:") + pw.println(" reset") + pw.println(" Restore the default system behavior.") + pw.println(" allowed-pkgs <package> ...") + pw.println(" Hide all notification except from packages listed here.") + pw.println(" Providing no packages is treated as a reset.") + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 7c206eb8a54e..eb496abad460 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -513,16 +513,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView * or is in an allowList). */ public boolean getIsNonblockable() { - if (mEntry == null || mEntry.getChannel() == null) { - Log.w(TAG, "missing entry or channel"); + if (mEntry == null) { return true; } - if (mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction() - && !mEntry.getChannel().isBlockable()) { - return true; - } - - return false; + return !mEntry.isBlockable(); } private boolean isConversation() { @@ -1669,6 +1663,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } + @VisibleForTesting + protected void setEntry(NotificationEntry entry) { + mEntry = entry; + } + private final Runnable mExpireRecentlyAlertedFlag = () -> applyAudiblyAlertedRecently(false); private void applyAudiblyAlertedRecently(boolean audiblyAlertedRecently) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index ba1088fba6ed..557c995586df 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -958,14 +958,16 @@ public class NotificationPanelViewController extends PanelViewController { }); } - private void onFinishInflate() { + @VisibleForTesting + void onFinishInflate() { loadDimens(); mKeyguardStatusBar = mView.findViewById(R.id.keyguard_header); FrameLayout userAvatarContainer = null; KeyguardUserSwitcherView keyguardUserSwitcherView = null; - if (mKeyguardUserSwitcherEnabled && mUserManager.isUserSwitcherEnabled()) { + if (mKeyguardUserSwitcherEnabled && mUserManager.isUserSwitcherEnabled( + mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user))) { if (mKeyguardQsUserSwitchEnabled) { ViewStub stub = mView.findViewById(R.id.keyguard_qs_user_switch_stub); userAvatarContainer = (FrameLayout) stub.inflate(); @@ -1191,7 +1193,8 @@ public class NotificationPanelViewController extends PanelViewController { return view; } - private void reInflateViews() { + @VisibleForTesting + void reInflateViews() { if (DEBUG_LOGCAT) Log.d(TAG, "reInflateViews"); // Re-inflate the status view group. KeyguardStatusView keyguardStatusView = @@ -1212,7 +1215,8 @@ public class NotificationPanelViewController extends PanelViewController { // Re-inflate the keyguard user switcher group. updateUserSwitcherFlags(); - boolean isUserSwitcherEnabled = mUserManager.isUserSwitcherEnabled(); + boolean isUserSwitcherEnabled = mUserManager.isUserSwitcherEnabled( + mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)); boolean showQsUserSwitch = mKeyguardQsUserSwitchEnabled && isUserSwitcherEnabled; boolean showKeyguardUserSwitcher = !mKeyguardQsUserSwitchEnabled diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt index 1206d0540fd2..ebedbf987aa2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt @@ -200,6 +200,7 @@ class NotificationsQSContainerController @Inject constructor( containerPadding = bottomStableInsets } else { containerPadding = 0 + stackScrollMargin = bottomStableInsets + notificationsBottomMargin } } val qsContainerPadding = if (!(isQSCustomizing || isQSDetailShowing)) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt index 2341928b2565..52b5857a2106 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt @@ -106,6 +106,23 @@ class AuthContainerViewTest : SysuiTestCase() { } @Test + fun testDismissesOnFocusLoss() { + val container = initializeContainer() + waitForIdleSync() + + verify(callback).onDialogAnimatedIn() + + container.onWindowFocusChanged(false) + waitForIdleSync() + + verify(callback).onDismissed( + eq(AuthDialogCallback.DISMISSED_USER_CANCELED), + eq<ByteArray?>(null) /* credentialAttestation */ + ) + assertThat(container.parent).isNull() + } + + @Test fun testActionAuthenticated_sendsDismissedAuthenticated() { val container = initializeContainer() container.mBiometricCallback.onAction( diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java index 7c53388c81aa..e3b5059131fa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; +import android.media.AudioManager; import android.media.session.MediaController; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; @@ -84,6 +85,7 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock( NearbyMediaDevicesManager.class); private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); + private final AudioManager mAudioManager = mock(AudioManager.class); private List<MediaController> mMediaControllers = new ArrayList<>(); private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl; @@ -108,7 +110,7 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotificationEntryManager, mDialogLaunchAnimator, - Optional.of(mNearbyMediaDevicesManager)); + Optional.of(mNearbyMediaDevicesManager), mAudioManager); mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mBroadcastSender, mMediaOutputController); mMediaOutputBaseDialogImpl.onCreate(new Bundle()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java index d2dae745bcdc..feed3347f3e2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java @@ -31,6 +31,7 @@ import static org.mockito.Mockito.when; import android.app.Notification; import android.content.Context; import android.graphics.drawable.Icon; +import android.media.AudioManager; import android.media.MediaDescription; import android.media.MediaMetadata; import android.media.NearbyDevice; @@ -95,6 +96,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { private MediaMetadata mMediaMetadata = mock(MediaMetadata.class); private RoutingSessionInfo mRemoteSessionInfo = mock(RoutingSessionInfo.class); private ActivityStarter mStarter = mock(ActivityStarter.class); + private AudioManager mAudioManager = mock(AudioManager.class); private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class); private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock( @@ -123,7 +125,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME, mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, - Optional.of(mNearbyMediaDevicesManager)); + Optional.of(mNearbyMediaDevicesManager), mAudioManager); mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; MediaDescription.Builder builder = new MediaDescription.Builder(); @@ -175,7 +177,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaOutputController = new MediaOutputController(mSpyContext, null, mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, - Optional.of(mNearbyMediaDevicesManager)); + Optional.of(mNearbyMediaDevicesManager), mAudioManager); mMediaOutputController.start(mCb); @@ -204,7 +206,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaOutputController = new MediaOutputController(mSpyContext, null, mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, - Optional.of(mNearbyMediaDevicesManager)); + Optional.of(mNearbyMediaDevicesManager), mAudioManager); mMediaOutputController.start(mCb); @@ -509,7 +511,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaOutputController = new MediaOutputController(mSpyContext, null, mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, - Optional.of(mNearbyMediaDevicesManager)); + Optional.of(mNearbyMediaDevicesManager), mAudioManager); assertThat(mMediaOutputController.getNotificationIcon()).isNull(); } @@ -569,4 +571,24 @@ public class MediaOutputControllerTest extends SysuiTestCase { assertThat(mMediaOutputController.getNotificationIcon()).isNull(); } + + @Test + public void isVolumeControlEnabled_isCastWithVolumeFixed_returnsFalse() { + when(mMediaDevice1.getDeviceType()).thenReturn( + MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE); + + when(mMediaDevice1.isVolumeFixed()).thenReturn(true); + + assertThat(mMediaOutputController.isVolumeControlEnabled(mMediaDevice1)).isFalse(); + } + + @Test + public void isVolumeControlEnabled_isCastWithVolumeNotFixed_returnsTrue() { + when(mMediaDevice1.getDeviceType()).thenReturn( + MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE); + + when(mMediaDevice1.isVolumeFixed()).thenReturn(false); + + assertThat(mMediaOutputController.isVolumeControlEnabled(mMediaDevice1)).isTrue(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java index e6ad6edcec45..6786ad0116ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.media.AudioManager; import android.media.MediaRoute2Info; import android.media.session.MediaController; import android.media.session.MediaSessionManager; @@ -82,6 +83,7 @@ public class MediaOutputDialogTest extends SysuiTestCase { private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock( NearbyMediaDevicesManager.class); + private final AudioManager mAudioManager = mock(AudioManager.class); private List<MediaController> mMediaControllers = new ArrayList<>(); private MediaOutputDialog mMediaOutputDialog; @@ -101,7 +103,7 @@ public class MediaOutputDialogTest extends SysuiTestCase { mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotificationEntryManager, mDialogLaunchAnimator, - Optional.of(mNearbyMediaDevicesManager)); + Optional.of(mNearbyMediaDevicesManager), mAudioManager); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; mMediaOutputDialog = new MediaOutputDialog(mContext, false, mBroadcastSender, mMediaOutputController, mUiEventLogger); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java index 0cdde0775b2d..379bb4fd6336 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputGroupDialogTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.media.AudioManager; import android.media.session.MediaSessionManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -68,6 +69,7 @@ public class MediaOutputGroupDialogTest extends SysuiTestCase { private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock( NearbyMediaDevicesManager.class); + private final AudioManager mAudioManager = mock(AudioManager.class); private MediaOutputGroupDialog mMediaOutputGroupDialog; private MediaOutputController mMediaOutputController; @@ -78,7 +80,7 @@ public class MediaOutputGroupDialogTest extends SysuiTestCase { mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotificationEntryManager, mDialogLaunchAnimator, - Optional.of(mNearbyMediaDevicesManager)); + Optional.of(mNearbyMediaDevicesManager), mAudioManager); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; mMediaOutputGroupDialog = new MediaOutputGroupDialog(mContext, false, mBroadcastSender, mMediaOutputController); diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java index 63dca3bafc5b..0badd861787d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.java @@ -146,6 +146,20 @@ public class ColorSchemeTest extends SysuiTestCase { Assert.assertTrue(cam.getChroma() <= 8.0); } + @Test + @SuppressWarnings("ResultOfMethodCallIgnored") + public void testToString() { + new ColorScheme(Color.TRANSPARENT, false /* darkTheme */).toString(); + new ColorScheme(Color.argb(0, 0, 0, 0xf), false /* darkTheme */).toString(); + new ColorScheme(Color.argb(0xff, 0xff, 0, 0), false /* darkTheme */).toString(); + new ColorScheme(0xFFFFFFFF, false /* darkTheme */).toString(); + + new ColorScheme(Color.TRANSPARENT, true /* darkTheme */).toString(); + new ColorScheme(Color.argb(0, 0, 0, 0xf), true /* darkTheme */).toString(); + new ColorScheme(0xFFFF0000, true /* darkTheme */).toString(); + new ColorScheme(0xFFFFFFFF, true /* darkTheme */).toString(); + } + /** * Generate xml for SystemPaletteTest#testThemeStyles(). */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt index e237a5ce03fe..60cfd7249919 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt @@ -13,18 +13,24 @@ */ package com.android.systemui.qs +import android.graphics.Rect import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper +import android.testing.ViewUtils import android.view.View -import android.view.ViewGroup +import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.accessibility.AccessibilityNodeInfo import android.widget.FrameLayout import android.widget.LinearLayout import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.qs.QSTile +import com.android.systemui.qs.tileimpl.QSIconViewImpl +import com.android.systemui.qs.tileimpl.QSTileViewImpl import com.google.common.truth.Truth.assertThat +import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -36,37 +42,40 @@ import org.mockito.MockitoAnnotations @RunWithLooper @SmallTest class QSPanelTest : SysuiTestCase() { - private lateinit var mTestableLooper: TestableLooper - private lateinit var mQsPanel: QSPanel + private lateinit var testableLooper: TestableLooper + private lateinit var qsPanel: QSPanel - private lateinit var mParentView: ViewGroup - - private lateinit var mFooter: View + private lateinit var footer: View @Before @Throws(Exception::class) fun setup() { MockitoAnnotations.initMocks(this) - mTestableLooper = TestableLooper.get(this) + testableLooper = TestableLooper.get(this) + + testableLooper.runWithLooper { + qsPanel = QSPanel(context, null) + qsPanel.mUsingMediaPlayer = true - mTestableLooper.runWithLooper { - mQsPanel = QSPanel(mContext, null) - mQsPanel.initialize() + qsPanel.initialize() // QSPanel inflates a footer inside of it, mocking it here - mFooter = LinearLayout(mContext).apply { id = R.id.qs_footer } - mQsPanel.addView(mFooter) - mQsPanel.onFinishInflate() + footer = LinearLayout(context).apply { id = R.id.qs_footer } + qsPanel.addView(footer, MATCH_PARENT, 100) + qsPanel.onFinishInflate() // Provides a parent with non-zero size for QSPanel - mParentView = FrameLayout(mContext).apply { - addView(mQsPanel) - } + ViewUtils.attachView(qsPanel) } } + @After + fun tearDown() { + ViewUtils.detachView(qsPanel) + } + @Test fun testHasCollapseAccessibilityAction() { - val info = AccessibilityNodeInfo(mQsPanel) - mQsPanel.onInitializeAccessibilityNodeInfo(info) + val info = AccessibilityNodeInfo(qsPanel) + qsPanel.onInitializeAccessibilityNodeInfo(info) assertThat(info.actions and AccessibilityNodeInfo.ACTION_COLLAPSE).isNotEqualTo(0) assertThat(info.actions and AccessibilityNodeInfo.ACTION_EXPAND).isEqualTo(0) @@ -75,9 +84,79 @@ class QSPanelTest : SysuiTestCase() { @Test fun testCollapseActionCallsRunnable() { val mockRunnable = mock(Runnable::class.java) - mQsPanel.setCollapseExpandAction(mockRunnable) + qsPanel.setCollapseExpandAction(mockRunnable) - mQsPanel.performAccessibilityAction(AccessibilityNodeInfo.ACTION_COLLAPSE, null) + qsPanel.performAccessibilityAction(AccessibilityNodeInfo.ACTION_COLLAPSE, null) verify(mockRunnable).run() } + + @Test + fun testTilesFooterVisibleRTLLandscapeMedia() { + qsPanel.layoutDirection = View.LAYOUT_DIRECTION_RTL + // We need at least a tile so the layout has a height + qsPanel.tileLayout?.addTile( + QSPanelControllerBase.TileRecord( + mock(QSTile::class.java), + QSTileViewImpl(context, QSIconViewImpl(context)) + ) + ) + + val mediaView = FrameLayout(context) + mediaView.addView(View(context), MATCH_PARENT, 800) + + qsPanel.setUsingHorizontalLayout(/* horizontal */ true, mediaView, /* force */ true) + qsPanel.measure( + /* width */ View.MeasureSpec.makeMeasureSpec(3000, View.MeasureSpec.EXACTLY), + /* height */ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY) + ) + qsPanel.layout(0, 0, qsPanel.measuredWidth, qsPanel.measuredHeight) + + val tiles = qsPanel.tileLayout as View + // Tiles are effectively to the right of media + assertThat(mediaView isLeftOf tiles) + assertThat(tiles.isVisibleToUser).isTrue() + + assertThat(mediaView isLeftOf footer) + assertThat(footer.isVisibleToUser).isTrue() + } + + @Test + fun testTilesFooterVisibleLandscapeMedia() { + qsPanel.layoutDirection = View.LAYOUT_DIRECTION_LTR + // We need at least a tile so the layout has a height + qsPanel.tileLayout?.addTile( + QSPanelControllerBase.TileRecord( + mock(QSTile::class.java), + QSTileViewImpl(context, QSIconViewImpl(context)) + ) + ) + + val mediaView = FrameLayout(context) + mediaView.addView(View(context), MATCH_PARENT, 800) + + qsPanel.setUsingHorizontalLayout(/* horizontal */ true, mediaView, /* force */ true) + qsPanel.measure( + /* width */ View.MeasureSpec.makeMeasureSpec(3000, View.MeasureSpec.EXACTLY), + /* height */ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY) + ) + qsPanel.layout(0, 0, qsPanel.measuredWidth, qsPanel.measuredHeight) + + val tiles = qsPanel.tileLayout as View + // Tiles are effectively to the left of media + assertThat(tiles isLeftOf mediaView) + assertThat(tiles.isVisibleToUser).isTrue() + + assertThat(footer isLeftOf mediaView) + assertThat(footer.isVisibleToUser).isTrue() + } + + private infix fun View.isLeftOf(other: View): Boolean { + val rect = Rect() + getBoundsOnScreen(rect) + val thisRight = rect.right + + other.getBoundsOnScreen(rect) + + return thisRight <= rect.left + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt index f76b50a173c3..bd4b94eef2dd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt @@ -189,6 +189,67 @@ class UserTrackerImplTest : SysuiTestCase() { assertThat(tracker.userProfiles.map { it.id }).containsExactly(tracker.userId, profileID) } + fun testManagedProfileUnavailable() { + tracker.initialize(0) + val profileID = tracker.userId + 10 + + `when`(userManager.getProfiles(anyInt())).thenAnswer { invocation -> + val id = invocation.getArgument<Int>(0) + val info = UserInfo(id, "", UserInfo.FLAG_FULL) + val infoProfile = UserInfo( + id + 10, + "", + "", + UserInfo.FLAG_MANAGED_PROFILE or UserInfo.FLAG_QUIET_MODE, + UserManager.USER_TYPE_PROFILE_MANAGED + ) + infoProfile.profileGroupId = id + listOf(info, infoProfile) + } + + val intent = Intent(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) + .putExtra(Intent.EXTRA_USER, UserHandle.of(profileID)) + tracker.onReceive(context, intent) + + assertThat(tracker.userProfiles.map { it.id }).containsExactly(tracker.userId, profileID) + } + + fun testManagedProfileStartedAndRemoved() { + tracker.initialize(0) + val profileID = tracker.userId + 10 + + `when`(userManager.getProfiles(anyInt())).thenAnswer { invocation -> + val id = invocation.getArgument<Int>(0) + val info = UserInfo(id, "", UserInfo.FLAG_FULL) + val infoProfile = UserInfo( + id + 10, + "", + "", + UserInfo.FLAG_MANAGED_PROFILE, + UserManager.USER_TYPE_PROFILE_MANAGED + ) + infoProfile.profileGroupId = id + listOf(info, infoProfile) + } + + // Managed profile started + val intent = Intent(Intent.ACTION_MANAGED_PROFILE_UNLOCKED) + .putExtra(Intent.EXTRA_USER, UserHandle.of(profileID)) + tracker.onReceive(context, intent) + + assertThat(tracker.userProfiles.map { it.id }).containsExactly(tracker.userId, profileID) + + `when`(userManager.getProfiles(anyInt())).thenAnswer { invocation -> + listOf(UserInfo(invocation.getArgument(0), "", UserInfo.FLAG_FULL)) + } + + val intent2 = Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED) + .putExtra(Intent.EXTRA_USER, UserHandle.of(profileID)) + tracker.onReceive(context, intent2) + + assertThat(tracker.userProfiles.map { it.id }).containsExactly(tracker.userId) + } + @Test fun testCallbackNotCalledOnAdd() { tracker.initialize(0) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java index 5804ad425267..769143ddbc0d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java @@ -29,6 +29,7 @@ import static com.android.systemui.statusbar.NotificationEntryHelper.modifySbn; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import android.app.ActivityManager; @@ -57,6 +58,7 @@ import com.android.systemui.util.time.FakeSystemClock; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import java.util.ArrayList; @@ -72,6 +74,7 @@ public class NotificationEntryTest extends SysuiTestCase { private int mId; private NotificationEntry mEntry; + private NotificationChannel mChannel = Mockito.mock(NotificationChannel.class); private final FakeSystemClock mClock = new FakeSystemClock(); @Before @@ -85,10 +88,13 @@ public class NotificationEntryTest extends SysuiTestCase { .setPkg(TEST_PACKAGE_NAME) .setOpPkg(TEST_PACKAGE_NAME) .setUid(TEST_UID) + .setChannel(mChannel) .setId(mId++) .setNotification(n.build()) .setUser(new UserHandle(ActivityManager.getCurrentUser())) .build(); + + doReturn(false).when(mChannel).isBlockable(); } @Test @@ -100,6 +106,44 @@ public class NotificationEntryTest extends SysuiTestCase { } @Test + public void testBlockableEntryWhenCritical() { + doReturn(true).when(mChannel).isBlockable(); + + assertTrue(mEntry.isBlockable()); + } + + + @Test + public void testBlockableEntryWhenCriticalAndChannelNotBlockable() { + doReturn(true).when(mChannel).isBlockable(); + doReturn(true).when(mChannel).isImportanceLockedByCriticalDeviceFunction(); + + assertTrue(mEntry.isBlockable()); + } + + @Test + public void testNonBlockableEntryWhenCriticalAndChannelNotBlockable() { + doReturn(false).when(mChannel).isBlockable(); + doReturn(true).when(mChannel).isImportanceLockedByCriticalDeviceFunction(); + + assertFalse(mEntry.isBlockable()); + } + + @Test + public void testBlockableWhenEntryHasNoChannel() { + StatusBarNotification sbn = new SbnBuilder().build(); + Ranking ranking = new RankingBuilder() + .setChannel(null) + .setKey(sbn.getKey()) + .build(); + + NotificationEntry entry = + new NotificationEntry(sbn, ranking, mClock.uptimeMillis()); + + assertFalse(entry.isBlockable()); + } + + @Test public void testIsExemptFromDndVisualSuppression_media() { Notification.Builder n = new Notification.Builder(mContext, "") .setStyle(new Notification.MediaStyle() @@ -117,7 +161,8 @@ public class NotificationEntryTest extends SysuiTestCase { @Test public void testIsExemptFromDndVisualSuppression_system() { - mEntry.mIsSystemNotification = true; + doReturn(true).when(mChannel).isImportanceLockedByCriticalDeviceFunction(); + doReturn(false).when(mChannel).isBlockable(); assertTrue(mEntry.isExemptFromDndVisualSuppression()); assertFalse(mEntry.shouldSuppressAmbient()); @@ -128,7 +173,7 @@ public class NotificationEntryTest extends SysuiTestCase { NotificationEntry entry = new NotificationEntryBuilder() .setUid(UID_NORMAL) .build(); - entry.mIsSystemNotification = true; + doReturn(true).when(mChannel).isImportanceLockedByCriticalDeviceFunction(); modifyRanking(entry).setSuppressedVisualEffects(SUPPRESSED_EFFECT_AMBIENT).build(); modifySbn(entry) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java index f4d8405a796e..15c1cb7b123a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.notification.collection.coordinator; +import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST; @@ -30,6 +31,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.testing.AndroidTestingRunner; @@ -185,7 +187,7 @@ public class RankingCoordinatorTest extends SysuiTestCase { // WHEN it's not dozing (showing the notification list) when(mStatusBarStateController.isDozing()).thenReturn(false); - + // THEN filter out the notification assertTrue(mCapturedDozingFilter.shouldFilterOut(mEntry, 0)); } @@ -277,6 +279,7 @@ public class RankingCoordinatorTest extends SysuiTestCase { private RankingBuilder getRankingForUnfilteredNotif() { return new RankingBuilder(mEntry.getRanking()) + .setChannel(new NotificationChannel("id", null, IMPORTANCE_DEFAULT)) .setSuppressedVisualEffects(0) .setSuspended(false); } @@ -292,7 +295,7 @@ public class RankingCoordinatorTest extends SysuiTestCase { mEntry.setRanking(new RankingBuilder(mEntry.getRanking()) .setImportance(ambient ? NotificationManager.IMPORTANCE_MIN - : NotificationManager.IMPORTANCE_DEFAULT) + : IMPORTANCE_DEFAULT) .build()); assertEquals(ambient, mEntry.getRanking().isAmbient()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java index 8a2dc263cf36..90627cb0fa78 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java @@ -36,6 +36,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Notification; +import android.app.NotificationChannel; import android.app.PendingIntent; import android.content.Intent; import android.graphics.drawable.Icon; @@ -529,6 +530,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .setPkg("a") .setOpPkg("a") .setTag("a") + .setChannel(new NotificationChannel("a", null, importance)) .setNotification(n) .setImportance(importance) .build(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java index c36737c6724e..b1bf971c52fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java @@ -58,6 +58,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.AboveShelfChangedListener; import com.android.systemui.statusbar.notification.FeedbackIcon; import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer; import org.junit.Assert; @@ -65,6 +66,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -412,27 +414,15 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { public void testGetIsNonblockable() throws Exception { ExpandableNotificationRow row = mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification()); - - assertFalse(row.getIsNonblockable()); - } - - @Test - public void testGetIsNonblockable_criticalDeviceFunction() throws Exception { - ExpandableNotificationRow row = - mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification()); - row.getEntry().getChannel().setImportanceLockedByCriticalDeviceFunction(true); - row.getEntry().getChannel().setBlockable(false); + row.setEntry(null); assertTrue(row.getIsNonblockable()); - } - @Test - public void testGetIsNonblockable_criticalDeviceFunction_butBlockable() throws Exception { - ExpandableNotificationRow row = - mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification()); - row.getEntry().getChannel().setImportanceLockedByCriticalDeviceFunction(true); - row.getEntry().getChannel().setBlockable(true); + NotificationEntry entry = mock(NotificationEntry.class); + Mockito.doReturn(false, true).when(entry).isBlockable(); + row.setEntry(entry); + assertTrue(row.getIsNonblockable()); assertFalse(row.getIsNonblockable()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index 16f934b5af59..2faff0ced70a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -39,6 +39,7 @@ import static org.mockito.Mockito.when; import android.app.IWallpaperManager; import android.app.Notification; +import android.app.NotificationChannel; import android.app.WallpaperManager; import android.app.trust.TrustManager; import android.content.BroadcastReceiver; @@ -718,6 +719,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { .setPkg("a") .setOpPkg("a") .setTag("a") + .setChannel(new NotificationChannel("id", null, IMPORTANCE_HIGH)) .setNotification(n) .setImportance(IMPORTANCE_HIGH) .setSuppressedVisualEffects(SUPPRESSED_EFFECT_PEEK) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java index 018c4531b382..d47644f047a2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java @@ -889,7 +889,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { updateSmallestScreenWidth(300); when(mResources.getBoolean( com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); - when(mUserManager.isUserSwitcherEnabled()).thenReturn(true); + when(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)).thenReturn(false); + when(mUserManager.isUserSwitcherEnabled(false)).thenReturn(true); updateSmallestScreenWidth(800); @@ -897,6 +898,34 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { } @Test + public void testFinishInflate_userSwitcherDisabled_doNotInflateUserSwitchView() { + givenViewAttached(); + when(mResources.getBoolean( + com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); + when(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)).thenReturn(false); + when(mUserManager.isUserSwitcherEnabled(false /* showEvenIfNotActionable */)) + .thenReturn(false); + + mNotificationPanelViewController.onFinishInflate(); + + verify(mUserSwitcherStubView, never()).inflate(); + } + + @Test + public void testReInflateViews_userSwitcherDisabled_doNotInflateUserSwitchView() { + givenViewAttached(); + when(mResources.getBoolean( + com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); + when(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)).thenReturn(false); + when(mUserManager.isUserSwitcherEnabled(false /* showEvenIfNotActionable */)) + .thenReturn(false); + + mNotificationPanelViewController.reInflateViews(); + + verify(mUserSwitcherStubView, never()).inflate(); + } + + @Test public void testCanCollapsePanelOnTouch_trueForKeyGuard() { mStatusBarStateController.setState(KEYGUARD); @@ -1298,7 +1327,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { } private void updateMultiUserSetting(boolean enabled) { - when(mUserManager.isUserSwitcherEnabled()).thenReturn(enabled); + when(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)).thenReturn(false); + when(mUserManager.isUserSwitcherEnabled(false)).thenReturn(enabled); final ArgumentCaptor<ContentObserver> observerCaptor = ArgumentCaptor.forClass(ContentObserver.class); verify(mContentResolver) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt index 003245298fa9..de40b7fd0a13 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt @@ -206,7 +206,9 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { given(taskbarVisible = false, navigationMode = BUTTONS_NAVIGATION, insets = windowInsets().withStableBottom()) - then(expectedContainerPadding = 0, expectedQsPadding = STABLE_INSET_BOTTOM) + then(expectedContainerPadding = 0, + expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN, + expectedQsPadding = STABLE_INSET_BOTTOM) } @Test diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java index c6e595b1d785..01cee33fd81a 100644 --- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java +++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java @@ -174,7 +174,7 @@ public final class PresentationStatsEventLogger { public void logAndEndEvent() { if (!mEventInternal.isPresent()) { - Slog.wtf(null, "Shouldn't be logging AutofillPresentationEventReported again for same " + Slog.w(TAG, "Shouldn't be logging AutofillPresentationEventReported again for same " + "event"); return; } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index a4eaef98235d..8368b4dfe070 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -63,6 +63,12 @@ import static android.os.Process.SYSTEM_UID; import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY; import static com.android.internal.messages.nano.SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICE_BG_LAUNCH; +import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED; +import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD; +import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_HOT; +import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM; +import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__BIND; +import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__START; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; @@ -522,8 +528,9 @@ public final class ActiveServices { + " delayedStop=" + r.delayedStop); } else { try { - startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, - true); + final ServiceRecord.StartItem si = r.pendingStarts.get(0); + startServiceInnerLocked(this, si.intent, r, false, true, si.callingId, + r.startRequested); } catch (TransactionTooLargeException e) { // Ignore, nobody upstack cares. } @@ -865,6 +872,7 @@ public final class ActiveServices { if (unscheduleServiceRestartLocked(r, callingUid, false)) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r); } + final boolean wasStartRequested = r.startRequested; r.lastActivity = SystemClock.uptimeMillis(); r.startRequested = true; r.delayedStop = false; @@ -954,7 +962,8 @@ public final class ActiveServices { if (allowBackgroundActivityStarts) { r.allowBgActivityStartsOnServiceStart(backgroundActivityStartsToken); } - ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); + ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting, + callingUid, wasStartRequested); return cmp; } @@ -1150,7 +1159,8 @@ public final class ActiveServices { } ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, - boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { + boolean callerFg, boolean addToStarting, int callingUid, boolean wasStartRequested) + throws TransactionTooLargeException { synchronized (mAm.mProcessStats.mLock) { final ServiceState stracker = r.getTracker(); if (stracker != null) { @@ -1177,6 +1187,15 @@ public final class ActiveServices { return new ComponentName("!!", error); } + FrameworkStatsLog.write(SERVICE_REQUEST_EVENT_REPORTED, uid, callingUid, + ActivityManagerService.getShortAction(service.getAction()), + SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__START, false, + r.app == null || r.app.getThread() == null + ? SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD + : (wasStartRequested || !r.getConnections().isEmpty() + ? SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_HOT + : SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM)); + if (r.startRequested && addToStarting) { boolean first = smap.mStartingBackground.size() == 0; smap.mStartingBackground.add(r); @@ -2876,6 +2895,8 @@ public final class ActiveServices { mAm.requireAllowedAssociationsLocked(s.appInfo.packageName); } + final boolean wasStartRequested = s.startRequested; + final boolean hadConnections = !s.getConnections().isEmpty(); mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.mState.getCurProcState(), s.appInfo.uid, s.appInfo.longVersionCode, s.instanceName, s.processName); @@ -2962,6 +2983,15 @@ public final class ActiveServices { mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE); } + FrameworkStatsLog.write(SERVICE_REQUEST_EVENT_REPORTED, s.appInfo.uid, callingUid, + ActivityManagerService.getShortAction(service.getAction()), + SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__BIND, false, + s.app == null || s.app.getThread() == null + ? SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD + : (wasStartRequested || hadConnections + ? SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_HOT + : SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM)); + if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b + ": received=" + b.intent.received + " apps=" + b.intent.apps.size() @@ -6917,7 +6947,8 @@ public final class ActiveServices { durationMs, r.mStartForegroundCount, ActivityManagerUtils.hashComponentNameForAtom(r.shortInstanceName), - r.mFgsHasNotificationPermission); + r.mFgsHasNotificationPermission, + r.foregroundServiceType); int event = 0; if (state == FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 71a28487a763..a78c64b6538d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5003,15 +5003,7 @@ public class ActivityManagerService extends IActivityManager.Stub final HostingRecord hostingRecord = app.getHostingRecord(); - final String action = hostingRecord.getAction(); - String shortAction = action; - if (action != null) { - // only log the last part of the action string to save stats data. - int index = action.lastIndexOf("."); - if (index != -1 && index != action.length() - 1) { - shortAction = action.substring(index + 1); - } - } + String shortAction = getShortAction(hostingRecord.getAction()); FrameworkStatsLog.write( FrameworkStatsLog.PROCESS_START_TIME, app.info.uid, @@ -5042,6 +5034,20 @@ public class ActivityManagerService extends IActivityManager.Stub } } + /** + * @return The last part of the string of an intent's action. + */ + static @Nullable String getShortAction(@Nullable String action) { + String shortAction = action; + if (action != null) { + int index = action.lastIndexOf('.'); + if (index != -1 && index != action.length() - 1) { + shortAction = action.substring(index + 1); + } + } + return shortAction; + } + void checkTime(long startTime, String where) { long now = SystemClock.uptimeMillis(); if ((now - startTime) > 50) { @@ -14262,7 +14268,7 @@ public class ActivityManagerService extends IActivityManager.Stub oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo, oldRecord.intent, Activity.RESULT_CANCELED, null, null, - false, false, oldRecord.userId); + false, false, oldRecord.userId, oldRecord.callingUid, callingUid); } catch (RemoteException e) { Slog.w(TAG, "Failure [" + queue.mQueueName + "] sending broadcast result of " diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index f7aa7c155719..43d0de9855fe 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -24,6 +24,11 @@ import static android.text.TextUtils.formatSimple; import static com.android.internal.util.FrameworkStatsLog.BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED; import static com.android.internal.util.FrameworkStatsLog.BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__BOOT_COMPLETED; import static com.android.internal.util.FrameworkStatsLog.BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED__EVENT__LOCKED_BOOT_COMPLETED; +import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED; +import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD; +import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM; +import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST; +import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__RUNTIME; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_DEFERRAL; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT; @@ -316,7 +321,7 @@ public final class BroadcastQueue { } private final void processCurBroadcastLocked(BroadcastRecord r, - ProcessRecord app) throws RemoteException { + ProcessRecord app, int receiverType, int processTemperature) throws RemoteException { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Process cur broadcast " + r + " for app " + app); final IApplicationThread thread = app.getThread(); @@ -362,6 +367,10 @@ public final class BroadcastQueue { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Process cur broadcast " + r + " DELIVERED for app " + app); started = true; + FrameworkStatsLog.write(BROADCAST_DELIVERY_EVENT_REPORTED, app.uid, + r.callingUid == -1 ? Process.SYSTEM_UID : r.callingUid, + ActivityManagerService.getShortAction(r.intent.getAction()), + receiverType, processTemperature); } finally { if (!started) { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, @@ -398,7 +407,9 @@ public final class BroadcastQueue { } try { mPendingBroadcast = null; - processCurBroadcastLocked(br, app); + processCurBroadcastLocked(br, app, + BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST, + BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD); didSomething = true; } catch (Exception e) { Slog.w(TAG, "Exception in new application when starting receiver " @@ -628,8 +639,8 @@ public final class BroadcastQueue { void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, Intent intent, int resultCode, String data, Bundle extras, - boolean ordered, boolean sticky, int sendingUser) - throws RemoteException { + boolean ordered, boolean sticky, int sendingUser, + int receiverUid, int callingUid) throws RemoteException { // Send the intent to the receiver asynchronously using one-way binder calls. if (app != null) { final IApplicationThread thread = app.getThread(); @@ -663,6 +674,12 @@ public final class BroadcastQueue { receiver.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser); } + FrameworkStatsLog.write(BROADCAST_DELIVERY_EVENT_REPORTED, + receiverUid == -1 ? Process.SYSTEM_UID : receiverUid, + callingUid == -1 ? Process.SYSTEM_UID : callingUid, + ActivityManagerService.getShortAction(intent.getAction()), + BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__RUNTIME, + BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM); } private void deliverToRegisteredReceiverLocked(BroadcastRecord r, @@ -965,7 +982,8 @@ public final class BroadcastQueue { maybeReportBroadcastDispatchedEventLocked(r, filter.owningUid); performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, new Intent(r.intent), r.resultCode, r.resultData, - r.resultExtras, r.ordered, r.initialSticky, r.userId); + r.resultExtras, r.ordered, r.initialSticky, r.userId, + filter.receiverList.uid, r.callingUid); // parallel broadcasts are fire-and-forget, not bookended by a call to // finishReceiverLocked(), so we manage their activity-start token here if (filter.receiverList.app != null @@ -1317,7 +1335,8 @@ public final class BroadcastQueue { } performReceiveLocked(r.callerApp, r.resultTo, new Intent(r.intent), r.resultCode, - r.resultData, r.resultExtras, false, false, r.userId); + r.resultData, r.resultExtras, false, false, r.userId, + r.callingUid, r.callingUid); logBootCompletedBroadcastCompletionLatencyIfPossible(r); // Set this to null so that the reference // (local and remote) isn't kept in the mBroadcastHistory. @@ -1837,7 +1856,9 @@ public final class BroadcastQueue { app.addPackage(info.activityInfo.packageName, info.activityInfo.applicationInfo.longVersionCode, mService.mProcessStats); maybeAddAllowBackgroundActivityStartsToken(app, r); - processCurBroadcastLocked(r, app); + processCurBroadcastLocked(r, app, + BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST, + BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when sending broadcast to " diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java index d4f4245f19c5..eb8387fe85e5 100644 --- a/services/core/java/com/android/server/audio/RotationHelper.java +++ b/services/core/java/com/android/server/audio/RotationHelper.java @@ -20,12 +20,13 @@ import android.content.Context; import android.hardware.devicestate.DeviceStateManager; import android.hardware.devicestate.DeviceStateManager.FoldStateListener; import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManagerGlobal; import android.media.AudioSystem; import android.os.Handler; import android.os.HandlerExecutor; import android.util.Log; +import android.view.Display; import android.view.Surface; -import android.view.WindowManager; /** * Class to handle device rotation events for AudioService, and forward device rotation @@ -48,6 +49,8 @@ class RotationHelper { private static final String TAG = "AudioService.RotationHelper"; + private static final boolean DEBUG_ROTATION = false; + private static AudioDisplayListener sDisplayListener; private static FoldStateListener sFoldStateListener; @@ -98,8 +101,8 @@ class RotationHelper { // Even though we're responding to device orientation events, // use display rotation so audio stays in sync with video/dialogs // TODO(b/148458001): Support multi-display - int newRotation = ((WindowManager) sContext.getSystemService( - Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation(); + int newRotation = DisplayManagerGlobal.getInstance() + .getDisplayInfo(Display.DEFAULT_DISPLAY).rotation; synchronized(sRotationLock) { if (newRotation != sDeviceRotation) { sDeviceRotation = newRotation; @@ -109,7 +112,9 @@ class RotationHelper { } private static void publishRotation(int rotation) { - Log.v(TAG, "publishing device rotation =" + rotation + " (x90deg)"); + if (DEBUG_ROTATION) { + Log.i(TAG, "publishing device rotation =" + rotation + " (x90deg)"); + } switch (rotation) { case Surface.ROTATION_0: AudioSystem.setParameters("rotation=0"); @@ -159,6 +164,9 @@ class RotationHelper { @Override public void onDisplayChanged(int displayId) { + if (DEBUG_ROTATION) { + Log.i(TAG, "onDisplayChanged diplayId:" + displayId); + } updateOrientation(); } } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 6285ef1fdabd..d3e2966c6df0 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -485,7 +485,7 @@ public final class DisplayManagerService extends SystemService { mUiHandler = UiThread.getHandler(); mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore); mLogicalDisplayMapper = new LogicalDisplayMapper(mContext, mDisplayDeviceRepo, - new LogicalDisplayListener(), mSyncRoot, mHandler); + new LogicalDisplayListener(), mSyncRoot, mHandler, new DeviceStateToLayoutMap()); mDisplayModeDirector = new DisplayModeDirector(context, mHandler); mBrightnessSynchronizer = new BrightnessSynchronizer(mContext); Resources resources = mContext.getResources(); @@ -945,7 +945,8 @@ public final class DisplayManagerService extends SystemService { private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) { synchronized (mSyncRoot) { - final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); + final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId, + /* includeDisabledDisplays= */ true); if (display != null) { final DisplayInfo info = getDisplayInfoForFrameRateOverride(display.getFrameRateOverrides(), @@ -2128,16 +2129,18 @@ public final class DisplayManagerService extends SystemService { } void resetBrightnessConfigurations() { - mPersistentDataStore.setBrightnessConfigurationForUser(null, mContext.getUserId(), - mContext.getPackageName()); - mLogicalDisplayMapper.forEachLocked((logicalDisplay -> { - if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { - return; - } - final String uniqueId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); - setBrightnessConfigurationForDisplayInternal(null, uniqueId, mContext.getUserId(), + synchronized (mSyncRoot) { + mPersistentDataStore.setBrightnessConfigurationForUser(null, mContext.getUserId(), mContext.getPackageName()); - })); + mLogicalDisplayMapper.forEachLocked((logicalDisplay -> { + if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { + return; + } + String uniqueId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); + setBrightnessConfigurationForDisplayInternal(null, uniqueId, mContext.getUserId(), + mContext.getPackageName()); + })); + } } void setAutoBrightnessLoggingEnabled(boolean enabled) { @@ -2814,15 +2817,16 @@ public final class DisplayManagerService extends SystemService { } /** - * Returns the list of all display ids. + * Returns the list of all enabled display ids, and disabled ones if specified. */ @Override // Binder call - public int[] getDisplayIds() { + public int[] getDisplayIds(boolean includeDisabledDisplays) { final int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { synchronized (mSyncRoot) { - return mLogicalDisplayMapper.getDisplayIdsLocked(callingUid); + return mLogicalDisplayMapper.getDisplayIdsLocked(callingUid, + includeDisabledDisplays); } } finally { Binder.restoreCallingIdentity(token); diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 70c9e23c6af8..34e8e75314ce 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -79,8 +79,12 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private static final int MSG_TRANSITION_TO_PENDING_DEVICE_STATE = 1; private static final int UPDATE_STATE_NEW = 0; - private static final int UPDATE_STATE_TRANSITION = 1; - private static final int UPDATE_STATE_UPDATED = 2; + private static final int UPDATE_STATE_UPDATED = 1; + private static final int UPDATE_STATE_DISABLED = 2; + + private static final int UPDATE_STATE_MASK = 0x3; + + private static final int UPDATE_STATE_FLAG_TRANSITION = 0x100; /** * Temporary display info, used for comparing display configurations. @@ -166,7 +170,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { LogicalDisplayMapper(@NonNull Context context, @NonNull DisplayDeviceRepository repo, @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot, - @NonNull Handler handler) { + @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap) { mSyncRoot = syncRoot; mPowerManager = context.getSystemService(PowerManager.class); mInteractive = mPowerManager.isInteractive(); @@ -181,7 +185,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { mDeviceStatesOnWhichToSleep = toSparseBooleanArray(context.getResources().getIntArray( com.android.internal.R.array.config_deviceStatesOnWhichToSleep)); mDisplayDeviceRepo.addListener(this); - mDeviceStateToLayoutMap = new DeviceStateToLayoutMap(); + mDeviceStateToLayoutMap = deviceStateToLayoutMap; } @Override @@ -218,10 +222,29 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } public LogicalDisplay getDisplayLocked(int displayId) { - return mLogicalDisplays.get(displayId); + return getDisplayLocked(displayId, /* includeDisabled= */ false); + } + + LogicalDisplay getDisplayLocked(int displayId, boolean includeDisabled) { + LogicalDisplay display = mLogicalDisplays.get(displayId); + if (display != null && (display.isEnabled() || includeDisabled)) { + return display; + } + return null; } public LogicalDisplay getDisplayLocked(DisplayDevice device) { + return getDisplayLocked(device, /* includeDisabled= */ false); + } + + /** + * Loops through the existing list of displays and returns one that is associated with the + * specified display device. + * + * @param device The display device that should be associated with the LogicalDisplay. + * @param includeDisabled True if this method should return disabled displays as well. + */ + private LogicalDisplay getDisplayLocked(DisplayDevice device, boolean includeDisabled) { if (device == null) { return null; } @@ -229,18 +252,32 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { for (int i = 0; i < count; i++) { final LogicalDisplay display = mLogicalDisplays.valueAt(i); if (display.getPrimaryDisplayDeviceLocked() == device) { - return display; + if (display.isEnabled() || includeDisabled) { + return display; + } else { + return null; + } } } return null; } + // Returns display Ids, defaults to enabled only. public int[] getDisplayIdsLocked(int callingUid) { + return getDisplayIdsLocked(callingUid, /* includeDisabledDisplays= */ false); + } + + // Returns display Ids, specified whether enabled only, or all displays. + public int[] getDisplayIdsLocked(int callingUid, boolean includeDisabledDisplays) { final int count = mLogicalDisplays.size(); int[] displayIds = new int[count]; int n = 0; for (int i = 0; i < count; i++) { LogicalDisplay display = mLogicalDisplays.valueAt(i); + if (!includeDisabledDisplays && !display.isEnabled()) { + continue; // Ignore disabled displays. + } + DisplayInfo info = display.getDisplayInfoLocked(); if (info.hasAccess(callingUid)) { displayIds[n++] = mLogicalDisplays.keyAt(i); @@ -255,7 +292,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { public void forEachLocked(Consumer<LogicalDisplay> consumer) { final int count = mLogicalDisplays.size(); for (int i = 0; i < count; i++) { - consumer.accept(mLogicalDisplays.valueAt(i)); + LogicalDisplay display = mLogicalDisplays.valueAt(i); + if (display.isEnabled()) { + consumer.accept(display); + } } } @@ -316,7 +356,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { // Find or create the LogicalDisplay to map the DisplayDevice to. final int logicalDisplayId = displayLayout.getLogicalDisplayId(); - final LogicalDisplay logicalDisplay = getDisplayLocked(logicalDisplayId); + final LogicalDisplay logicalDisplay = + getDisplayLocked(logicalDisplayId, /* includeDisabled= */ true); if (logicalDisplay == null) { Slog.w(TAG, "The logical display (" + address + "), is not available" + " for the display state " + deviceState); @@ -452,7 +493,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } /** - * Returns if the device should be put to sleep or not. + * Returns true if the device should be put to sleep or not. * * Includes a check to verify that the device state that we are moving to, {@code pendingState}, * is the same as the physical state of the device, {@code baseState}. Different values for @@ -598,9 +639,12 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo); display.updateLocked(mDisplayDeviceRepo); - final DisplayInfo newDisplayInfo = display.getDisplayInfoLocked(); - final int updateState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW); - final boolean wasPreviouslyUpdated = updateState != UPDATE_STATE_NEW; + DisplayInfo newDisplayInfo = display.getDisplayInfoLocked(); + + final int storedState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW); + final int updateState = storedState & UPDATE_STATE_MASK; + final boolean isTransitioning = (storedState & UPDATE_STATE_FLAG_TRANSITION) != 0; + final boolean wasPreviouslyUpdated = updateState == UPDATE_STATE_UPDATED; // The display is no longer valid and needs to be removed. if (!display.isValidLocked()) { @@ -624,6 +668,35 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } continue; + // The display has been newly disabled, we report this as a removed display but + // don't actually remove it from our internal list in LogicalDisplayMapper. The reason + // is that LogicalDisplayMapper assumes and relies on the fact that every DisplayDevice + // has a LogicalDisplay wrapper, but certain displays that are unusable (like the inner + // display on a folded foldable device) are not available for use by the system and + // we keep them hidden. To do this, we mark those LogicalDisplays as "disabled". + // Also, if the display is in TRANSITION but was previously reported as disabled + // then keep it unreported. + } else if (!display.isEnabled() + || (display.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION + && updateState == UPDATE_STATE_DISABLED)) { + mUpdatedLogicalDisplays.put(displayId, UPDATE_STATE_DISABLED); + + // If we never told anyone about this display, nothing to do + if (!wasPreviouslyUpdated) { + continue; + } + + // Remove from group + final DisplayGroup displayGroup = getDisplayGroupLocked( + getDisplayGroupIdFromDisplayIdLocked(displayId)); + if (displayGroup != null) { + displayGroup.removeDisplayLocked(display); + } + + Slog.i(TAG, "Removing (disabled) display: " + displayId); + mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_REMOVED); + continue; + // The display is new. } else if (!wasPreviouslyUpdated) { Slog.i(TAG, "Adding new display: " + displayId + ": " + newDisplayInfo); @@ -643,7 +716,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED); // The display is involved in a display layout transition - } else if (updateState == UPDATE_STATE_TRANSITION) { + } else if (isTransitioning) { mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION); @@ -717,7 +790,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } final int id = mLogicalDisplaysToUpdate.keyAt(i); - final LogicalDisplay display = getDisplayLocked(id); + final LogicalDisplay display = getDisplayLocked(id, /* includeDisabled= */ true); if (DEBUG) { final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); final String uniqueId = device == null ? "null" : device.getUniqueId(); @@ -725,7 +798,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { + " with device=" + uniqueId); } mListener.onLogicalDisplayEventLocked(display, msg); - if (msg == LOGICAL_DISPLAY_EVENT_REMOVED) { + if (msg == LOGICAL_DISPLAY_EVENT_REMOVED && !display.isValidLocked()) { // We wait until we sent the EVENT_REMOVED event before actually removing the // display. mLogicalDisplays.delete(id); @@ -845,7 +918,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { if (isTransitioning) { setDisplayPhase(logicalDisplay, phase); if (phase == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION) { - mUpdatedLogicalDisplays.put(displayId, UPDATE_STATE_TRANSITION); + int oldState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW); + mUpdatedLogicalDisplays.put(displayId, oldState | UPDATE_STATE_FLAG_TRANSITION); } } } @@ -879,14 +953,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { // Now that we have a display-device, we need a LogicalDisplay to map it to. Find the // right one, if it doesn't exist, create a new one. final int logicalDisplayId = displayLayout.getLogicalDisplayId(); - LogicalDisplay newDisplay = getDisplayLocked(logicalDisplayId); + LogicalDisplay newDisplay = + getDisplayLocked(logicalDisplayId, /* includeDisabled= */ true); if (newDisplay == null) { newDisplay = createNewLogicalDisplayLocked( - null /*displayDevice*/, logicalDisplayId); + /* displayDevice= */ null, logicalDisplayId); } // Now swap the underlying display devices between the old display and the new display - final LogicalDisplay oldDisplay = getDisplayLocked(device); + final LogicalDisplay oldDisplay = getDisplayLocked(device, /* includeDisabled= */ true); if (newDisplay != oldDisplay) { newDisplay.swapDisplaysLocked(oldDisplay); } @@ -903,13 +978,14 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { * Creates a new logical display for the specified device and display Id and adds it to the list * of logical displays. * - * @param device The device to associate with the LogicalDisplay. + * @param displayDevice The displayDevice to associate with the LogicalDisplay. * @param displayId The display ID to give the new display. If invalid, a new ID is assigned. * @return The new logical display if created, null otherwise. */ - private LogicalDisplay createNewLogicalDisplayLocked(DisplayDevice device, int displayId) { + private LogicalDisplay createNewLogicalDisplayLocked(DisplayDevice displayDevice, + int displayId) { final int layerStack = assignLayerStackLocked(displayId); - final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device); + final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, displayDevice); display.updateLocked(mDisplayDeviceRepo); mLogicalDisplays.put(displayId, display); setDisplayPhase(display, LogicalDisplay.DISPLAY_PHASE_ENABLED); diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java index 59daee9ea2ff..b9a0738d15c4 100644 --- a/services/core/java/com/android/server/display/PersistentDataStore.java +++ b/services/core/java/com/android/server/display/PersistentDataStore.java @@ -153,7 +153,7 @@ final class PersistentDataStore { @VisibleForTesting PersistentDataStore(Injector injector) { - this(injector, BackgroundThread.getHandler()); + this(injector, new Handler(BackgroundThread.getHandler().getLooper())); } @VisibleForTesting diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java index d238dae634ad..e222c644da9e 100644 --- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java +++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java @@ -27,6 +27,8 @@ import android.view.InputWindowHandle; import android.view.SurfaceControl; import android.view.WindowManager; +import com.android.server.policy.WindowManagerPolicy; + /** * An internal implementation of an {@link InputMonitor} that uses a spy window. * @@ -67,7 +69,9 @@ class GestureMonitorSpyWindow { final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); t.setInputWindowInfo(mInputSurface, mWindowHandle); - t.setLayer(mInputSurface, Integer.MAX_VALUE); + // Gesture monitor should be above handwriting event surface, hence setting it to + // WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER + 1 + t.setLayer(mInputSurface, WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER + 1); t.setPosition(mInputSurface, 0, 0); t.setCrop(mInputSurface, null /* crop to parent surface */); t.show(mInputSurface); diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java index 8180e66166d9..5438faa8793e 100644 --- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java +++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java @@ -27,6 +27,8 @@ import android.view.InputWindowHandle; import android.view.SurfaceControl; import android.view.WindowManager; +import com.android.server.policy.WindowManagerPolicy; + final class HandwritingEventReceiverSurface { public static final String TAG = HandwritingEventReceiverSurface.class.getSimpleName(); @@ -36,7 +38,8 @@ final class HandwritingEventReceiverSurface { // is above gesture monitors, then edge-back and swipe-up gestures won't work when this surface // is intercepting. // TODO(b/217538817): Specify the ordering in WM by usage. - private static final int HANDWRITING_SURFACE_LAYER = Integer.MAX_VALUE - 1; + private static final int HANDWRITING_SURFACE_LAYER = + WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER; private final InputWindowHandle mWindowHandle; private final InputChannel mClientChannel; diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index d536a463f7b4..b89147ea181a 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -563,14 +563,16 @@ public class MediaSessionService extends SystemService implements Monitor { try { enforcePackageName(callingPackage, callingUid); if (targetUid != callingUid) { - Log.d(TAG, "tempAllowlistTargetPkgIfPossible callingPackage:" - + callingPackage + " targetPackage:" + targetPackage - + " reason:" + reason); boolean canAllowWhileInUse = mActivityManagerLocal .canAllowWhileInUsePermissionInFgs(callingPid, callingUid, callingPackage); boolean canStartFgs = canAllowWhileInUse || mActivityManagerLocal.canStartForegroundService(callingPid, callingUid, callingPackage); + Log.i(TAG, "tempAllowlistTargetPkgIfPossible callingPackage:" + + callingPackage + " targetPackage:" + targetPackage + + " reason:" + reason + + (canAllowWhileInUse ? " [WIU]" : "") + + (canStartFgs ? " [FGS]" : "")); if (canAllowWhileInUse) { mActivityManagerLocal.tempAllowWhileInUsePermissionInFgs(targetUid, MediaSessionDeviceConfig diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 2c1be72e02f0..b3ba20b81118 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -17,6 +17,7 @@ package com.android.server.pm.permission; import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD; +import static android.Manifest.permission.CAPTURE_AUDIO_OUTPUT; import static android.Manifest.permission.RECORD_AUDIO; import static android.Manifest.permission.UPDATE_APP_OPS_STATS; import static android.app.AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE; @@ -1364,8 +1365,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { // the only use case for this, so simply override here. if (!permissionGranted && Process.isIsolated(uid) // simple check which fails-fast for the common case - && (permission.equals(RECORD_AUDIO) - || permission.equals(CAPTURE_AUDIO_HOTWORD))) { + && (permission.equals(RECORD_AUDIO) || permission.equals(CAPTURE_AUDIO_HOTWORD) + || permission.equals(CAPTURE_AUDIO_OUTPUT))) { HotwordDetectionServiceProvider hotwordServiceProvider = permissionManagerServiceInt.getHotwordDetectionServiceProvider(); permissionGranted = hotwordServiceProvider != null diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java index d2c4ec4cc5a5..95badb31f324 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java @@ -449,8 +449,8 @@ public interface PermissionManagerServiceInternal extends PermissionManagerInter /** * Provides the uid of the currently active - * {@link android.service.voice.HotwordDetectionService}, which should be granted RECORD_AUDIO - * and CAPTURE_AUDIO_HOTWORD permissions. + * {@link android.service.voice.HotwordDetectionService}, which should be granted RECORD_AUDIO, + * CAPTURE_AUDIO_HOTWORD and CAPTURE_AUDIO_OUTPUT permissions. */ interface HotwordDetectionServiceProvider { int getUid(); diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index 7ca09ab5154f..89178139ffec 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -156,6 +156,10 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { int FINISH_LAYOUT_REDO_ANIM = 0x0008; /** Layer for the screen off animation */ int COLOR_FADE_LAYER = 0x40000001; + /** Layer for Input overlays for capturing inputs for gesture detection, etc. */ + int INPUT_DISPLAY_OVERLAY_LAYER = 0x7f000000; + /** Layer for Screen Decoration: The top most visible layer just below input overlay layers */ + int SCREEN_DECOR_DISPLAY_OVERLAY_LAYER = INPUT_DISPLAY_OVERLAY_LAYER - 1; /** * Register shortcuts for window manager to dispatch. diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index a059ac613dde..98c5d512be0e 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5392,6 +5392,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return mOverlayLayer; } + SurfaceControl[] findRoundedCornerOverlays() { + List<SurfaceControl> roundedCornerOverlays = new ArrayList<>(); + for (WindowToken token : mTokenMap.values()) { + if (token.mRoundedCornerOverlay) { + roundedCornerOverlays.add(token.mSurfaceControl); + } + } + return roundedCornerOverlays.toArray(new SurfaceControl[0]); + } + /** * Updates the display's system gesture exclusion. * diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java index 33cdd2e98113..b7ddbd070460 100644 --- a/services/core/java/com/android/server/wm/InputManagerCallback.java +++ b/services/core/java/com/android/server/wm/InputManagerCallback.java @@ -265,7 +265,7 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal .setContainerLayer() .setName(name) .setCallsite("createSurfaceForGestureMonitor") - .setParent(dc.getSurfaceControl()) + .setParent(dc.getOverlayLayer()) .build(); } } diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index 518bfd4c90df..2ef19321d958 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -164,6 +164,10 @@ class ScreenRotationAnimation { .setCaptureSecureLayers(true) .setAllowProtected(true) .setSourceCrop(new Rect(0, 0, width, height)) + // Exclude rounded corner overlay from screenshot buffer. Rounded + // corner overlay windows are un-rotated during rotation animation + // for a seamless transition. + .setExcludeLayers(displayContent.findRoundedCornerOverlays()) .build(); SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = SurfaceControl.captureLayers(args); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 902218621cd0..52af39ee64b3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -8215,7 +8215,7 @@ public class WindowManagerService extends IWindowManager.Stub .setContainerLayer() .setName("IME Handwriting Surface") .setCallsite("getHandwritingSurfaceForDisplay") - .setParent(dc.getSurfaceControl()) + .setParent(dc.getOverlayLayer()) .build(); } } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index d2e56faa0914..18f60b1a9a20 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -368,7 +368,7 @@ class WindowToken extends WindowContainer<WindowState> { super.assignRelativeLayer(t, mDisplayContent.getDefaultTaskDisplayArea().getSplitScreenDividerAnchor(), 1); } else if (mRoundedCornerOverlay) { - super.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1); + super.assignLayer(t, WindowManagerPolicy.SCREEN_DECOR_DISPLAY_OVERLAY_LAYER); } else { super.assignLayer(t, layer); } @@ -378,7 +378,7 @@ class WindowToken extends WindowContainer<WindowState> { SurfaceControl.Builder makeSurface() { final SurfaceControl.Builder builder = super.makeSurface(); if (mRoundedCornerOverlay) { - builder.setParent(null); + builder.setParent(getDisplayContent().getOverlayLayer()); } return builder; } diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java index cdc9d7198cb5..494246491e47 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -67,6 +67,7 @@ import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REFRESH_ import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_ALARMS; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_FOR_CANCELED; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.TARE_AFFORDABILITY_CHANGED; +import static com.android.server.alarm.AlarmManagerService.AlarmHandler.TEMPORARY_QUOTA_CHANGED; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_QUOTA; @@ -83,6 +84,7 @@ import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_FUT import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_INTERVAL; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_WINDOW; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_PRIORITY_ALARM_DELAY; +import static com.android.server.alarm.AlarmManagerService.Constants.KEY_TEMPORARY_QUOTA_BUMP; import static com.android.server.alarm.AlarmManagerService.Constants.MAX_EXACT_ALARM_DENY_LIST_SIZE; import static com.android.server.alarm.AlarmManagerService.FREQUENT_INDEX; import static com.android.server.alarm.AlarmManagerService.INDEFINITE_DELAY; @@ -110,6 +112,7 @@ import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verifyZeroInteractions; import android.Manifest; import android.app.ActivityManager; @@ -654,6 +657,7 @@ public class AlarmManagerServiceTest { setDeviceConfigLong(KEY_MIN_INTERVAL, 0); mDeviceConfigKeys.add(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[ACTIVE_INDEX]); mDeviceConfigKeys.add(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[WORKING_INDEX]); + mDeviceConfigKeys.add(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[FREQUENT_INDEX]); doReturn(50).when(mDeviceConfigProperties) .getInt(eq(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[ACTIVE_INDEX]), anyInt()); doReturn(35).when(mDeviceConfigProperties) @@ -732,6 +736,7 @@ public class AlarmManagerServiceTest { setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, 55); setDeviceConfigLong(KEY_MIN_DEVICE_IDLE_FUZZ, 60); setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 65); + setDeviceConfigInt(KEY_TEMPORARY_QUOTA_BUMP, 70); assertEquals(5, mService.mConstants.MIN_FUTURITY); assertEquals(10, mService.mConstants.MIN_INTERVAL); assertEquals(15, mService.mConstants.MAX_INTERVAL); @@ -745,6 +750,7 @@ public class AlarmManagerServiceTest { assertEquals(55, mService.mConstants.PRIORITY_ALARM_DELAY); assertEquals(60, mService.mConstants.MIN_DEVICE_IDLE_FUZZ); assertEquals(65, mService.mConstants.MAX_DEVICE_IDLE_FUZZ); + assertEquals(70, mService.mConstants.TEMPORARY_QUOTA_BUMP); } @Test @@ -879,6 +885,7 @@ public class AlarmManagerServiceTest { for (int i = 0; i < quota; i++) { alarmSetter.accept(firstTrigger + i); mNowElapsedTest = mTestTimer.getElapsed(); + assertEquals("Incorrect trigger time at i=" + i, firstTrigger + i, mNowElapsedTest); mTestTimer.expire(); } // This one should get deferred on set @@ -897,6 +904,7 @@ public class AlarmManagerServiceTest { alarmSetter.accept(firstTrigger + quota); for (int i = 0; i < quota; i++) { mNowElapsedTest = mTestTimer.getElapsed(); + assertEquals("Incorrect trigger time at i=" + i, firstTrigger + i, mNowElapsedTest); mTestTimer.expire(); } final long expectedNextTrigger = firstTrigger + window; @@ -914,6 +922,7 @@ public class AlarmManagerServiceTest { alarmSetter.accept(expectedNextTrigger); for (int i = 0; i < quota; i++) { mNowElapsedTest = mTestTimer.getElapsed(); + assertEquals("Incorrect trigger time at i=" + i, firstTrigger + i, mNowElapsedTest); mTestTimer.expire(); } assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); @@ -1919,16 +1928,14 @@ public class AlarmManagerServiceTest { getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow); // Refresh the state - mService.removeLocked(TEST_CALLING_UID, - REMOVE_REASON_UNDEFINED); + mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED); mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); testQuotasDeferralOnExpiration(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow); // Refresh the state - mService.removeLocked(TEST_CALLING_UID, - REMOVE_REASON_UNDEFINED); + mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED); mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); testQuotasNoDeferral(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger, @@ -3303,7 +3310,7 @@ public class AlarmManagerServiceTest { Arrays.asList(package4)); mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false); - mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] { + mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{ package1, package3, }); @@ -3315,7 +3322,7 @@ public class AlarmManagerServiceTest { assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4)); mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true); - mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] { + mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{ package1, package3, }); @@ -3407,6 +3414,218 @@ public class AlarmManagerServiceTest { assertFalse(mService.hasUseExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID)); } + @Test + public void temporaryQuotaReserve_hasQuota() { + final int quotaToFill = 5; + final String package1 = "package1"; + final int user1 = 123; + final long startTime = 54; + final long quotaDuration = 17; + + final AlarmManagerService.TemporaryQuotaReserve quotaReserve = + new AlarmManagerService.TemporaryQuotaReserve(quotaDuration); + quotaReserve.replenishQuota(package1, user1, quotaToFill, startTime); + + for (long time = startTime; time <= startTime + quotaDuration; time++) { + assertTrue(quotaReserve.hasQuota(package1, user1, time)); + assertFalse(quotaReserve.hasQuota("some.other.package", 21, time)); + assertFalse(quotaReserve.hasQuota(package1, 321, time)); + } + + assertFalse(quotaReserve.hasQuota(package1, user1, startTime + quotaDuration + 1)); + assertFalse(quotaReserve.hasQuota(package1, user1, startTime + quotaDuration + 435421)); + + for (int i = 0; i < quotaToFill - 1; i++) { + assertTrue(i < quotaDuration); + // Use record usage multiple times with the same timestamp. + quotaReserve.recordUsage(package1, user1, startTime + i); + quotaReserve.recordUsage(package1, user1, startTime + i); + quotaReserve.recordUsage(package1, user1, startTime + i); + quotaReserve.recordUsage(package1, user1, startTime + i); + + // Quota should not run out in this loop. + assertTrue(quotaReserve.hasQuota(package1, user1, startTime + i)); + } + quotaReserve.recordUsage(package1, user1, startTime + quotaDuration); + + // Should be out of quota now. + for (long time = startTime; time <= startTime + quotaDuration; time++) { + assertFalse(quotaReserve.hasQuota(package1, user1, time)); + } + } + + @Test + public void temporaryQuotaReserve_removeForPackage() { + final String[] packages = new String[]{"package1", "test.package2"}; + final int userId = 472; + final long startTime = 59; + final long quotaDuration = 100; + + final AlarmManagerService.TemporaryQuotaReserve quotaReserve = + new AlarmManagerService.TemporaryQuotaReserve(quotaDuration); + + quotaReserve.replenishQuota(packages[0], userId, 10, startTime); + quotaReserve.replenishQuota(packages[1], userId, 10, startTime); + + assertTrue(quotaReserve.hasQuota(packages[0], userId, startTime + 1)); + assertTrue(quotaReserve.hasQuota(packages[1], userId, startTime + 1)); + + quotaReserve.removeForPackage(packages[0], userId); + + assertFalse(quotaReserve.hasQuota(packages[0], userId, startTime + 1)); + assertTrue(quotaReserve.hasQuota(packages[1], userId, startTime + 1)); + } + + @Test + public void temporaryQuotaReserve_removeForUser() { + final String[] packagesUser1 = new String[]{"test1.package1", "test1.package2"}; + final String[] packagesUser2 = new String[]{"test2.p1", "test2.p2", "test2.p3"}; + final int user1 = 3201; + final int user2 = 5409; + final long startTime = 59; + final long quotaDuration = 100; + + final AlarmManagerService.TemporaryQuotaReserve quotaReserve = + new AlarmManagerService.TemporaryQuotaReserve(quotaDuration); + + for (String packageUser1 : packagesUser1) { + quotaReserve.replenishQuota(packageUser1, user1, 10, startTime); + } + for (String packageUser2 : packagesUser2) { + quotaReserve.replenishQuota(packageUser2, user2, 10, startTime); + } + + for (String packageUser1 : packagesUser1) { + assertTrue(quotaReserve.hasQuota(packageUser1, user1, startTime)); + } + for (String packageUser2 : packagesUser2) { + assertTrue(quotaReserve.hasQuota(packageUser2, user2, startTime)); + } + + quotaReserve.removeForUser(user2); + + for (String packageUser1 : packagesUser1) { + assertTrue(quotaReserve.hasQuota(packageUser1, user1, startTime)); + } + for (String packageUser2 : packagesUser2) { + assertFalse(quotaReserve.hasQuota(packageUser2, user2, startTime)); + } + } + + @Test + public void triggerTemporaryQuotaBump_zeroQuota() { + setDeviceConfigInt(KEY_TEMPORARY_QUOTA_BUMP, 0); + + mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + verifyZeroInteractions(mPackageManagerInternal); + verifyZeroInteractions(mService.mHandler); + } + + private void testTemporaryQuota_bumpedAfterDeferral(int standbyBucket) throws Exception { + final int temporaryQuota = 31; + setDeviceConfigInt(KEY_TEMPORARY_QUOTA_BUMP, temporaryQuota); + + final int standbyQuota = mService.getQuotaForBucketLocked(standbyBucket); + when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), + anyLong())).thenReturn(standbyBucket); + + final long firstTrigger = mNowElapsedTest + 10; + for (int i = 0; i < standbyQuota + 1; i++) { + setTestAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, getNewMockPendingIntent()); + } + + for (int i = 0; i < standbyQuota; i++) { + mNowElapsedTest = mTestTimer.getElapsed(); + assertEquals("Incorrect trigger time at i=" + i, firstTrigger + i, mNowElapsedTest); + mTestTimer.expire(); + } + + // The last alarm should be deferred due to exceeding the quota + final long deferredTrigger = firstTrigger + mAppStandbyWindow; + assertEquals(deferredTrigger, mTestTimer.getElapsed()); + + // Triggering temporary quota now. + mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + assertAndHandleMessageSync(TEMPORARY_QUOTA_CHANGED); + // The last alarm should now be rescheduled to go as per original expectations + final long originalTrigger = firstTrigger + standbyQuota; + assertEquals("Incorrect next alarm trigger", originalTrigger, mTestTimer.getElapsed()); + } + + + @Test + public void temporaryQuota_bumpedAfterDeferral_active() throws Exception { + testTemporaryQuota_bumpedAfterDeferral(STANDBY_BUCKET_ACTIVE); + } + + @Test + public void temporaryQuota_bumpedAfterDeferral_working() throws Exception { + testTemporaryQuota_bumpedAfterDeferral(STANDBY_BUCKET_WORKING_SET); + } + + @Test + public void temporaryQuota_bumpedAfterDeferral_frequent() throws Exception { + testTemporaryQuota_bumpedAfterDeferral(STANDBY_BUCKET_FREQUENT); + } + + @Test + public void temporaryQuota_bumpedAfterDeferral_rare() throws Exception { + testTemporaryQuota_bumpedAfterDeferral(STANDBY_BUCKET_RARE); + } + + private void testTemporaryQuota_bumpedBeforeDeferral(int standbyBucket) throws Exception { + final int temporaryQuota = 7; + setDeviceConfigInt(KEY_TEMPORARY_QUOTA_BUMP, temporaryQuota); + + final int standbyQuota = mService.getQuotaForBucketLocked(standbyBucket); + when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), + anyLong())).thenReturn(standbyBucket); + + mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + // No need to handle message TEMPORARY_QUOTA_CHANGED, as the quota change doesn't need to + // trigger a re-evaluation in this test. + testQuotasDeferralOnExpiration(trigger -> setTestAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent()), standbyQuota + temporaryQuota, mAppStandbyWindow); + + // refresh the state. + mService.removeLocked(TEST_CALLING_PACKAGE); + mService.mAppWakeupHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + mService.mTemporaryQuotaReserve.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + + mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + testQuotasDeferralOnSet(trigger -> setTestAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent()), standbyQuota + temporaryQuota, mAppStandbyWindow); + + // refresh the state. + mService.removeLocked(TEST_CALLING_PACKAGE); + mService.mAppWakeupHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + mService.mTemporaryQuotaReserve.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + + mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER); + testQuotasNoDeferral(trigger -> setTestAlarm(ELAPSED_REALTIME_WAKEUP, trigger, + getNewMockPendingIntent()), standbyQuota + temporaryQuota, mAppStandbyWindow); + } + + @Test + public void temporaryQuota_bumpedBeforeDeferral_active() throws Exception { + testTemporaryQuota_bumpedBeforeDeferral(STANDBY_BUCKET_ACTIVE); + } + + @Test + public void temporaryQuota_bumpedBeforeDeferral_working() throws Exception { + testTemporaryQuota_bumpedBeforeDeferral(STANDBY_BUCKET_WORKING_SET); + } + + @Test + public void temporaryQuota_bumpedBeforeDeferral_frequent() throws Exception { + testTemporaryQuota_bumpedBeforeDeferral(STANDBY_BUCKET_FREQUENT); + } + + @Test + public void temporaryQuota_bumpedBeforeDeferral_rare() throws Exception { + testTemporaryQuota_bumpedBeforeDeferral(STANDBY_BUCKET_RARE); + } + @After public void tearDown() { if (mMockingSession != null) { diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java index 1e97c1c5c5bc..5f1ff6be49be 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -287,7 +287,7 @@ public class DisplayManagerServiceTest { when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); - final int displayIds[] = bs.getDisplayIds(); + final int[] displayIds = bs.getDisplayIds(/* includeDisabled= */ false); final int size = displayIds.length; assertTrue(size > 0); @@ -297,7 +297,9 @@ public class DisplayManagerServiceTest { ); for (int i = 0; i < size; i++) { DisplayInfo info = bs.getDisplayInfo(displayIds[i]); - assertTrue(expectedDisplayTypeToViewPortTypeMapping.keySet().contains(info.type)); + if (info != null) { + assertTrue(expectedDisplayTypeToViewPortTypeMapping.keySet().contains(info.type)); + } } displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class)); @@ -1174,7 +1176,8 @@ public class DisplayManagerServiceTest { DisplayManagerService.BinderService displayManagerBinderService, FakeDisplayDevice displayDevice) { - final int[] displayIds = displayManagerBinderService.getDisplayIds(); + final int[] displayIds = displayManagerBinderService.getDisplayIds( + /* includeDisabled= */ false); assertTrue(displayIds.length > 0); int displayId = Display.INVALID_DISPLAY; for (int i = 0; i < displayIds.length; i++) { diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java index cc68ba88f76e..5b131454e4db 100644 --- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java +++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java @@ -33,6 +33,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -53,6 +54,8 @@ import android.view.DisplayInfo; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.server.display.layout.Layout; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -79,6 +82,7 @@ public class LogicalDisplayMapperTest { private TestLooper mLooper; private Handler mHandler; private PowerManager mPowerManager; + private DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy; @Mock LogicalDisplayMapper.Listener mListenerMock; @Mock Context mContextMock; @@ -133,8 +137,11 @@ public class LogicalDisplayMapperTest { mLooper = new TestLooper(); mHandler = new Handler(mLooper.getLooper()); + + mDeviceStateToLayoutMapSpy = spy(new DeviceStateToLayoutMap()); mLogicalDisplayMapper = new LogicalDisplayMapper(mContextMock, mDisplayDeviceRepo, - mListenerMock, new DisplayManagerService.SyncRoot(), mHandler); + mListenerMock, new DisplayManagerService.SyncRoot(), mHandler, + mDeviceStateToLayoutMapSpy); } @@ -413,6 +420,86 @@ public class LogicalDisplayMapperTest { /* isBootCompleted= */true)); } + @Test public void testEnabledAndDisabledDisplays() { + DisplayAddress displayAddressOne = new TestUtils.TestDisplayAddress(); + DisplayAddress displayAddressTwo = new TestUtils.TestDisplayAddress(); + DisplayAddress displayAddressThree = new TestUtils.TestDisplayAddress(); + + TestDisplayDevice device1 = createDisplayDevice(displayAddressOne, Display.TYPE_INTERNAL, + 600, 800, + DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY); + TestDisplayDevice device2 = createDisplayDevice(displayAddressTwo, Display.TYPE_INTERNAL, + 200, 800, + DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); + TestDisplayDevice device3 = createDisplayDevice(displayAddressThree, Display.TYPE_INTERNAL, + 600, 900, DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP); + + Layout threeDevicesEnabledLayout = new Layout(); + threeDevicesEnabledLayout.createDisplayLocked( + displayAddressOne, + /* isDefault= */ true, + /* isEnabled= */ true); + + threeDevicesEnabledLayout.createDisplayLocked( + displayAddressTwo, + /* isDefault= */ false, + /* isEnabled= */ true); + threeDevicesEnabledLayout.createDisplayLocked( + displayAddressThree, + /* isDefault= */ false, + /* isEnabled= */ true); + + when(mDeviceStateToLayoutMapSpy.get(DeviceStateToLayoutMap.STATE_DEFAULT)) + .thenReturn(threeDevicesEnabledLayout); + + LogicalDisplay display1 = add(device1); + LogicalDisplay display2 = add(device2); + LogicalDisplay display3 = add(device3); + + // ensure 3 displays are returned + int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID); + assertEquals(3, ids.length); + Arrays.sort(ids); + assertEquals(DEFAULT_DISPLAY, ids[0]); + + Layout oneDeviceEnabledLayout = new Layout(); + oneDeviceEnabledLayout.createDisplayLocked( + display1.getDisplayInfoLocked().address, + /* isDefault= */ true, + /* isEnabled= */ true); + oneDeviceEnabledLayout.createDisplayLocked( + display2.getDisplayInfoLocked().address, + /* isDefault= */ false, + /* isEnabled= */ false); + oneDeviceEnabledLayout.createDisplayLocked( + display3.getDisplayInfoLocked().address, + /* isDefault= */ false, + /* isEnabled= */ false); + + when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(oneDeviceEnabledLayout); + when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(threeDevicesEnabledLayout); + + mLogicalDisplayMapper + .setDeviceStateLocked(0, false); + mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED); + final int[] allDisplayIds = mLogicalDisplayMapper.getDisplayIdsLocked( + Process.SYSTEM_UID, false); + mLooper.dispatchAll(); + + // ensure only one display is returned + assertEquals(1, allDisplayIds.length); + + mLogicalDisplayMapper + .setDeviceStateLocked(1, false); + mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED); + final int[] threeDisplaysEnabled = mLogicalDisplayMapper.getDisplayIdsLocked( + Process.SYSTEM_UID, false); + mLooper.dispatchAll(); + + // ensure all three displays are returned + assertEquals(3, threeDisplaysEnabled.length); + } + ///////////////// // Helper Methods ///////////////// diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java index 758a56f3d2ad..e9171c0c3514 100644 --- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java @@ -393,14 +393,14 @@ public class SystemConfigTest { + " <library \n" + " name=\"foo\"\n" + " file=\"" + mFooJar + "\"\n" - + " on-bootclasspath-before=\"A\"\n" + + " on-bootclasspath-before=\"Q\"\n" + " on-bootclasspath-since=\"W\"\n" + " />\n\n" + " </permissions>"; parseSharedLibraries(contents); assertFooIsOnlySharedLibrary(); SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo"); - assertThat(entry.onBootclasspathBefore).isEqualTo("A"); + assertThat(entry.onBootclasspathBefore).isEqualTo("Q"); assertThat(entry.onBootclasspathSince).isEqualTo("W"); } diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java index cc28ea6f55d2..87382952314b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java @@ -48,11 +48,11 @@ public class SurfaceSyncerTest { public void testSyncOne() throws InterruptedException { final CountDownLatch finishedLatch = new CountDownLatch(1); int startSyncId = mSurfaceSyncer.setupSync(transaction -> finishedLatch.countDown()); - Syncable syncable = new Syncable(); - mSurfaceSyncer.addToSync(startSyncId, syncable); + SyncTarget syncTarget = new SyncTarget(); + mSurfaceSyncer.addToSync(startSyncId, syncTarget); mSurfaceSyncer.markSyncReady(startSyncId); - syncable.onBufferReady(); + syncTarget.onBufferReady(); finishedLatch.await(5, TimeUnit.SECONDS); assertEquals(0, finishedLatch.getCount()); @@ -62,22 +62,22 @@ public class SurfaceSyncerTest { public void testSyncMultiple() throws InterruptedException { final CountDownLatch finishedLatch = new CountDownLatch(1); int startSyncId = mSurfaceSyncer.setupSync(transaction -> finishedLatch.countDown()); - Syncable syncable1 = new Syncable(); - Syncable syncable2 = new Syncable(); - Syncable syncable3 = new Syncable(); + SyncTarget syncTarget1 = new SyncTarget(); + SyncTarget syncTarget2 = new SyncTarget(); + SyncTarget syncTarget3 = new SyncTarget(); - mSurfaceSyncer.addToSync(startSyncId, syncable1); - mSurfaceSyncer.addToSync(startSyncId, syncable2); - mSurfaceSyncer.addToSync(startSyncId, syncable3); + mSurfaceSyncer.addToSync(startSyncId, syncTarget1); + mSurfaceSyncer.addToSync(startSyncId, syncTarget2); + mSurfaceSyncer.addToSync(startSyncId, syncTarget3); mSurfaceSyncer.markSyncReady(startSyncId); - syncable1.onBufferReady(); + syncTarget1.onBufferReady(); assertNotEquals(0, finishedLatch.getCount()); - syncable3.onBufferReady(); + syncTarget3.onBufferReady(); assertNotEquals(0, finishedLatch.getCount()); - syncable2.onBufferReady(); + syncTarget2.onBufferReady(); finishedLatch.await(5, TimeUnit.SECONDS); assertEquals(0, finishedLatch.getCount()); @@ -85,7 +85,7 @@ public class SurfaceSyncerTest { @Test public void testInvalidSyncId() { - assertFalse(mSurfaceSyncer.addToSync(0, new Syncable())); + assertFalse(mSurfaceSyncer.addToSync(0, new SyncTarget())); } @Test @@ -93,14 +93,14 @@ public class SurfaceSyncerTest { final CountDownLatch finishedLatch = new CountDownLatch(1); int startSyncId = mSurfaceSyncer.setupSync(transaction -> finishedLatch.countDown()); - Syncable syncable1 = new Syncable(); - Syncable syncable2 = new Syncable(); + SyncTarget syncTarget1 = new SyncTarget(); + SyncTarget syncTarget2 = new SyncTarget(); - assertTrue(mSurfaceSyncer.addToSync(startSyncId, syncable1)); + assertTrue(mSurfaceSyncer.addToSync(startSyncId, syncTarget1)); mSurfaceSyncer.markSyncReady(startSyncId); // Adding to a sync that has been completed is also invalid since the sync id has been // cleared. - assertFalse(mSurfaceSyncer.addToSync(startSyncId, syncable2)); + assertFalse(mSurfaceSyncer.addToSync(startSyncId, syncTarget2)); } @Test @@ -110,27 +110,89 @@ public class SurfaceSyncerTest { int startSyncId1 = mSurfaceSyncer.setupSync(transaction -> finishedLatch1.countDown()); int startSyncId2 = mSurfaceSyncer.setupSync(transaction -> finishedLatch2.countDown()); - Syncable syncable1 = new Syncable(); - Syncable syncable2 = new Syncable(); + SyncTarget syncTarget1 = new SyncTarget(); + SyncTarget syncTarget2 = new SyncTarget(); - assertTrue(mSurfaceSyncer.addToSync(startSyncId1, syncable1)); - assertTrue(mSurfaceSyncer.addToSync(startSyncId2, syncable2)); + assertTrue(mSurfaceSyncer.addToSync(startSyncId1, syncTarget1)); + assertTrue(mSurfaceSyncer.addToSync(startSyncId2, syncTarget2)); mSurfaceSyncer.markSyncReady(startSyncId1); mSurfaceSyncer.markSyncReady(startSyncId2); - syncable1.onBufferReady(); + syncTarget1.onBufferReady(); finishedLatch1.await(5, TimeUnit.SECONDS); assertEquals(0, finishedLatch1.getCount()); assertNotEquals(0, finishedLatch2.getCount()); - syncable2.onBufferReady(); + syncTarget2.onBufferReady(); finishedLatch2.await(5, TimeUnit.SECONDS); assertEquals(0, finishedLatch2.getCount()); } - private static class Syncable implements SurfaceSyncer.SyncTarget { + @Test + public void testMergeSync() throws InterruptedException { + final CountDownLatch finishedLatch1 = new CountDownLatch(1); + final CountDownLatch finishedLatch2 = new CountDownLatch(1); + int startSyncId1 = mSurfaceSyncer.setupSync(transaction -> finishedLatch1.countDown()); + int startSyncId2 = mSurfaceSyncer.setupSync(transaction -> finishedLatch2.countDown()); + + SyncTarget syncTarget1 = new SyncTarget(); + SyncTarget syncTarget2 = new SyncTarget(); + + assertTrue(mSurfaceSyncer.addToSync(startSyncId1, syncTarget1)); + assertTrue(mSurfaceSyncer.addToSync(startSyncId2, syncTarget2)); + mSurfaceSyncer.markSyncReady(startSyncId1); + mSurfaceSyncer.merge(startSyncId2, startSyncId1, mSurfaceSyncer); + mSurfaceSyncer.markSyncReady(startSyncId2); + + // Finish syncTarget2 first to test that the syncSet is not complete until the merged sync + // is also done. + syncTarget2.onBufferReady(); + finishedLatch2.await(1, TimeUnit.SECONDS); + // Sync did not complete yet + assertNotEquals(0, finishedLatch2.getCount()); + + syncTarget1.onBufferReady(); + + // The first sync will still get a callback when it's sync requirements are done. + finishedLatch1.await(5, TimeUnit.SECONDS); + assertEquals(0, finishedLatch1.getCount()); + + finishedLatch2.await(5, TimeUnit.SECONDS); + assertEquals(0, finishedLatch2.getCount()); + } + + @Test + public void testMergeSyncAlreadyComplete() throws InterruptedException { + final CountDownLatch finishedLatch1 = new CountDownLatch(1); + final CountDownLatch finishedLatch2 = new CountDownLatch(1); + int startSyncId1 = mSurfaceSyncer.setupSync(transaction -> finishedLatch1.countDown()); + int startSyncId2 = mSurfaceSyncer.setupSync(transaction -> finishedLatch2.countDown()); + + SyncTarget syncTarget1 = new SyncTarget(); + SyncTarget syncTarget2 = new SyncTarget(); + + assertTrue(mSurfaceSyncer.addToSync(startSyncId1, syncTarget1)); + assertTrue(mSurfaceSyncer.addToSync(startSyncId2, syncTarget2)); + mSurfaceSyncer.markSyncReady(startSyncId1); + syncTarget1.onBufferReady(); + + // The first sync will still get a callback when it's sync requirements are done. + finishedLatch1.await(5, TimeUnit.SECONDS); + assertEquals(0, finishedLatch1.getCount()); + + mSurfaceSyncer.merge(startSyncId2, startSyncId1, mSurfaceSyncer); + mSurfaceSyncer.markSyncReady(startSyncId2); + syncTarget2.onBufferReady(); + + // Verify that the second sync will receive complete since the merged sync was already + // completed before the merge. + finishedLatch2.await(5, TimeUnit.SECONDS); + assertEquals(0, finishedLatch2.getCount()); + } + + private static class SyncTarget implements SurfaceSyncer.SyncTarget { private SurfaceSyncer.SyncBufferCallback mSyncBufferCallback; @Override diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 2337a5aae467..d07d8097bce4 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -3426,21 +3426,10 @@ public class SubscriptionManager { * Get subscriptionInfo list of subscriptions that are in the same group of given subId. * See {@link #createSubscriptionGroup(List)} for more details. * - * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE} - * or carrier privilege permission on the subscription. + * Caller will either have {@link android.Manifest.permission#READ_PHONE_STATE} + * permission or had carrier privilege permission on the subscription. * {@link TelephonyManager#hasCarrierPrivileges()} * - * <p>Starting with API level 33, the caller needs the additional permission - * {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} - * to get the list of subscriptions associated with a group UUID. - * This method can be invoked if one of the following requirements is met: - * <ul> - * <li>If the app has carrier privilege permission. - * {@link TelephonyManager#hasCarrierPrivileges()} - * <li>If the app has {@link android.Manifest.permission#READ_PHONE_STATE} and - * {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} permission. - * </ul> - * * @throws IllegalStateException if Telephony service is in bad state. * @throws SecurityException if the caller doesn't meet the requirements * outlined above. |