diff options
752 files changed, 10947 insertions, 6221 deletions
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java index 1b9cf2648a3f..7393bcde13b6 100644 --- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java +++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java @@ -27,7 +27,7 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.compat.annotation.ChangeId; -import android.compat.annotation.EnabledAfter; +import android.compat.annotation.Disabled; import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; @@ -282,15 +282,14 @@ public class AlarmManager { public static final long ENABLE_USE_EXACT_ALARM = 218533173L; /** - * For apps targeting {@link Build.VERSION_CODES#TIRAMISU} or above, the permission - * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} will be denied, unless the user explicitly - * allows it from Settings. + * The permission {@link Manifest.permission#SCHEDULE_EXACT_ALARM} will be denied, unless the + * user explicitly allows it from Settings. * - * TODO (b/226439802): change to EnabledSince(T) after SDK finalization. + * TODO (b/226439802): Either enable it in the next SDK or replace it with a better alternative. * @hide */ @ChangeId - @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S_V2) + @Disabled public static final long SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = 226439802L; @UnsupportedAppUsage 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 2ea8592e883e..7b77e86f4d6a 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -565,9 +565,6 @@ 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_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = - "schedule_exact_alarm_denied_by_default"; private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; @@ -612,8 +609,6 @@ public class AlarmManagerService extends SystemService { private static final boolean DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = true; - private static final boolean DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = true; - // Minimum futurity of a new alarm public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY; @@ -701,14 +696,6 @@ public class AlarmManagerService extends SystemService { public boolean KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED; - /** - * When this is {@code true}, apps with the change - * {@link AlarmManager#SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT} enabled will not get - * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} unless the user grants it to them. - */ - public volatile boolean SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = - DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT; - public boolean USE_TARE_POLICY = Settings.Global.DEFAULT_ENABLE_TARE == 1; private long mLastAllowWhileIdleWhitelistDuration = -1; @@ -892,15 +879,6 @@ public class AlarmManagerService extends SystemService { KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED, DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED); break; - case KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT: - final boolean oldValue = SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT; - - SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = properties.getBoolean( - KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, - DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT); - handleScheduleExactAlarmDeniedByDefaultChange(oldValue, - SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT); - break; default: if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) { // The quotas need to be updated in order, so we can't just rely @@ -971,15 +949,6 @@ public class AlarmManagerService extends SystemService { } } - private void handleScheduleExactAlarmDeniedByDefaultChange(boolean oldValue, - boolean newValue) { - if (oldValue == newValue) { - return; - } - mHandler.obtainMessage(AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE, - newValue).sendToTarget(); - } - private void migrateAlarmsToNewStoreLocked() { final AlarmStore newStore = LAZY_BATCHING ? new LazyAlarmStore() : new BatchingAlarmStore(); @@ -1156,9 +1125,6 @@ public class AlarmManagerService extends SystemService { pw.print(KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED, KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED); pw.println(); - pw.print(KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, - SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT); - pw.println(); pw.print(Settings.Global.ENABLE_TARE, USE_TARE_POLICY); pw.println(); @@ -2928,10 +2894,8 @@ public class AlarmManagerService extends SystemService { } private boolean isScheduleExactAlarmDeniedByDefault(String packageName, int userId) { - return mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT - && CompatChanges.isChangeEnabled( - AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, packageName, - UserHandle.of(userId)); + return CompatChanges.isChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, + packageName, UserHandle.of(userId)); } @NeverCompile // Avoid size overhead of debugging code. @@ -4707,7 +4671,6 @@ 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 CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE = 14; AlarmHandler() { super(Looper.myLooper()); @@ -4827,32 +4790,6 @@ public class AlarmManagerService extends SystemService { removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */false); } break; - case CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE: - final boolean defaultDenied = (Boolean) msg.obj; - - final int[] startedUserIds = mActivityManagerInternal.getStartedUserIds(); - for (int appId : mExactAlarmCandidates) { - for (int userId : startedUserIds) { - uid = UserHandle.getUid(userId, appId); - - final AndroidPackage packageForUid = - mPackageManagerInternal.getPackage(uid); - if (packageForUid == null) { - continue; - } - final String pkg = packageForUid.getPackageName(); - if (defaultDenied) { - if (!hasScheduleExactAlarmInternal(pkg, uid) - && !hasUseExactAlarmInternal(pkg, uid)) { - removeExactAlarmsOnPermissionRevoked(uid, pkg, true); - } - } else if (hasScheduleExactAlarmInternal(pkg, uid)) { - sendScheduleExactAlarmPermissionStateChangedBroadcast(pkg, - UserHandle.getUserId(uid)); - } - } - } - break; default: // nope, just ignore it break; diff --git a/core/api/test-current.txt b/core/api/test-current.txt index e7e4bccb95db..4669ee1b25af 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -314,7 +314,6 @@ package android.app { public final class NotificationChannel implements android.os.Parcelable { method public int getOriginalImportance(); method public boolean isImportanceLockedByCriticalDeviceFunction(); - method public boolean isImportanceLockedByOEM(); method public void lockFields(int); method public void setDeleted(boolean); method public void setDeletedTimeMs(long); diff --git a/core/java/Android.bp b/core/java/Android.bp index f081a439c49c..7f9485b6ea45 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -15,6 +15,14 @@ filegroup { "**/*.java", "**/*.aidl", ], + exclude_srcs: [ + // Remove election toolbar code from build time + "android/service/selectiontoolbar/*.aidl", + "android/service/selectiontoolbar/*.java", + "android/view/selectiontoolbar/*.aidl", + "android/view/selectiontoolbar/*.java", + "com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java", + ], visibility: ["//frameworks/base"], } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index abd60177f884..5d1d225f4d2d 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -4617,8 +4617,8 @@ public class ActivityManager { try { getService().broadcastIntentWithFeature( null, null, intent, null, null, Activity.RESULT_OK, null, null, - null /*requiredPermissions*/, null /*excludedPermissions*/, appOp, null, false, - true, userId); + null /*requiredPermissions*/, null /*excludedPermissions*/, + null /*excludedPackages*/, appOp, null, false, true, userId); } catch (RemoteException ex) { } } diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 49a5c9f78230..f2ea060b1694 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -568,14 +568,15 @@ public abstract class ActivityManagerInternal { public abstract void unregisterProcessObserver(IProcessObserver processObserver); /** - * Checks if there is an unfinished instrumentation that targets the given uid. + * Gets the uid of the instrumentation source if there is an unfinished instrumentation that + * targets the given uid. * * @param uid The uid to be checked for * - * @return True, if there is an instrumentation whose target application uid matches the given - * uid, false otherwise + * @return the uid of the instrumentation source, if there is an instrumentation whose target + * application uid matches the given uid, and {@link android.os.Process#INVALID_UID} otherwise. */ - public abstract boolean isUidCurrentlyInstrumented(int uid); + public abstract int getInstrumentationSourceUid(int uid); /** Is this a device owner app? */ public abstract boolean isDeviceOwner(int uid); diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 3b1943bf86f6..a216021fc66b 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1335,9 +1335,17 @@ public class AppOpsManager { public static final int OP_ACCESS_RESTRICTED_SETTINGS = AppProtoEnums.APP_OP_ACCESS_RESTRICTED_SETTINGS; + /** + * Receive microphone audio from an ambient sound detection event + * + * @hide + */ + public static final int OP_RECEIVE_AMBIENT_TRIGGER_AUDIO = + AppProtoEnums.APP_OP_RECEIVE_AMBIENT_TRIGGER_AUDIO; + /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final int _NUM_OP = 120; + public static final int _NUM_OP = 121; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -1800,6 +1808,14 @@ public class AppOpsManager { public static final String OPSTR_ACCESS_RESTRICTED_SETTINGS = "android:access_restricted_settings"; + /** + * Receive microphone audio from an ambient sound detection event + * + * @hide + */ + public static final String OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO = + "android:receive_ambient_trigger_audio"; + /** {@link #sAppOpsToNote} not initialized yet for this op */ private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0; /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */ @@ -2021,6 +2037,7 @@ public class AppOpsManager { OP_ESTABLISH_VPN_SERVICE, // OP_ESTABLISH_VPN_SERVICE OP_ESTABLISH_VPN_MANAGER, // OP_ESTABLISH_VPN_MANAGER OP_ACCESS_RESTRICTED_SETTINGS, // OP_ACCESS_RESTRICTED_SETTINGS + OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, // RECEIVE_SOUNDTRIGGER_AUDIO }; /** @@ -2147,6 +2164,7 @@ public class AppOpsManager { OPSTR_ESTABLISH_VPN_SERVICE, OPSTR_ESTABLISH_VPN_MANAGER, OPSTR_ACCESS_RESTRICTED_SETTINGS, + OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO, }; /** @@ -2274,6 +2292,7 @@ public class AppOpsManager { "ESTABLISH_VPN_SERVICE", "ESTABLISH_VPN_MANAGER", "ACCESS_RESTRICTED_SETTINGS", + "RECEIVE_SOUNDTRIGGER_AUDIO", }; /** @@ -2402,6 +2421,7 @@ public class AppOpsManager { null, // no permission for OP_ESTABLISH_VPN_SERVICE null, // no permission for OP_ESTABLISH_VPN_MANAGER null, // no permission for OP_ACCESS_RESTRICTED_SETTINGS, + null, // no permission for OP_RECEIVE_SOUNDTRIGGER_AUDIO }; /** @@ -2529,7 +2549,8 @@ public class AppOpsManager { null, // NEARBY_WIFI_DEVICES null, // ESTABLISH_VPN_SERVICE null, // ESTABLISH_VPN_MANAGER - null, // ACCESS_RESTRICTED_SETTINGS, + null, // ACCESS_RESTRICTED_SETTINGS + null, // RECEIVE_SOUNDTRIGGER_AUDIO }; /** @@ -2656,7 +2677,8 @@ public class AppOpsManager { null, // NEARBY_WIFI_DEVICES null, // ESTABLISH_VPN_SERVICE null, // ESTABLISH_VPN_MANAGER - null, // ACCESS_RESTRICTED_SETTINGS, + null, // ACCESS_RESTRICTED_SETTINGS + null, // RECEIVE_SOUNDTRIGGER_AUDIO }; /** @@ -2765,7 +2787,7 @@ public class AppOpsManager { AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE AppOpsManager.MODE_ALLOWED, // PHONE_CALL_MICROPHONE AppOpsManager.MODE_ALLOWED, // PHONE_CALL_CAMERA - AppOpsManager.MODE_ALLOWED, // OP_RECORD_AUDIO_HOTWORD + AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO_HOTWORD AppOpsManager.MODE_DEFAULT, // MANAGE_ONGOING_CALLS AppOpsManager.MODE_DEFAULT, // MANAGE_CREDENTIALS AppOpsManager.MODE_DEFAULT, // USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER @@ -2783,6 +2805,7 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_SERVICE AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_MANAGER AppOpsManager.MODE_ALLOWED, // ACCESS_RESTRICTED_SETTINGS, + AppOpsManager.MODE_ALLOWED, // RECEIVE_SOUNDTRIGGER_AUDIO }; /** @@ -2913,6 +2936,7 @@ public class AppOpsManager { false, // OP_ESTABLISH_VPN_SERVICE false, // OP_ESTABLISH_VPN_MANAGER true, // ACCESS_RESTRICTED_SETTINGS + false, // RECEIVE_SOUNDTRIGGER_AUDIO }; /** @@ -3040,6 +3064,7 @@ public class AppOpsManager { false, // OP_ESTABLISH_VPN_SERVICE false, // OP_ESTABLISH_VPN_MANAGER true, // ACCESS_RESTRICTED_SETTINGS + false, // RECEIVE_SOUNDTRIGGER_AUDIO }; /** diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index ac46066997ff..6d982ced385c 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1193,7 +1193,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, - AppOpsManager.OP_NONE, null, false, false, getUserId()); + null, AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1210,7 +1210,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false, + null /*excludedPermissions=*/, null, AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1226,7 +1226,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false, + null /*excludedPermissions=*/, null, AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1243,8 +1243,8 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false, - getUserId()); + null /*excludedPermissions=*/, null /*excludedPackages*/, + AppOpsManager.OP_NONE, options, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1259,7 +1259,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false, + null /*excludedPermissions=*/, null, AppOpsManager.OP_NONE, null, false, false, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1268,7 +1268,7 @@ class ContextImpl extends Context { @Override public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, - String[] excludedPermissions) { + String[] excludedPermissions, String[] excludedPackages) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); try { @@ -1276,7 +1276,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, excludedPermissions, - AppOpsManager.OP_NONE, null, false, false, getUserId()); + excludedPackages, AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1303,7 +1303,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - excludedPermissions, AppOpsManager.OP_NONE, options, false, false, + excludedPermissions, null, AppOpsManager.OP_NONE, options, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1321,7 +1321,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - null /*excludedPermissions=*/, appOp, null, false, false, getUserId()); + null /*excludedPermissions=*/, null, appOp, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1338,7 +1338,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, false, + null /*excludedPermissions=*/, null, AppOpsManager.OP_NONE, null, true, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1402,7 +1402,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, rd, initialCode, initialData, initialExtras, receiverPermissions, - null /*excludedPermissions=*/, appOp, options, true, false, getUserId()); + null /*excludedPermissions=*/, null, appOp, options, true, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1416,7 +1416,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, - AppOpsManager.OP_NONE, null, false, false, user.getIdentifier()); + null, AppOpsManager.OP_NONE, null, false, false, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1439,8 +1439,8 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false, - user.getIdentifier()); + null /*excludedPermissions=*/, null, AppOpsManager.OP_NONE, options, false, + false, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1457,7 +1457,8 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, - null /*excludedPermissions=*/, appOp, null, false, false, user.getIdentifier()); + null /*excludedPermissions=*/, null, appOp, null, false, false, + user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1508,7 +1509,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, rd, initialCode, initialData, initialExtras, receiverPermissions, - null /*excludedPermissions=*/, appOp, options, true, false, + null /*excludedPermissions=*/, null, appOp, options, true, false, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1550,7 +1551,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, - AppOpsManager.OP_NONE, null, false, true, getUserId()); + null, AppOpsManager.OP_NONE, null, false, true, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1589,7 +1590,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, - AppOpsManager.OP_NONE, options, false, true, getUserId()); + null, AppOpsManager.OP_NONE, options, false, true, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1625,7 +1626,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, true, + null /*excludedPermissions=*/, null, AppOpsManager.OP_NONE, null, true, true, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1658,7 +1659,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, - AppOpsManager.OP_NONE, null, false, true, user.getIdentifier()); + null, AppOpsManager.OP_NONE, null, false, true, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1673,7 +1674,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, - AppOpsManager.OP_NONE, options, false, true, user.getIdentifier()); + null, AppOpsManager.OP_NONE, options, false, true, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1708,7 +1709,7 @@ class ContextImpl extends Context { ActivityManager.getService().broadcastIntentWithFeature( mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, true, + null /*excludedPermissions=*/, null, AppOpsManager.OP_NONE, null, true, true, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 4efe9dfe7185..8367441b1b95 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -141,7 +141,7 @@ interface IActivityManager { int broadcastIntentWithFeature(in IApplicationThread caller, in String callingFeatureId, in Intent intent, in String resolvedType, in IIntentReceiver resultTo, int resultCode, in String resultData, in Bundle map, in String[] requiredPermissions, in String[] excludePermissions, - int appOp, in Bundle options, boolean serialized, boolean sticky, int userId); + in String[] excludePackages, int appOp, in Bundle options, boolean serialized, boolean sticky, int userId); void unbroadcastIntent(in IApplicationThread caller, in Intent intent, int userId); @UnsupportedAppUsage oneway void finishReceiver(in IBinder who, int resultCode, in String resultData, in Bundle map, diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index 99d7c63cde42..8984c4292023 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1058,10 +1058,11 @@ public class Instrumentation { } /** - * Sends the key events corresponding to the text to the app being - * instrumented. - * - * @param text The text to be sent. + * Sends the key events that result in the given text being typed into the currently focused + * window, and waits for it to be processed. + * + * @param text The text to be sent. + * @see #sendKeySync(KeyEvent) */ public void sendStringSync(String text) { if (text == null) { @@ -1084,11 +1085,12 @@ public class Instrumentation { } /** - * Send a key event to the currently focused window/view and wait for it to - * be processed. Finished at some point after the recipient has returned - * from its event processing, though it may <em>not</em> have completely - * finished reacting from the event -- for example, if it needs to update - * its display as a result, it may still be in the process of doing that. + * Sends a key event to the currently focused window, and waits for it to be processed. + * <p> + * This method blocks until the recipient has finished handling the event. Note that the + * recipient may <em>not</em> have completely finished reacting from the event when this method + * returns. For example, it may still be in the process of updating its display or UI contents + * upon reacting to the injected event. * * @param event The event to send to the current focus. */ @@ -1116,34 +1118,42 @@ public class Instrumentation { } /** - * Sends an up and down key event sync to the currently focused window. + * Sends up and down key events with the given key code to the currently focused window, and + * waits for it to be processed. * - * @param key The integer keycode for the event. + * @param keyCode The key code for the events to send. + * @see #sendKeySync(KeyEvent) */ - public void sendKeyDownUpSync(int key) { - sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, key)); - sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, key)); + public void sendKeyDownUpSync(int keyCode) { + sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode)); + sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, keyCode)); } /** - * Higher-level method for sending both the down and up key events for a - * particular character key code. Equivalent to creating both KeyEvent - * objects by hand and calling {@link #sendKeySync}. The event appears - * as if it came from keyboard 0, the built in one. - * + * Sends up and down key events with the given key code to the currently focused window, and + * waits for it to be processed. + * <p> + * Equivalent to {@link #sendKeyDownUpSync(int)}. + * * @param keyCode The key code of the character to send. + * @see #sendKeySync(KeyEvent) */ public void sendCharacterSync(int keyCode) { - sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode)); - sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, keyCode)); + sendKeyDownUpSync(keyCode); } - + /** - * Dispatch a pointer event. Finished at some point after the recipient has - * returned from its event processing, though it may <em>not</em> have - * completely finished reacting from the event -- for example, if it needs - * to update its display as a result, it may still be in the process of - * doing that. + * Dispatches a pointer event into a window owned by the instrumented application, and waits for + * it to be processed. + * <p> + * If the motion event being injected is targeted at a window that is not owned by the + * instrumented application, the input injection will fail. See {@link #getUiAutomation()} for + * injecting events into all windows. + * <p> + * This method blocks until the recipient has finished handling the event. Note that the + * recipient may <em>not</em> have completely finished reacting from the event when this method + * returns. For example, it may still be in the process of updating its display or UI contents + * upon reacting to the injected event. * * @param event A motion event describing the pointer action. (As noted in * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use @@ -1155,10 +1165,10 @@ public class Instrumentation { event.setSource(InputDevice.SOURCE_TOUCHSCREEN); } - syncInputTransactionsAndInjectEvent(event); + syncInputTransactionsAndInjectEventIntoSelf(event); } - private void syncInputTransactionsAndInjectEvent(MotionEvent event) { + private void syncInputTransactionsAndInjectEventIntoSelf(MotionEvent event) { final boolean syncBefore = event.getAction() == MotionEvent.ACTION_DOWN || event.isFromSource(InputDevice.SOURCE_MOUSE); final boolean syncAfter = event.getAction() == MotionEvent.ACTION_UP; @@ -1169,8 +1179,9 @@ public class Instrumentation { .syncInputTransactions(true /*waitForAnimations*/); } + // Direct the injected event into windows owned by the instrumentation target. InputManager.getInstance().injectInputEvent( - event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); + event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH, Process.myUid()); if (syncAfter) { WindowManagerGlobal.getWindowManagerService() @@ -1182,19 +1193,21 @@ public class Instrumentation { } /** - * Dispatch a trackball event. Finished at some point after the recipient has - * returned from its event processing, though it may <em>not</em> have - * completely finished reacting from the event -- for example, if it needs - * to update its display as a result, it may still be in the process of - * doing that. - * + * Dispatches a trackball event into the currently focused window, and waits for it to be + * processed. + * <p> + * This method blocks until the recipient has finished handling the event. Note that the + * recipient may <em>not</em> have completely finished reacting from the event when this method + * returns. For example, it may still be in the process of updating its display or UI contents + * upon reacting to the injected event. + * * @param event A motion event describing the trackball action. (As noted in * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use * {@link SystemClock#uptimeMillis()} as the timebase. */ public void sendTrackballEventSync(MotionEvent event) { validateNotAppThread(); - if ((event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) { + if (!event.isFromSource(InputDevice.SOURCE_CLASS_TRACKBALL)) { event.setSource(InputDevice.SOURCE_TRACKBALL); } InputManager.getInstance().injectInputEvent(event, diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java index 91ab19b9e44a..6f0b03aeb6f3 100644 --- a/core/java/android/app/NotificationChannel.java +++ b/core/java/android/app/NotificationChannel.java @@ -867,14 +867,6 @@ public final class NotificationChannel implements Parcelable { * @hide */ @TestApi - public boolean isImportanceLockedByOEM() { - return mImportanceLockedByOEM; - } - - /** - * @hide - */ - @TestApi public boolean isImportanceLockedByCriticalDeviceFunction() { return mImportanceLockedDefaultApp; } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 6615374f71ec..40192836e0a7 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -230,8 +230,6 @@ import android.view.contentcapture.ContentCaptureManager; import android.view.contentcapture.IContentCaptureManager; import android.view.displayhash.DisplayHashManager; import android.view.inputmethod.InputMethodManager; -import android.view.selectiontoolbar.ISelectionToolbarManager; -import android.view.selectiontoolbar.SelectionToolbarManager; import android.view.textclassifier.TextClassificationManager; import android.view.textservice.TextServicesManager; import android.view.translation.ITranslationManager; @@ -365,15 +363,6 @@ public final class SystemServiceRegistry { return new TextClassificationManager(ctx); }}); - registerService(Context.SELECTION_TOOLBAR_SERVICE, SelectionToolbarManager.class, - new CachedServiceFetcher<SelectionToolbarManager>() { - @Override - public SelectionToolbarManager createService(ContextImpl ctx) { - IBinder b = ServiceManager.getService(Context.SELECTION_TOOLBAR_SERVICE); - return new SelectionToolbarManager(ctx.getOuterContext(), - ISelectionToolbarManager.Stub.asInterface(b)); - }}); - registerService(Context.FONT_SERVICE, FontManager.class, new CachedServiceFetcher<FontManager>() { @Override diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 0a2b42121545..63cdfe60d40b 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -14569,12 +14569,13 @@ public class DevicePolicyManager { } /** - * Called by Device owner to disable user control over apps. User will not be able to clear - * app data or force-stop packages. + * Called by a device owner or a profile owner to disable user control over apps. User will not + * be able to clear app data or force-stop packages. When called by a device owner, applies to + * all users on the device. * * @param admin which {@link DeviceAdminReceiver} this request is associated with * @param packages The package names for the apps. - * @throws SecurityException if {@code admin} is not a device owner. + * @throws SecurityException if {@code admin} is not a device owner or a profile owner. */ public void setUserControlDisabledPackages(@NonNull ComponentName admin, @NonNull List<String> packages) { @@ -14589,12 +14590,14 @@ public class DevicePolicyManager { } /** - * Returns the list of packages over which user control is disabled by the device owner. + * Returns the list of packages over which user control is disabled by a device or profile + * owner. * * @param admin which {@link DeviceAdminReceiver} this request is associated with - * @throws SecurityException if {@code admin} is not a device owner. + * @throws SecurityException if {@code admin} is not a device or profile owner. */ - public @NonNull List<String> getUserControlDisabledPackages(@NonNull ComponentName admin) { + @NonNull + public List<String> getUserControlDisabledPackages(@NonNull ComponentName admin) { throwIfParentInstance("getUserControlDisabledPackages"); if (mService != null) { try { diff --git a/core/java/android/app/admin/DevicePolicyResources.java b/core/java/android/app/admin/DevicePolicyResources.java index c8033fafbc4e..5044245166a3 100644 --- a/core/java/android/app/admin/DevicePolicyResources.java +++ b/core/java/android/app/admin/DevicePolicyResources.java @@ -184,6 +184,12 @@ public final class DevicePolicyResources { PREFIX + "WORK_PROFILE_IT_ADMIN_CANT_RESET_SCREEN_LOCK"; /** + * Text shown on the CTA link shown to user to set a separate lock for work apps + */ + public static final String WORK_PROFILE_IT_ADMIN_CANT_RESET_SCREEN_LOCK_ACTION = + PREFIX + "WORK_PROFILE_IT_ADMIN_CANT_RESET_SCREEN_LOCK_ACTION"; + + /** * Message shown in screen lock picker for setting up a work profile screen lock */ public static final String WORK_PROFILE_SCREEN_LOCK_SETUP_MESSAGE = diff --git a/core/java/android/app/admin/PasswordMetrics.java b/core/java/android/app/admin/PasswordMetrics.java index 4c1a36340d5d..ab48791d43ef 100644 --- a/core/java/android/app/admin/PasswordMetrics.java +++ b/core/java/android/app/admin/PasswordMetrics.java @@ -41,6 +41,7 @@ import static com.android.internal.widget.PasswordValidationError.NOT_ENOUGH_SYM import static com.android.internal.widget.PasswordValidationError.NOT_ENOUGH_UPPER_CASE; import static com.android.internal.widget.PasswordValidationError.TOO_LONG; import static com.android.internal.widget.PasswordValidationError.TOO_SHORT; +import static com.android.internal.widget.PasswordValidationError.TOO_SHORT_WHEN_ALL_NUMERIC; import static com.android.internal.widget.PasswordValidationError.WEAK_CREDENTIAL_TYPE; import android.annotation.IntDef; @@ -569,21 +570,15 @@ public final class PasswordMetrics implements Parcelable { result.add(new PasswordValidationError(TOO_LONG, MAX_PASSWORD_LENGTH)); } - // A flag indicating whether the provided password already has non-numeric characters in - // it or if the admin imposes the requirement of any non-numeric characters. - final boolean hasOrWouldNeedNonNumeric = - actualMetrics.nonNumeric > 0 || adminMetrics.nonNumeric > 0 - || adminMetrics.letters > 0 || adminMetrics.lowerCase > 0 - || adminMetrics.upperCase > 0 || adminMetrics.symbols > 0; - final PasswordMetrics minMetrics = - applyComplexity(adminMetrics, hasOrWouldNeedNonNumeric, bucket); + final PasswordMetrics minMetrics = applyComplexity(adminMetrics, + actualMetrics.credType == CREDENTIAL_TYPE_PIN, bucket); // Clamp required length between maximum and minimum valid values. minMetrics.length = Math.min(MAX_PASSWORD_LENGTH, Math.max(minMetrics.length, MIN_LOCK_PASSWORD_SIZE)); minMetrics.removeOverlapping(); - comparePasswordMetrics(minMetrics, actualMetrics, result); + comparePasswordMetrics(minMetrics, bucket, actualMetrics, result); return result; } @@ -591,11 +586,23 @@ public final class PasswordMetrics implements Parcelable { /** * TODO: move to PasswordPolicy */ - private static void comparePasswordMetrics(PasswordMetrics minMetrics, + private static void comparePasswordMetrics(PasswordMetrics minMetrics, ComplexityBucket bucket, PasswordMetrics actualMetrics, ArrayList<PasswordValidationError> result) { if (actualMetrics.length < minMetrics.length) { result.add(new PasswordValidationError(TOO_SHORT, minMetrics.length)); } + if (actualMetrics.nonNumeric == 0 && minMetrics.nonNumeric == 0 && minMetrics.letters == 0 + && minMetrics.lowerCase == 0 && minMetrics.upperCase == 0 + && minMetrics.symbols == 0) { + // When provided password is all numeric and all numeric password is allowed. + int allNumericMinimumLength = bucket.getMinimumLength(false); + if (allNumericMinimumLength > minMetrics.length + && allNumericMinimumLength > minMetrics.numeric + && actualMetrics.length < allNumericMinimumLength) { + result.add(new PasswordValidationError( + TOO_SHORT_WHEN_ALL_NUMERIC, allNumericMinimumLength)); + } + } if (actualMetrics.letters < minMetrics.letters) { result.add(new PasswordValidationError(NOT_ENOUGH_LETTERS, minMetrics.letters)); } @@ -668,15 +675,12 @@ public final class PasswordMetrics implements Parcelable { * * TODO: move to PasswordPolicy */ - public static PasswordMetrics applyComplexity( - PasswordMetrics adminMetrics, boolean withNonNumericCharacters, + public static PasswordMetrics applyComplexity(PasswordMetrics adminMetrics, boolean isPin, int complexity) { - return applyComplexity(adminMetrics, withNonNumericCharacters, - ComplexityBucket.forComplexity(complexity)); + return applyComplexity(adminMetrics, isPin, ComplexityBucket.forComplexity(complexity)); } - private static PasswordMetrics applyComplexity( - PasswordMetrics adminMetrics, boolean withNonNumericCharacters, + private static PasswordMetrics applyComplexity(PasswordMetrics adminMetrics, boolean isPin, ComplexityBucket bucket) { final PasswordMetrics minMetrics = new PasswordMetrics(adminMetrics); @@ -684,8 +688,7 @@ public final class PasswordMetrics implements Parcelable { minMetrics.seqLength = Math.min(minMetrics.seqLength, MAX_ALLOWED_SEQUENCE); } - minMetrics.length = Math.max(minMetrics.length, - bucket.getMinimumLength(withNonNumericCharacters)); + minMetrics.length = Math.max(minMetrics.length, bucket.getMinimumLength(!isPin)); return minMetrics; } diff --git a/core/java/android/app/admin/ProvisioningIntentHelper.java b/core/java/android/app/admin/ProvisioningIntentHelper.java index fbad90c30d7e..1c38559a4083 100644 --- a/core/java/android/app/admin/ProvisioningIntentHelper.java +++ b/core/java/android/app/admin/ProvisioningIntentHelper.java @@ -17,8 +17,10 @@ package android.app.admin; import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE; +import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE; import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME; import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME; +import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ROLE_HOLDER_EXTRAS_BUNDLE; import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TRIGGER; import static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC; import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_NFC; @@ -36,12 +38,14 @@ import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.os.Bundle; import android.os.Parcelable; +import android.os.PersistableBundle; import android.util.Log; import java.io.IOException; import java.io.StringReader; import java.util.Enumeration; import java.util.Properties; +import java.util.Set; /** * Utility class that provides functionality to create provisioning intents from nfc intents. @@ -124,12 +128,46 @@ final class ProvisioningIntentHelper { ComponentName componentName = ComponentName.unflattenFromString( properties.getProperty(propertyName)); bundle.putParcelable(propertyName, componentName); + } else if (EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE.equals(propertyName) + || EXTRA_PROVISIONING_ROLE_HOLDER_EXTRAS_BUNDLE.equals(propertyName)) { + try { + bundle.putParcelable(propertyName, + deserializeExtrasBundle(properties, propertyName)); + } catch (IOException e) { + Log.e(TAG, + "Failed to parse " + propertyName + ".", e); + } } else { bundle.putString(propertyName, properties.getProperty(propertyName)); } } + /** + * Get a {@link PersistableBundle} from a {@code String} property in a {@link Properties} + * object. + * @param properties the source of the extra + * @param extraName key into the {@link Properties} object + * @return the {@link PersistableBundle} or {@code null} if there was no property with the + * given name + * @throws IOException if there was an error parsing the property + */ + private static PersistableBundle deserializeExtrasBundle( + Properties properties, String extraName) throws IOException { + String serializedExtras = properties.getProperty(extraName); + if (serializedExtras == null) { + return null; + } + Properties bundleProperties = new Properties(); + bundleProperties.load(new StringReader(serializedExtras)); + PersistableBundle extrasBundle = new PersistableBundle(bundleProperties.size()); + Set<String> propertyNames = bundleProperties.stringPropertyNames(); + for (String propertyName : propertyNames) { + extrasBundle.putString(propertyName, bundleProperties.getProperty(propertyName)); + } + return extrasBundle; + } + private static Intent createProvisioningIntentFromBundle(Bundle bundle) { requireNonNull(bundle); diff --git a/core/java/android/app/smartspace/SmartspaceTarget.java b/core/java/android/app/smartspace/SmartspaceTarget.java index be077435b080..79d7b216628f 100644 --- a/core/java/android/app/smartspace/SmartspaceTarget.java +++ b/core/java/android/app/smartspace/SmartspaceTarget.java @@ -174,7 +174,7 @@ public final class SmartspaceTarget implements Parcelable { public static final int FEATURE_MEDIA_HEADS_UP = 36; public static final int FEATURE_STEP_COUNTING = 37; public static final int FEATURE_EARTHQUAKE_ALERT = 38; - public static final int FEATURE_STEP_DATE = 39; + public static final int FEATURE_STEP_DATE = 39; // This represents a DATE. "STEP" is a typo. public static final int FEATURE_BLAZE_BUILD_PROGRESS = 40; public static final int FEATURE_EARTHQUAKE_OCCURRED = 41; @@ -283,7 +283,7 @@ public final class SmartspaceTarget implements Parcelable { this.mAssociatedSmartspaceTargetId = in.readString(); this.mSliceUri = in.readTypedObject(Uri.CREATOR); this.mWidget = in.readTypedObject(AppWidgetProviderInfo.CREATOR); - this.mTemplateData = in.readTypedObject(BaseTemplateData.CREATOR); + this.mTemplateData = in.readParcelable(/* loader= */null, BaseTemplateData.class); } private SmartspaceTarget(String smartspaceTargetId, @@ -491,7 +491,7 @@ public final class SmartspaceTarget implements Parcelable { dest.writeString(this.mAssociatedSmartspaceTargetId); dest.writeTypedObject(this.mSliceUri, flags); dest.writeTypedObject(this.mWidget, flags); - dest.writeTypedObject(this.mTemplateData, flags); + dest.writeParcelable(this.mTemplateData, flags); } @Override diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 907db7df68d5..836bff598ede 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2269,6 +2269,19 @@ public abstract class Context { */ public void sendBroadcastMultiplePermissions(@NonNull Intent intent, @NonNull String[] receiverPermissions, @Nullable String[] excludedPermissions) { + sendBroadcastMultiplePermissions(intent, receiverPermissions, excludedPermissions, null); + } + + + /** + * Like {@link #sendBroadcastMultiplePermissions(Intent, String[], String[])}, but also allows + * specification of a list of excluded packages. + * + * @hide + */ + public void sendBroadcastMultiplePermissions(@NonNull Intent intent, + @NonNull String[] receiverPermissions, @Nullable String[] excludedPermissions, + @Nullable String[] excludedPackages) { throw new RuntimeException("Not implemented. Must override in a subclass."); } diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 4ecd7761ac4f..e6549187e5c5 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -515,8 +515,10 @@ public class ContextWrapper extends Context { /** @hide */ @Override public void sendBroadcastMultiplePermissions(@NonNull Intent intent, - @NonNull String[] receiverPermissions, @Nullable String[] excludedPermissions) { - mBase.sendBroadcastMultiplePermissions(intent, receiverPermissions, excludedPermissions); + @NonNull String[] receiverPermissions, @Nullable String[] excludedPermissions, + @Nullable String[] excludedPackages) { + mBase.sendBroadcastMultiplePermissions(intent, receiverPermissions, excludedPermissions, + excludedPackages); } /** @hide */ diff --git a/core/java/android/content/pm/AppSearchShortcutInfo.java b/core/java/android/content/pm/AppSearchShortcutInfo.java index 1b84686bbfcf..fb41b890ce9c 100644 --- a/core/java/android/content/pm/AppSearchShortcutInfo.java +++ b/core/java/android/content/pm/AppSearchShortcutInfo.java @@ -413,7 +413,10 @@ public class AppSearchShortcutInfo extends GenericDocument { final int iconResId = (int) getPropertyLong(KEY_ICON_RES_ID); final String iconResName = getPropertyString(KEY_ICON_RES_NAME); final String iconUri = getPropertyString(KEY_ICON_URI); - final int disabledReason = Integer.parseInt(getPropertyString(KEY_DISABLED_REASON)); + final String disabledReasonString = getPropertyString(KEY_DISABLED_REASON); + final int disabledReason = !TextUtils.isEmpty(disabledReasonString) + ? Integer.parseInt(getPropertyString(KEY_DISABLED_REASON)) + : ShortcutInfo.DISABLED_REASON_NOT_DISABLED; final Map<String, Map<String, List<String>>> capabilityBindings = parseCapabilityBindings(getPropertyStringArray(KEY_CAPABILITY_BINDINGS)); return new ShortcutInfo( diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java index cb55e303e778..20a4fdf658c6 100644 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java @@ -567,9 +567,14 @@ public class ApkLiteParseUtils { targetCode = minCode; } + boolean allowUnknownCodenames = false; + if ((flags & FrameworkParsingPackageUtils.PARSE_APK_IN_APEX) != 0) { + allowUnknownCodenames = true; + } + ParseResult<Integer> targetResult = FrameworkParsingPackageUtils.computeTargetSdkVersion( targetVer, targetCode, SDK_CODENAMES, input, - /* allowUnknownCodenames= */ false); + allowUnknownCodenames); if (targetResult.isError()) { return input.error(targetResult); } diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java index bde71bb90bf7..8cc4cdb955ca 100644 --- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java @@ -58,6 +58,7 @@ public class FrameworkParsingPackageUtils { private static final int MAX_FILE_NAME_SIZE = 223; public static final int PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY = 1 << 7; + public static final int PARSE_APK_IN_APEX = 1 << 9; /** * Check if the given name is valid. diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index 5dbe9bff328e..5b1973ad2dd4 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -1241,8 +1241,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * {@link #onCaptureStarted}. Unlike {@link #onCaptureStarted}, instead of passing * a timestamp of start of exposure, this callback passes a timestamp of start of * camera data readout. This is useful because for a camera running at fixed frame - * rate, the start of readout is at fixed interval, but not necessary for the start - * of exposure.</p> + * rate, the start of readout is at fixed interval, which is not necessarily true for + * the start of exposure, particularly when autoexposure is changing exposure duration + * between frames.</p> * * <p>This timestamp may not match {@link CaptureResult#SENSOR_TIMESTAMP the result * timestamp field}. It will, however, match the timestamp of buffers sent to the diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index 06edf66f4ea5..7092e43596ec 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -1369,13 +1369,17 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan case FACE_ACQUIRED_TOO_FAR: return context.getString(R.string.face_acquired_too_far); case FACE_ACQUIRED_TOO_HIGH: - return context.getString(R.string.face_acquired_too_high); - case FACE_ACQUIRED_TOO_LOW: + // TODO(b/181269243) Change back once error codes are fixed. return context.getString(R.string.face_acquired_too_low); + case FACE_ACQUIRED_TOO_LOW: + // TODO(b/181269243) Change back once error codes are fixed. + return context.getString(R.string.face_acquired_too_high); case FACE_ACQUIRED_TOO_RIGHT: - return context.getString(R.string.face_acquired_too_right); - case FACE_ACQUIRED_TOO_LEFT: + // TODO(b/181269243) Change back once error codes are fixed. return context.getString(R.string.face_acquired_too_left); + case FACE_ACQUIRED_TOO_LEFT: + // TODO(b/181269243) Change back once error codes are fixed. + return context.getString(R.string.face_acquired_too_right); case FACE_ACQUIRED_POOR_GAZE: return context.getString(R.string.face_acquired_poor_gaze); case FACE_ACQUIRED_PAN_TOO_EXTREME: diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index e1ffd4a6761d..2da12e6c5c9d 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -57,11 +57,16 @@ interface IInputManager { // Temporarily changes the pointer speed. void tryPointerSpeed(int speed); - // Injects an input event into the system. To inject into windows owned by other - // applications, the caller must have the INJECT_EVENTS permission. + // Injects an input event into the system. The caller must have the INJECT_EVENTS permssion. + // This method exists only for compatibility purposes and may be removed in a future release. @UnsupportedAppUsage boolean injectInputEvent(in InputEvent ev, int mode); + // Injects an input event into the system. The caller must have the INJECT_EVENTS permission. + // The caller can target windows owned by a certain UID by providing a valid UID, or by + // providing {@link android.os.Process#INVALID_UID} to target all windows. + boolean injectInputEventToTarget(in InputEvent ev, int mode, int targetUid); + VerifiedInputEvent verifyInputEvent(in InputEvent ev); // Calibrate input device position diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index cc5b275bbf5a..d17a9523ab37 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -45,6 +45,7 @@ import android.os.IVibratorStateListener; import android.os.InputEventInjectionSync; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; @@ -1107,14 +1108,18 @@ public final class InputManager { } } - /** - * Injects an input event into the event system on behalf of an application. + * Injects an input event into the event system, targeting windows owned by the provided uid. + * + * If a valid targetUid is provided, the system will only consider injecting the input event + * into windows owned by the provided uid. If the input event is targeted at a window that is + * not owned by the provided uid, input injection will fail and a RemoteException will be + * thrown. + * * The synchronization mode determines whether the method blocks while waiting for * input injection to proceed. * <p> - * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into - * windows that are owned by other applications. + * Requires the {@link android.Manifest.permission.INJECT_EVENTS} permission. * </p><p> * Make sure you correctly set the event time and input source of the event * before calling this method. @@ -1125,12 +1130,14 @@ public final class InputManager { * {@link android.os.InputEventInjectionSync.NONE}, * {@link android.os.InputEventInjectionSync.WAIT_FOR_RESULT}, or * {@link android.os.InputEventInjectionSync.WAIT_FOR_FINISHED}. + * @param targetUid The uid to target, or {@link android.os.Process#INVALID_UID} to target all + * windows. * @return True if input event injection succeeded. * * @hide */ - @UnsupportedAppUsage - public boolean injectInputEvent(InputEvent event, int mode) { + @RequiresPermission(Manifest.permission.INJECT_EVENTS) + public boolean injectInputEvent(InputEvent event, int mode, int targetUid) { if (event == null) { throw new IllegalArgumentException("event must not be null"); } @@ -1141,13 +1148,39 @@ public final class InputManager { } try { - return mIm.injectInputEvent(event, mode); + return mIm.injectInputEventToTarget(event, mode, targetUid); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } /** + * Injects an input event into the event system on behalf of an application. + * The synchronization mode determines whether the method blocks while waiting for + * input injection to proceed. + * <p> + * Requires the {@link android.Manifest.permission.INJECT_EVENTS} permission. + * </p><p> + * Make sure you correctly set the event time and input source of the event + * before calling this method. + * </p> + * + * @param event The event to inject. + * @param mode The synchronization mode. One of: + * {@link android.os.InputEventInjectionSync.NONE}, + * {@link android.os.InputEventInjectionSync.WAIT_FOR_RESULT}, or + * {@link android.os.InputEventInjectionSync.WAIT_FOR_FINISHED}. + * @return True if input event injection succeeded. + * + * @hide + */ + @RequiresPermission(Manifest.permission.INJECT_EVENTS) + @UnsupportedAppUsage + public boolean injectInputEvent(InputEvent event, int mode) { + return injectInputEvent(event, mode, Process.INVALID_UID); + } + + /** * Verify the details of an {@link android.view.InputEvent} that came from the system. * If the event did not come from the system, or its details could not be verified, then this * will return {@code null}. Receiving {@code null} does not mean that the event did not diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java index 3c2c7f03761b..b494c7f4026a 100644 --- a/core/java/android/permission/PermissionControllerManager.java +++ b/core/java/android/permission/PermissionControllerManager.java @@ -860,7 +860,7 @@ public final class PermissionControllerManager { Binder.restoreCallingIdentity(token); } } - }); + }, executor); } /** diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java index 4ed939c48bd7..f5f1c374b636 100644 --- a/core/java/android/permission/PermissionUsageHelper.java +++ b/core/java/android/permission/PermissionUsageHelper.java @@ -30,6 +30,7 @@ import static android.app.AppOpsManager.OPSTR_COARSE_LOCATION; import static android.app.AppOpsManager.OPSTR_FINE_LOCATION; import static android.app.AppOpsManager.OPSTR_PHONE_CALL_CAMERA; import static android.app.AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE; +import static android.app.AppOpsManager.OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO; import static android.app.AppOpsManager.OPSTR_RECORD_AUDIO; import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED; @@ -137,6 +138,7 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis private static final List<String> MIC_OPS = List.of( OPSTR_PHONE_CALL_MICROPHONE, + OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO, OPSTR_RECORD_AUDIO ); @@ -147,6 +149,7 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis private static @NonNull String getGroupForOp(String op) { switch (op) { + case OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO: case OPSTR_RECORD_AUDIO: return MICROPHONE; case OPSTR_CAMERA: diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 37f44e98c165..9a2f7baa7265 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -738,6 +738,14 @@ public final class DeviceConfig { */ public static final String NAMESPACE_VENDOR_SYSTEM_NATIVE = "vendor_system_native"; + /** + * Namespace for DevicePolicyManager related features. + * + * @hide + */ + public static final String NAMESPACE_DEVICE_POLICY_MANAGER = + "device_policy_manager"; + private static final Object sLock = new Object(); @GuardedBy("sLock") private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners = diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 2a304aa037a1..d1ff9f79d96a 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -10206,15 +10206,6 @@ public final class Settings { public static final String NOTIFICATION_DISMISS_RTL = "notification_dismiss_rtl"; /** - * Whether the app-level notification setting is represented by a manifest permission. - * - * @hide - */ - @Readable - public static final String NOTIFICATION_PERMISSION_ENABLED = - "notification_permission_enabled"; - - /** * Comma separated list of QS tiles that have been auto-added already. * @hide */ diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 0ec95c687090..425dbb9cb204 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -904,6 +904,7 @@ public abstract class WallpaperService extends Service { // based on its default wallpaper color hints. mShouldDim = dimAmount != 0f || mShouldDimByDefault; updateSurfaceDimming(); + updateSurface(false, false, true); } private void updateSurfaceDimming() { @@ -940,7 +941,6 @@ public abstract class WallpaperService extends Service { } else { Log.v(TAG, "Setting wallpaper dimming: " + 0); surfaceControlTransaction.setAlpha(mBbqSurfaceControl, 1.0f).apply(); - updateSurface(false, false, true); } mPreviousWallpaperDimAmount = mWallpaperDimAmount; diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index e5ec260907df..691452f51ee8 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -341,10 +341,12 @@ public class Surface implements Parcelable { */ @UnsupportedAppUsage public void destroy() { - if (mNativeObject != 0) { - nativeDestroy(mNativeObject); + synchronized (mLock) { + if (mNativeObject != 0) { + nativeDestroy(mNativeObject); + } + release(); } - release(); } /** diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index d04b07c13b41..38ca2481726b 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -11941,7 +11941,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @NonNull public final List<Rect> getUnrestrictedPreferKeepClearRects() { final ListenerInfo info = mListenerInfo; - if (info != null && info.mKeepClearRects != null) { + if (info != null && info.mUnrestrictedKeepClearRects != null) { return new ArrayList(info.mUnrestrictedKeepClearRects); } @@ -21170,6 +21170,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } AccessibilityNodeIdManager.getInstance().unregisterViewWithId(getAccessibilityViewId()); + + if (mBackgroundRenderNode != null) { + mBackgroundRenderNode.forceEndAnimators(); + } + mRenderNode.forceEndAnimators(); } private void cleanupDraw() { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index aa8e2abfba64..690981eaa14a 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -3122,10 +3122,14 @@ public interface WindowManager extends ViewManager { /** * The preferred refresh rate for the window. - * + * <p> * This must be one of the supported refresh rates obtained for the display(s) the window * is on. The selected refresh rate will be applied to the display's default mode. - * + * <p> + * This should be used in favor of {@link LayoutParams#preferredDisplayModeId} for + * applications that want to specify the refresh rate, but do not want to specify a + * preference for any other displayMode properties (e.g., resolution). + * <p> * This value is ignored if {@link #preferredDisplayModeId} is set. * * @see Display#getSupportedRefreshRates() diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index 51da61ffb9c9..c81184fb2383 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -107,8 +107,11 @@ public final class TransitionInfo implements Parcelable { */ public static final int FLAG_DISPLAY_HAS_ALERT_WINDOWS = 1 << 7; + /** The container is an input-method window. */ + public static final int FLAG_IS_INPUT_METHOD = 1 << 8; + /** The first unused bit. This can be used by remotes to attach custom flags to this change. */ - public static final int FLAG_FIRST_CUSTOM = 1 << 8; + public static final int FLAG_FIRST_CUSTOM = 1 << 9; /** @hide */ @IntDef(prefix = { "FLAG_" }, value = { @@ -121,6 +124,7 @@ public final class TransitionInfo implements Parcelable { FLAG_IS_DISPLAY, FLAG_OCCLUDES_KEYGUARD, FLAG_DISPLAY_HAS_ALERT_WINDOWS, + FLAG_IS_INPUT_METHOD, FLAG_FIRST_CUSTOM }) public @interface ChangeFlags {} @@ -300,6 +304,9 @@ public final class TransitionInfo implements Parcelable { if ((flags & FLAG_IS_WALLPAPER) != 0) { sb.append("IS_WALLPAPER"); } + if ((flags & FLAG_IS_INPUT_METHOD) != 0) { + sb.append("IS_INPUT_METHOD"); + } if ((flags & FLAG_TRANSLUCENT) != 0) { sb.append((sb.length() == 0 ? "" : "|") + "TRANSLUCENT"); } diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java index 7db4243d3a83..0976f45c02b0 100644 --- a/core/java/android/window/WindowTokenClient.java +++ b/core/java/android/window/WindowTokenClient.java @@ -21,8 +21,10 @@ import static android.window.ConfigurationHelper.shouldUpdateResources; import android.annotation.AnyThread; import android.annotation.BinderThread; +import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityThread; import android.app.IWindowToken; import android.app.ResourcesManager; import android.content.Context; @@ -33,7 +35,6 @@ import android.os.Bundle; import android.os.Debug; import android.os.Handler; import android.os.IBinder; -import android.os.Looper; import android.os.RemoteException; import android.util.Log; import android.view.IWindowManager; @@ -42,6 +43,7 @@ import android.view.WindowManagerGlobal; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.function.pooled.PooledLambda; import java.lang.ref.WeakReference; @@ -76,7 +78,7 @@ public class WindowTokenClient extends IWindowToken.Stub { private boolean mAttachToWindowContainer; - private final Handler mHandler = new Handler(Looper.getMainLooper()); + private final Handler mHandler = ActivityThread.currentActivityThread().getHandler(); /** * Attaches {@code context} to this {@link WindowTokenClient}. Each {@link WindowTokenClient} @@ -188,8 +190,8 @@ public class WindowTokenClient extends IWindowToken.Stub { @BinderThread @Override public void onConfigurationChanged(Configuration newConfig, int newDisplayId) { - mHandler.post(() -> onConfigurationChanged(newConfig, newDisplayId, - true /* shouldReportConfigChange */)); + mHandler.post(PooledLambda.obtainRunnable(this::onConfigurationChanged, newConfig, + newDisplayId, true /* shouldReportConfigChange */).recycleOnUse()); } // TODO(b/192048581): rewrite this method based on WindowContext and WindowProviderService @@ -279,12 +281,16 @@ public class WindowTokenClient extends IWindowToken.Stub { @BinderThread @Override public void onWindowTokenRemoved() { - mHandler.post(() -> { - final Context context = mContextRef.get(); - if (context != null) { - context.destroy(); - mContextRef.clear(); - } - }); + mHandler.post(PooledLambda.obtainRunnable( + WindowTokenClient::onWindowTokenRemovedInner, this).recycleOnUse()); + } + + @MainThread + private void onWindowTokenRemovedInner() { + final Context context = mContextRef.get(); + if (context != null) { + context.destroy(); + mContextRef.clear(); + } } } diff --git a/core/java/com/android/internal/app/AppLocaleStore.java b/core/java/com/android/internal/app/AppLocaleStore.java index 599e6d24600c..f3a322cac79a 100644 --- a/core/java/com/android/internal/app/AppLocaleStore.java +++ b/core/java/com/android/internal/app/AppLocaleStore.java @@ -20,12 +20,15 @@ import static com.android.internal.app.AppLocaleStore.AppLocaleResult.LocaleStat import android.app.LocaleConfig; import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.InstallSourceInfo; import android.content.pm.PackageManager; import android.os.LocaleList; import android.util.Log; -import java.util.ArrayList; +import java.util.HashSet; import java.util.Locale; +import java.util.stream.Collectors; class AppLocaleStore { private static final String TAG = AppLocaleStore.class.getSimpleName(); @@ -34,7 +37,8 @@ class AppLocaleStore { Context context, String packageName) { LocaleConfig localeConfig = null; AppLocaleResult.LocaleStatus localeStatus = LocaleStatus.UNKNOWN_FAILURE; - ArrayList<Locale> appSupportedLocales = new ArrayList<>(); + HashSet<Locale> appSupportedLocales = new HashSet<>(); + HashSet<Locale> assetLocale = getAssetLocales(context, packageName); try { localeConfig = new LocaleConfig(context.createPackageContext(packageName, 0)); @@ -45,32 +49,43 @@ class AppLocaleStore { if (localeConfig != null) { if (localeConfig.getStatus() == LocaleConfig.STATUS_SUCCESS) { LocaleList packageLocaleList = localeConfig.getSupportedLocales(); - if (packageLocaleList.size() > 0) { + boolean shouldFilterNotMatchingLocale = !hasInstallerInfo(context, packageName) && + isSystemApp(context, packageName); + + Log.d(TAG, "filterNonMatchingLocale. " + + ", shouldFilterNotMatchingLocale: " + shouldFilterNotMatchingLocale + + ", assetLocale size: " + assetLocale.size() + + ", packageLocaleList size: " + packageLocaleList.size()); + + for (int i = 0; i < packageLocaleList.size(); i++) { + appSupportedLocales.add(packageLocaleList.get(i)); + } + if (shouldFilterNotMatchingLocale) { + appSupportedLocales = filterNotMatchingLocale(appSupportedLocales, assetLocale); + } + + if (appSupportedLocales.size() > 0) { localeStatus = LocaleStatus.GET_SUPPORTED_LANGUAGE_FROM_LOCAL_CONFIG; - for (int i = 0; i < packageLocaleList.size(); i++) { - appSupportedLocales.add(packageLocaleList.get(i)); - } } else { localeStatus = LocaleStatus.NO_SUPPORTED_LANGUAGE_IN_APP; } } else if (localeConfig.getStatus() == LocaleConfig.STATUS_NOT_SPECIFIED) { - String[] languages = getAssetLocales(context, packageName); - if (languages.length > 0) { + if (assetLocale.size() > 0) { localeStatus = LocaleStatus.GET_SUPPORTED_LANGUAGE_FROM_ASSET; - for (String language : languages) { - appSupportedLocales.add(Locale.forLanguageTag(language)); - } + appSupportedLocales = assetLocale; } else { localeStatus = LocaleStatus.ASSET_LOCALE_IS_EMPTY; } } } - Log.d(TAG, "getAppSupportedLocales(). status: " + localeStatus + Log.d(TAG, "getAppSupportedLocales(). package: " + packageName + + ", status: " + localeStatus + ", appSupportedLocales:" + appSupportedLocales.size()); return new AppLocaleResult(localeStatus, appSupportedLocales); } - private static String[] getAssetLocales(Context context, String packageName) { + private static HashSet<Locale> getAssetLocales(Context context, String packageName) { + HashSet<Locale> result = new HashSet<>(); try { PackageManager packageManager = context.getPackageManager(); String[] locales = packageManager.getResourcesForApplication( @@ -78,16 +93,59 @@ class AppLocaleStore { .applicationInfo).getAssets().getNonSystemLocales(); if (locales == null) { Log.i(TAG, "[" + packageName + "] locales are null."); - return new String[0]; } else if (locales.length <= 0) { Log.i(TAG, "[" + packageName + "] locales length is 0."); - return new String[0]; + } else { + for (String language : locales) { + result.add(Locale.forLanguageTag(language)); + } } - return locales; } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Can not found the package name : " + packageName + " / " + e); } - return new String[0]; + return result; + } + + private static HashSet<Locale> filterNotMatchingLocale( + HashSet<Locale> appSupportedLocales, HashSet<Locale> assetLocale) { + return appSupportedLocales.stream() + .filter(locale -> matchLanguageInSet(locale, assetLocale)) + .collect(Collectors.toCollection(HashSet::new)); + } + + private static boolean matchLanguageInSet(Locale locale, HashSet<Locale> localesSet) { + if (localesSet.contains(locale)) { + return true; + } + for (Locale l: localesSet) { + if(LocaleList.matchesLanguageAndScript(l, locale)) { + return true; + } + } + return false; + } + + private static boolean hasInstallerInfo(Context context, String packageName) { + InstallSourceInfo installSourceInfo; + try { + installSourceInfo = context.getPackageManager().getInstallSourceInfo(packageName); + return installSourceInfo != null; + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Installer info not found for: " + packageName); + } + return false; + } + + private static boolean isSystemApp(Context context, String packageName) { + ApplicationInfo applicationInfo; + try { + applicationInfo = context.getPackageManager() + .getApplicationInfoAsUser(packageName, /* flags= */ 0, context.getUserId()); + return applicationInfo.isSystemApp(); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Application info not found for: " + packageName); + } + return false; } static class AppLocaleResult { @@ -100,9 +158,9 @@ class AppLocaleStore { } LocaleStatus mLocaleStatus; - ArrayList<Locale> mAppSupportedLocales; + HashSet<Locale> mAppSupportedLocales; - public AppLocaleResult(LocaleStatus localeStatus, ArrayList<Locale> appSupportedLocales) { + public AppLocaleResult(LocaleStatus localeStatus, HashSet<Locale> appSupportedLocales) { this.mLocaleStatus = localeStatus; this.mAppSupportedLocales = appSupportedLocales; } diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 781b6d5459ca..2ad1b3845bdc 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -1861,10 +1861,10 @@ public class ChooserActivity extends ResolverActivity implements try { final Intent intent = getTargetIntent(); String dataString = intent.getDataString(); - if (!TextUtils.isEmpty(dataString)) { - return new IntentFilter(intent.getAction(), dataString); - } if (intent.getType() == null) { + if (!TextUtils.isEmpty(dataString)) { + return new IntentFilter(intent.getAction(), dataString); + } Log.e(TAG, "Failed to get target intent filter: intent data and type are null"); return null; } diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java index f6445849d897..8dd827287942 100644 --- a/core/java/com/android/internal/app/ChooserListAdapter.java +++ b/core/java/com/android/internal/app/ChooserListAdapter.java @@ -144,7 +144,9 @@ public class ChooserListAdapter extends ResolverListAdapter { } } if (ai == null) { - ri = packageManager.resolveActivity(ii, PackageManager.MATCH_DEFAULT_ONLY); + // Because of AIDL bug, resolveActivity can't accept subclasses of Intent. + final Intent rii = (ii.getClass() == Intent.class) ? ii : new Intent(ii); + ri = packageManager.resolveActivity(rii, PackageManager.MATCH_DEFAULT_ONLY); ai = ri != null ? ri.activityInfo : null; } if (ai == null) { diff --git a/core/java/com/android/internal/app/ChooserTargetActionsDialogFragment.java b/core/java/com/android/internal/app/ChooserTargetActionsDialogFragment.java index 4f1f380c3a77..3e1b5f087c10 100644 --- a/core/java/com/android/internal/app/ChooserTargetActionsDialogFragment.java +++ b/core/java/com/android/internal/app/ChooserTargetActionsDialogFragment.java @@ -269,7 +269,7 @@ public class ChooserTargetActionsDialogFragment extends DialogFragment protected CharSequence getItemLabel(DisplayResolveInfo dri) { final PackageManager pm = getContext().getPackageManager(); return getPinLabel(isPinned(dri), - isShortcutTarget() ? "" : dri.getResolveInfo().loadLabel(pm)); + isShortcutTarget() ? mShortcutTitle : dri.getResolveInfo().loadLabel(pm)); } @Nullable diff --git a/core/java/com/android/internal/app/LocalePickerWithRegion.java b/core/java/com/android/internal/app/LocalePickerWithRegion.java index a06ba9be4689..2247e2f9a9fc 100644 --- a/core/java/com/android/internal/app/LocalePickerWithRegion.java +++ b/core/java/com/android/internal/app/LocalePickerWithRegion.java @@ -29,13 +29,13 @@ import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.view.MenuItem.OnActionExpandListener; import android.view.View; import android.widget.ListView; import android.widget.SearchView; import com.android.internal.R; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Locale; @@ -64,6 +64,7 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O private int mTopDistance = 0; private String mAppPackageName; private CharSequence mTitle = null; + private OnActionExpandListener mOnActionExpandListener; /** * Other classes can register to be notified when a locale was selected. @@ -80,8 +81,10 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O private static LocalePickerWithRegion createCountryPicker(Context context, LocaleSelectedListener listener, LocaleStore.LocaleInfo parent, - boolean translatedOnly, String appPackageName) { + boolean translatedOnly, String appPackageName, + OnActionExpandListener onActionExpandListener) { LocalePickerWithRegion localePicker = new LocalePickerWithRegion(); + localePicker.setOnActionExpandListener(onActionExpandListener); boolean shouldShowTheList = localePicker.setListener(context, listener, parent, translatedOnly, appPackageName); return shouldShowTheList ? localePicker : null; @@ -95,8 +98,10 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O } public static LocalePickerWithRegion createLanguagePicker(Context context, - LocaleSelectedListener listener, boolean translatedOnly, String appPackageName) { + LocaleSelectedListener listener, boolean translatedOnly, String appPackageName, + OnActionExpandListener onActionExpandListener) { LocalePickerWithRegion localePicker = new LocalePickerWithRegion(); + localePicker.setOnActionExpandListener(onActionExpandListener); localePicker.setListener( context, listener, /* parent */ null, translatedOnly, appPackageName); return localePicker; @@ -198,13 +203,20 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O } private Set<LocaleStore.LocaleInfo> filterTheLanguagesNotSupportedInApp( - boolean shouldShowList, ArrayList<Locale> supportedLocales) { + boolean shouldShowList, HashSet<Locale> supportedLocales) { Set<LocaleStore.LocaleInfo> filteredList = new HashSet<>(); - if (shouldShowList) { - for(LocaleStore.LocaleInfo li: mLocaleList) { + if (!shouldShowList) { + return filteredList; + } + + for(LocaleStore.LocaleInfo li: mLocaleList) { + if (supportedLocales.contains(li.getLocale())) { + filteredList.add(li); + } else { for(Locale l: supportedLocales) { if(LocaleList.matchesLanguageAndScript(li.getLocale(), l)) { filteredList.add(li); + break; } } } @@ -310,7 +322,7 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O } else { LocalePickerWithRegion selector = LocalePickerWithRegion.createCountryPicker( getContext(), mListener, locale, mTranslatedOnly /* translate only */, - mAppPackageName); + mAppPackageName, mOnActionExpandListener); if (selector != null) { getFragmentManager().beginTransaction() .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) @@ -328,8 +340,11 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O inflater.inflate(R.menu.language_selection_list, menu); final MenuItem searchMenuItem = menu.findItem(R.id.locale_search_menu); - mSearchView = (SearchView) searchMenuItem.getActionView(); + if (!mAppPackageName.isEmpty() && mOnActionExpandListener != null) { + searchMenuItem.setOnActionExpandListener(mOnActionExpandListener); + } + mSearchView = (SearchView) searchMenuItem.getActionView(); mSearchView.setQueryHint(getText(R.string.search_language_hint)); mSearchView.setOnQueryTextListener(this); @@ -363,4 +378,11 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O } return false; } + + /** + * Sets OnActionExpandListener to LocalePickerWithRegion to dectect action of search bar. + */ + public void setOnActionExpandListener(OnActionExpandListener onActionExpandListener) { + mOnActionExpandListener = onActionExpandListener; + } } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index bd5a73d8194a..a23f84158366 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -119,6 +119,11 @@ public class ResolverActivity extends Activity implements @UnsupportedAppUsage public ResolverActivity() { + mIsIntentPicker = getClass().equals(ResolverActivity.class); + } + + protected ResolverActivity(boolean isIntentPicker) { + mIsIntentPicker = isIntentPicker; } private boolean mSafeForwardingMode; @@ -135,6 +140,8 @@ public class ResolverActivity extends Activity implements private String mReferrerPackage; private CharSequence mTitle; private int mDefaultTitleResId; + // Expected to be true if this object is ResolverActivity or is ResolverWrapperActivity. + private final boolean mIsIntentPicker; // Whether or not this activity supports choosing a default handler for the intent. @VisibleForTesting @@ -445,10 +452,6 @@ public class ResolverActivity extends Activity implements + (categories != null ? Arrays.toString(categories.toArray()) : "")); } - private boolean isIntentPicker() { - return getClass().equals(ResolverActivity.class); - } - protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter( Intent[] initialIntents, List<ResolveInfo> rList, @@ -637,6 +640,11 @@ public class ResolverActivity extends Activity implements resetButtonBar(); + if (shouldUseMiniResolver()) { + View buttonContainer = findViewById(R.id.button_bar_container); + buttonContainer.setPadding(0, 0, 0, mSystemWindowInsets.bottom); + } + // Need extra padding so the list can fully scroll up if (shouldAddFooterView()) { applyFooterView(mSystemWindowInsets.bottom); @@ -649,7 +657,8 @@ public class ResolverActivity extends Activity implements public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged(); - if (isIntentPicker() && shouldShowTabs() && !useLayoutWithDefault()) { + if (mIsIntentPicker && shouldShowTabs() && !useLayoutWithDefault() + && !shouldUseMiniResolver()) { updateIntentPickerPaddings(); } @@ -1084,7 +1093,7 @@ public class ResolverActivity extends Activity implements if (isAutolaunching()) { return; } - if (isIntentPicker()) { + if (mIsIntentPicker) { ((ResolverMultiProfilePagerAdapter) mMultiProfilePagerAdapter) .setUseLayoutWithDefault(useLayoutWithDefault()); } @@ -1108,7 +1117,7 @@ public class ResolverActivity extends Activity implements protected void onListRebuilt(ResolverListAdapter listAdapter, boolean rebuildCompleted) { final ItemClickListener listener = new ItemClickListener(); setupAdapterListView((ListView) mMultiProfilePagerAdapter.getActiveAdapterView(), listener); - if (shouldShowTabs() && isIntentPicker()) { + if (shouldShowTabs() && mIsIntentPicker) { final ResolverDrawerLayout rdl = findViewById(R.id.contentPanel); if (rdl != null) { rdl.setMaxCollapsedHeight(getResources() @@ -1448,6 +1457,12 @@ public class ResolverActivity extends Activity implements return postRebuildList(rebuildCompleted); } + /** + * Mini resolver is shown when the user is choosing between browser[s] in this profile and a + * single app in the other profile (see shouldUseMiniResolver()). It shows the single app icon + * and asks the user if they'd like to open that cross-profile app or use the in-profile + * browser. + */ private void configureMiniResolverContent() { mLayoutId = R.layout.miniresolver; setContentView(mLayoutId); @@ -1484,7 +1499,16 @@ public class ResolverActivity extends Activity implements }); } + /** + * Mini resolver should be used when all of the following are true: + * 1. This is the intent picker (ResolverActivity). + * 2. This profile only has web browser matches. + * 3. The other profile has a single non-browser match. + */ private boolean shouldUseMiniResolver() { + if (!mIsIntentPicker) { + return false; + } if (mMultiProfilePagerAdapter.getActiveListAdapter() == null || mMultiProfilePagerAdapter.getInactiveListAdapter() == null) { return false; @@ -1790,7 +1814,7 @@ public class ResolverActivity extends Activity implements void onHorizontalSwipeStateChanged(int state) {} private void maybeHideDivider() { - if (!isIntentPicker()) { + if (!mIsIntentPicker) { return; } final View divider = findViewById(R.id.divider); @@ -1807,7 +1831,7 @@ public class ResolverActivity extends Activity implements protected void onProfileTabSelected() { } private void resetCheckedItem() { - if (!isIntentPicker()) { + if (!mIsIntentPicker) { return; } mLastSelected = ListView.INVALID_POSITION; diff --git a/core/java/com/android/internal/app/UnlaunchableAppActivity.java b/core/java/com/android/internal/app/UnlaunchableAppActivity.java index 957a6365739d..e56d92b48528 100644 --- a/core/java/com/android/internal/app/UnlaunchableAppActivity.java +++ b/core/java/com/android/internal/app/UnlaunchableAppActivity.java @@ -91,7 +91,12 @@ public class UnlaunchableAppActivity extends Activity } else { builder.setPositiveButton(R.string.ok, null); } - builder.show(); + final AlertDialog dialog = builder.create(); + dialog.create(); + // Prevents screen overlay attack. + getWindow().setHideOverlayWindows(true); + dialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true); + dialog.show(); } private String getDialogTitle() { diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index e466c8866afa..2e4860a6da26 100644 --- a/core/java/com/android/internal/jank/InteractionJankMonitor.java +++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java @@ -71,6 +71,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_NEXT_FLOW; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TAKE_SCREENSHOT; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__UNFOLD_ANIM; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_SWITCH; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION; @@ -194,6 +195,7 @@ public class InteractionJankMonitor { public static final int CUJ_LOCKSCREEN_LAUNCH_CAMERA = 51; // reserved. public static final int CUJ_SPLIT_SCREEN_RESIZE = 52; public static final int CUJ_SETTINGS_SLIDER = 53; + public static final int CUJ_TAKE_SCREENSHOT = 54; private static final int NO_STATSD_LOGGING = -1; @@ -256,6 +258,7 @@ public class InteractionJankMonitor { UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_LAUNCH_CAMERA, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_RESIZE, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_SLIDER, + UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TAKE_SCREENSHOT, }; private static volatile InteractionJankMonitor sInstance; @@ -330,6 +333,7 @@ public class InteractionJankMonitor { CUJ_LOCKSCREEN_LAUNCH_CAMERA, CUJ_SPLIT_SCREEN_RESIZE, CUJ_SETTINGS_SLIDER, + CUJ_TAKE_SCREENSHOT, }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { @@ -756,6 +760,8 @@ public class InteractionJankMonitor { return "CUJ_SPLIT_SCREEN_RESIZE"; case CUJ_SETTINGS_SLIDER: return "SETTINGS_SLIDER"; + case CUJ_TAKE_SCREENSHOT: + return "TAKE_SCREENSHOT"; } return "UNKNOWN"; } diff --git a/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java b/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java index 3eb980465214..5adaf4fbd2cc 100644 --- a/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java +++ b/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java @@ -28,18 +28,15 @@ import com.android.internal.R; public final class NotificationAccessConfirmationActivityContract { public static final String EXTRA_USER_ID = "user_id"; public static final String EXTRA_COMPONENT_NAME = "component_name"; - public static final String EXTRA_PACKAGE_TITLE = "package_title"; /** * Creates a launcher intent for NotificationAccessConfirmationActivity. */ - public static Intent launcherIntent(Context context, int userId, ComponentName component, - String packageTitle) { + public static Intent launcherIntent(Context context, int userId, ComponentName component) { return new Intent() .setComponent(ComponentName.unflattenFromString(context.getString( R.string.config_notificationAccessConfirmationActivity))) .putExtra(EXTRA_USER_ID, userId) - .putExtra(EXTRA_COMPONENT_NAME, component) - .putExtra(EXTRA_PACKAGE_TITLE, packageTitle); + .putExtra(EXTRA_COMPONENT_NAME, component); } } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 3f87de2e0f8a..b03a8cbeb79c 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -167,7 +167,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - static final int VERSION = 207; + static final int VERSION = 208; // The maximum number of names wakelocks we will keep track of // per uid; once the limit is reached, we batch the remaining wakelocks @@ -3981,8 +3981,7 @@ public class BatteryStatsImpl extends BatteryStats { if (idxObj != null) { idx = idxObj; if ((idx & TAG_FIRST_OCCURRENCE_FLAG) != 0) { - idx &= ~TAG_FIRST_OCCURRENCE_FLAG; - mHistoryTagPool.put(tag, idx); + mHistoryTagPool.put(tag, idx & ~TAG_FIRST_OCCURRENCE_FLAG); } return idx; } else if (mNextHistoryTagIdx < HISTORY_TAG_INDEX_LIMIT) { diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 1db4bbba9ad5..ea5797d752d7 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -1262,7 +1262,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind } } - if (forceConsumingNavBar && !mDrawLegacyNavigationBarBackgroundHandled) { + if (forceConsumingNavBar && !hideNavigation && !mDrawLegacyNavigationBarBackgroundHandled) { mBackgroundInsets = Insets.of(mLastLeftInset, 0, mLastRightInset, mLastBottomInset); } else { mBackgroundInsets = Insets.NONE; diff --git a/core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java b/core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java index fc064ea1ff10..4173abff9042 100644 --- a/core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java +++ b/core/java/com/android/internal/policy/ForceShowNavBarSettingsObserver.java @@ -16,13 +16,18 @@ package com.android.internal.policy; +import android.annotation.NonNull; +import android.app.ActivityManager; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; +import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; +import java.util.Collection; + /** * A ContentObserver for listening {@link Settings.Secure#NAV_BAR_FORCE_VISIBLE} setting key. * @@ -59,7 +64,11 @@ public class ForceShowNavBarSettingsObserver extends ContentObserver { } @Override - public void onChange(boolean selfChange) { + public void onChange(boolean selfChange, @NonNull Collection<Uri> uris, int flags, int userId) { + if (userId != ActivityManager.getCurrentUser()) { + return; + } + if (mOnChangeRunnable != null) { mOnChangeRunnable.run(); } diff --git a/core/java/com/android/internal/widget/PasswordValidationError.java b/core/java/com/android/internal/widget/PasswordValidationError.java index 41b234ef024e..f678b130f4f1 100644 --- a/core/java/com/android/internal/widget/PasswordValidationError.java +++ b/core/java/com/android/internal/widget/PasswordValidationError.java @@ -24,16 +24,17 @@ public class PasswordValidationError { public static final int WEAK_CREDENTIAL_TYPE = 1; public static final int CONTAINS_INVALID_CHARACTERS = 2; public static final int TOO_SHORT = 3; - public static final int TOO_LONG = 4; - public static final int CONTAINS_SEQUENCE = 5; - public static final int NOT_ENOUGH_LETTERS = 6; - public static final int NOT_ENOUGH_UPPER_CASE = 7; - public static final int NOT_ENOUGH_LOWER_CASE = 8; - public static final int NOT_ENOUGH_DIGITS = 9; - public static final int NOT_ENOUGH_SYMBOLS = 10; - public static final int NOT_ENOUGH_NON_LETTER = 11; - public static final int NOT_ENOUGH_NON_DIGITS = 12; - public static final int RECENTLY_USED = 13; + public static final int TOO_SHORT_WHEN_ALL_NUMERIC = 4; + public static final int TOO_LONG = 5; + public static final int CONTAINS_SEQUENCE = 6; + public static final int NOT_ENOUGH_LETTERS = 7; + public static final int NOT_ENOUGH_UPPER_CASE = 8; + public static final int NOT_ENOUGH_LOWER_CASE = 9; + public static final int NOT_ENOUGH_DIGITS = 10; + public static final int NOT_ENOUGH_SYMBOLS = 11; + public static final int NOT_ENOUGH_NON_LETTER = 12; + public static final int NOT_ENOUGH_NON_DIGITS = 13; + public static final int RECENTLY_USED = 14; // WARNING: if you add a new error, make sure it is presented to the user correctly in Settings. public final int errorCode; @@ -61,6 +62,7 @@ public class PasswordValidationError { case WEAK_CREDENTIAL_TYPE: return "Weak credential type"; case CONTAINS_INVALID_CHARACTERS: return "Contains an invalid character"; case TOO_SHORT: return "Password too short"; + case TOO_SHORT_WHEN_ALL_NUMERIC: return "Password too short"; case TOO_LONG: return "Password too long"; case CONTAINS_SEQUENCE: return "Sequence too long"; case NOT_ENOUGH_LETTERS: return "Too few letters"; diff --git a/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java index f7af67b3b2a8..c484525dbe20 100644 --- a/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java +++ b/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbarPopup.java @@ -21,7 +21,6 @@ import android.content.Context; import android.graphics.Rect; import android.view.MenuItem; import android.view.View; -import android.view.selectiontoolbar.SelectionToolbarManager; import android.widget.PopupWindow; import java.util.List; @@ -93,10 +92,7 @@ public interface FloatingToolbarPopup { * enabled, otherwise returns {@link LocalFloatingToolbarPopup} implementation. */ static FloatingToolbarPopup createInstance(Context context, View parent) { - boolean enabled = SelectionToolbarManager.isRemoteSelectionToolbarEnabled(context); - return enabled - ? new RemoteFloatingToolbarPopup(context, parent) - : new LocalFloatingToolbarPopup(context, parent); + return new LocalFloatingToolbarPopup(context, parent); } } diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index b6fbe206a262..f24c66695052 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -1264,6 +1264,12 @@ static jint convertAudioProfileFromNative(JNIEnv *env, jobject *jAudioProfile, size_t numPositionMasks = 0; size_t numIndexMasks = 0; + int audioFormat = audioFormatFromNative(nAudioProfile->format); + if (audioFormat == ENCODING_INVALID) { + ALOGW("Unknown native audio format for JAVA API: %u", nAudioProfile->format); + return AUDIO_JAVA_BAD_VALUE; + } + // count up how many masks are positional and indexed for (size_t index = 0; index < nAudioProfile->num_channel_masks; index++) { const audio_channel_mask_t mask = nAudioProfile->channel_masks[index]; @@ -1306,10 +1312,9 @@ static jint convertAudioProfileFromNative(JNIEnv *env, jobject *jAudioProfile, ALOGW("Unknown encapsulation type for JAVA API: %u", nAudioProfile->encapsulation_type); } - *jAudioProfile = - env->NewObject(gAudioProfileClass, gAudioProfileCstor, - audioFormatFromNative(nAudioProfile->format), jSamplingRates.get(), - jChannelMasks.get(), jChannelIndexMasks.get(), encapsulationType); + *jAudioProfile = env->NewObject(gAudioProfileClass, gAudioProfileCstor, audioFormat, + jSamplingRates.get(), jChannelMasks.get(), + jChannelIndexMasks.get(), encapsulationType); if (*jAudioProfile == nullptr) { return AUDIO_JAVA_ERROR; @@ -1368,6 +1373,10 @@ static jint convertAudioPortFromNative(JNIEnv *env, jobject *jAudioPort, jobject jAudioProfile = nullptr; jStatus = convertAudioProfileFromNative(env, &jAudioProfile, &nAudioPort->audio_profiles[i], useInMask); + if (jStatus == AUDIO_JAVA_BAD_VALUE) { + // skipping Java layer unsupported audio formats + continue; + } if (jStatus != NO_ERROR) { jStatus = (jint)AUDIO_JAVA_ERROR; goto exit; @@ -2406,8 +2415,13 @@ static jint android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject th goto exit; } for (size_t i = 0; i < numSurroundFormats; i++) { - jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor, - audioFormatFromNative(surroundFormats[i])); + int audioFormat = audioFormatFromNative(surroundFormats[i]); + if (audioFormat == ENCODING_INVALID) { + // skipping Java layer unsupported audio formats + ALOGW("Unknown surround native audio format for JAVA API: %u", surroundFormats[i]); + continue; + } + jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor, audioFormat); jobject enabled = env->NewObject(gBooleanClass, gBooleanCstor, surroundFormatsEnabled[i]); env->CallObjectMethod(jSurroundFormats, gMapPut, surroundFormat, enabled); env->DeleteLocalRef(surroundFormat); @@ -2453,8 +2467,13 @@ static jint android_media_AudioSystem_getReportedSurroundFormats(JNIEnv *env, jo goto exit; } for (size_t i = 0; i < numSurroundFormats; i++) { - jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor, - audioFormatFromNative(surroundFormats[i])); + int audioFormat = audioFormatFromNative(surroundFormats[i]); + if (audioFormat == ENCODING_INVALID) { + // skipping Java layer unsupported audio formats + ALOGW("Unknown surround native audio format for JAVA API: %u", surroundFormats[i]); + continue; + } + jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor, audioFormat); env->CallObjectMethod(jSurroundFormats, gArrayListMethods.add, surroundFormat); env->DeleteLocalRef(surroundFormat); } @@ -2919,6 +2938,10 @@ static jint android_media_AudioSystem_getDirectProfilesForAttributes(JNIEnv *env for (const auto &audioProfile : audioProfiles) { jobject jAudioProfile; jStatus = convertAudioProfileFromNative(env, &jAudioProfile, &audioProfile, false); + if (jStatus == AUDIO_JAVA_BAD_VALUE) { + // skipping Java layer unsupported audio formats + continue; + } if (jStatus != AUDIO_JAVA_SUCCESS) { return jStatus; } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index c769da57eecc..4044c579a57f 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -1921,6 +1921,7 @@ static void nativeRemoveCurrentInputFocus(JNIEnv* env, jclass clazz, jlong trans FocusRequest request; request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC); request.displayId = displayId; + request.windowName = "<null>"; transaction->setFocusedWindow(request); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 0f328b034f38..f20b824e6bf7 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -6441,11 +6441,11 @@ <!-- @SystemApi Must be required by a safety source to send an update using the {@link android.safetycenter.SafetyCenterManager}. - <p>Protection level: signature|privileged + <p>Protection level: internal|privileged @hide --> <permission android:name="android.permission.SEND_SAFETY_CENTER_UPDATE" - android:protectionLevel="signature|privileged" /> + android:protectionLevel="internal|privileged" /> <!-- @SystemApi Allows an application to launch device manager setup screens. <p>Not for use by third-party applications. diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml index 252f59e5ac62..0b6a2016f03d 100644 --- a/core/res/res/layout/autofill_fill_dialog.xml +++ b/core/res/res/layout/autofill_fill_dialog.xml @@ -50,6 +50,7 @@ android:visibility="gone" /> </LinearLayout> + <!-- For Authentication. --> <LinearLayout android:id="@+id/autofill_dialog_container" android:layout_width="fill_parent" @@ -58,7 +59,7 @@ android:paddingStart="@dimen/autofill_save_inner_padding" android:paddingEnd="@dimen/autofill_save_inner_padding" android:visibility="gone" - style="@style/AutofillDatasetPicker" /> + android:background="@drawable/autofill_dataset_picker_background"/> <ListView android:id="@+id/autofill_dialog_list" @@ -68,8 +69,8 @@ android:drawSelectorOnTop="true" android:clickable="true" android:divider="?android:attr/listDivider" - android:visibility="gone" - style="@style/AutofillDatasetPicker" /> + android:background="@drawable/autofill_dataset_picker_background" + android:visibility="gone"/> <com.android.internal.widget.ButtonBarLayout android:layout_width="match_parent" diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index c49d1b444807..d95478daf005 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1685,7 +1685,7 @@ <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"FRA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vil du give <xliff:g id="SERVICE">%1$s</xliff:g> fuld kontrol over din enhed?"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Fuld kontrol er velegnet til apps, der hjælper dig med hjælpefunktioner, men ikke de fleste apps."</string> - <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Se og styre skærm"</string> + <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Se og styre skærmen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Den kan læse alt indhold på skærmen og vise indhold oven på andre apps."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Se og udføre handlinger"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Den kan spore dine interaktioner med en app eller en hardwaresensor og interagere med apps på dine vegne."</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index fccda03286e8..a8860aff327e 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1392,7 +1392,7 @@ <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Bistaratu beste aplikazioen gainean"</string> <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> aplikazioen gainean agertzea"</string> <string name="alert_windows_notification_title" msgid="6331662751095228536">"Besteen gainean agertzen da <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="alert_windows_notification_message" msgid="6538171456970725333">"Ez baduzu nahi <xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string> + <string name="alert_windows_notification_message" msgid="6538171456970725333">"<xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea nahi ez baduzu, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string> <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desaktibatu"</string> <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"<xliff:g id="NAME">%s</xliff:g> egiaztatzen…"</string> <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Edukia berrikusten"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 1de93fb449eb..e082e3211955 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1317,7 +1317,7 @@ <string name="select_character" msgid="3352797107930786979">"درج نویسه"</string> <string name="sms_control_title" msgid="4748684259903148341">"درحال ارسال پیامکها"</string> <string name="sms_control_message" msgid="6574313876316388239">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> درحال ارسال تعداد زیادی پیامک است. آیا اجازه میدهید این برنامه همچنان پیامک ارسال کند؟"</string> - <string name="sms_control_yes" msgid="4858845109269524622">"مجاز است"</string> + <string name="sms_control_yes" msgid="4858845109269524622">"اجازه دادن"</string> <string name="sms_control_no" msgid="4845717880040355570">"مجاز نبودن"</string> <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> مایل است پیامی به <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> ارسال کند."</string> <string name="sms_short_code_details" msgid="2723725738333388351">"این مورد "<b>"شاید هزینهای"</b>" را به حساب دستگاه همراهتان بگذارد."</string> @@ -1689,7 +1689,7 @@ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"میتواند همه محتوای صفحه را بخواند و آن را روی بقیه برنامهها نمایش دهد."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"مشاهده و انجام کنشها"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"این عملکرد میتواند با برنامه یا حسگری سختافزاری تعاملاتتان را ردیابی کند و ازطرف شما با برنامهها تعامل داشته باشد."</string> - <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"مجاز"</string> + <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"اجازه دادن"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"مجاز نبودن"</string> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"برای استفاده از ویژگی، روی آن ضربه بزنید:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"انتخاب ویژگیهای موردنظر برای استفاده با دکمه دسترسپذیری"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index eab052cac455..a971242639ef 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -2266,7 +2266,7 @@ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Novas opcións de configuración de ampliación"</string> <string name="window_magnification_prompt_content" msgid="8159173903032344891">"Xa podes ampliar parte da pantalla"</string> <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activar en Configuración"</string> - <string name="dismiss_action" msgid="1728820550388704784">"Ignorar"</string> + <string name="dismiss_action" msgid="1728820550388704784">"Pechar"</string> <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Desbloquea o micrófono do dispositivo"</string> <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Desbloquea a cámara do dispositivo"</string> <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para <b><xliff:g id="APP">%s</xliff:g></b> e todas as aplicacións e servizos"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index f18af9dff1d6..6074b4a5f9fc 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -245,10 +245,10 @@ <string name="global_action_power_options" msgid="1185286119330160073">"Սնուցման կոճակ"</string> <string name="global_action_restart" msgid="4678451019561687074">"Վերագործարկել"</string> <string name="global_action_emergency" msgid="1387617624177105088">"Շտապ կանչ"</string> - <string name="global_action_bug_report" msgid="5127867163044170003">"Վրիպակի զեկույց"</string> + <string name="global_action_bug_report" msgid="5127867163044170003">"Հաղորդում վրիպակի մասին"</string> <string name="global_action_logout" msgid="6093581310002476511">"Ավարտել աշխատաշրջանը"</string> <string name="global_action_screenshot" msgid="2610053466156478564">"Սքրինշոթ"</string> - <string name="bugreport_title" msgid="8549990811777373050">"Հաշվետվություն վրիպակի մասին"</string> + <string name="bugreport_title" msgid="8549990811777373050">"Հաղորդում վրիպակի մասին"</string> <string name="bugreport_message" msgid="5212529146119624326">"Սա տեղեկություններ կհավաքագրի ձեր սարքի առկա կարգավիճակի մասին և կուղարկի այն էլեկտրոնային նամակով: Որոշակի ժամանակ կպահանջվի վրիպակի մասին զեկուցելու պահից սկսած մինչ ուղարկելը: Խնդրում ենք փոքր-ինչ համբերատար լինել:"</string> <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Ինտերակտիվ զեկույց"</string> <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Հիմնականում օգտագործեք այս տարբերակը: Այն ձեզ թույլ է տալիս հետևել զեկույցի ստեղծման գործընթացին, խնդրի մասին լրացուցիչ տեղեկություններ մուտքագրել և սքրինշոթներ ստեղծել: Կարող է բաց թողնել քիչ օգտագործվող որոշ բաժիններ, որոնց ստեղծումը երկար է տևում:"</string> @@ -1377,7 +1377,7 @@ <string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"USB միացքը կարող է օգտագործվել"</string> <string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"Հեռախոսում ջուր կամ աղտ չի հայտնաբերվել:"</string> <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Վրիպակի զեկույցի ստեղծում…"</string> - <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Տրամադրե՞լ վրիպակի զեկույցը:"</string> + <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Կիսվե՞լ վրիպակի մասին հաղորդմամբ"</string> <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Վրիպակի զեկույցի տրամադրում…"</string> <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Այս սարքի անսարքությունների վերացման նպատակով ձեր ադմինիստրատորին անհրաժեշտ է վրիպակի հաշվետվություն: Կարող են տրամադրվել տեղեկություններ հավելվածների մասին և այլ տվյալներ։"</string> <string name="share_remote_bugreport_action" msgid="7630880678785123682">"ՏՐԱՄԱԴՐԵԼ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 54377f7f4ff2..5ecea3fd4c1e 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1701,7 +1701,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"단축키 사용"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"색상 반전"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"색상 보정"</string> - <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"한 손 사용 모드"</string> + <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"한 손 모드"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"더 어둡게"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index bfc02345835e..85a58c2ff40f 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -221,7 +221,7 @@ <string name="silent_mode_silent" msgid="5079789070221150912">"Коңгуроо өчүк"</string> <string name="silent_mode_vibrate" msgid="8821830448369552678">"Чалганда титирөө"</string> <string name="silent_mode_ring" msgid="6039011004781526678">"Коңгуроо жандырылган"</string> - <string name="reboot_to_update_title" msgid="2125818841916373708">"Android тутум жаңыртуусу"</string> + <string name="reboot_to_update_title" msgid="2125818841916373708">"Android системасын жаңыртуу"</string> <string name="reboot_to_update_prepare" msgid="6978842143587422365">"Жаңыртууга даярдалууда…"</string> <string name="reboot_to_update_package" msgid="4644104795527534811">"Жаңыртуу топтому иштелүүдө…"</string> <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Өчүрүлүп күйгүзүлүүдө…"</string> @@ -1675,10 +1675,10 @@ <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ыкчам иштетесизби?"</string> <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Атайын мүмкүнчүлүктөр функциясын пайдалануу үчүн ал күйгүзүлгөндө, үндү катуулатып/акырындаткан эки баскычты тең 3 секунддай коё бербей басып туруңуз."</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Атайын мүмкүнчүлүктөрдүн ыкчам баскычын иштетесизби?"</string> - <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Атайын мүмкүнчүлүктөр функциясын иштетүү үчүн үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nУчурдагы функциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТандалган функцияларды өзгөртүү үчүн Жөндөөлөр > Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string> + <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Атайын мүмкүнчүлүктөр функциясын иштетүү үчүн үндү катуулатуу/акырындатуу баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nУчурдагы функциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТандалган функцияларды өзгөртүү үчүн Жөндөөлөр > Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string> <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string> <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"<xliff:g id="SERVICE">%1$s</xliff:g> ыкчам баскычын иштетесизби?"</string> - <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматын иштетүү үчүн үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nБаскычтардын ушул айкалышын башка функцияга дайындоо үчүн, Жөндөөлөр > Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string> + <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматын иштетүү үчүн үндү катуулатуу/акырындатуу баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nБаскычтардын ушул айкалышын башка функцияга дайындоо үчүн, Жөндөөлөр > Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ооба"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Жок"</string> <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"КҮЙҮК"</string> @@ -1686,7 +1686,7 @@ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматына түзмөгүңүздү толугу менен көзөмөлдөөгө уруксат бересизби?"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Толук көзөмөл атайын мүмкүнчүлүктөрдү пайдаланууга керек, бирок калган көпчүлүк колдонмолорго кереги жок."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Экранды көрүп, көзөмөлдөө"</string> - <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Кызмат экрандагы нерселерди окуп, материалды башка колдонмолордун үстүнөн көрсөтөт."</string> + <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Кызмат экрандагы нерселерди окуп, аларды башка колдонмолордун үстүнөн көрсөтөт."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Аракеттерди көрүп, аткаруу"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Кызмат колдонмодо жасаган аракеттериңизге же түзмөктүн сенсорлоруна көз салып, сиздин атыңыздан буйруктарды берет."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Уруксат берүү"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index c151712ed8ab..76947429d55a 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1686,7 +1686,7 @@ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> എന്നതിന് നിങ്ങളുടെ ഉപകരണത്തിന്മേൽ പൂർണ്ണ നിയന്ത്രണം അനുവദിക്കണോ?"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"ഉപയോഗസഹായി ആവശ്യങ്ങൾക്കായി നിങ്ങളെ സഹായിക്കുന്ന ആപ്പുകൾക്ക് പൂർണ്ണ നിയന്ത്രണം അനുയോജ്യമാണെങ്കിലും മിക്ക ആപ്പുകൾക്കും അനുയോജ്യമല്ല."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"സ്ക്രീൻ കാണുക, നിയന്ത്രിക്കുക"</string> - <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ഇതിന് സ്ക്രീനിലെ എല്ലാ ഉള്ളടക്കവും വായിക്കാനും മറ്റ് ആപ്പുകളിൽ ഉള്ളടക്കം പ്രദർശിപ്പിക്കാനുമാവും."</string> + <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ഇതിന് സ്ക്രീനിലെ എല്ലാ ഉള്ളടക്കവും വായിക്കാനും മറ്റ് ആപ്പുകൾക്ക് മുകളിൽ ഉള്ളടക്കം പ്രദർശിപ്പിക്കാനുമാകും."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"കാണുക, പ്രവർത്തനങ്ങൾ നിർവഹിക്കുക"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ഇതിന് ഒരു ആപ്പുമായോ ഹാർഡ്വെയർ സെൻസറുമായോ ഉള്ള നിങ്ങളുടെ ആശയവിനിമയങ്ങൾ ട്രാക്ക് ചെയ്യാനും നിങ്ങളുടെ പേരിൽ ആശയവിനിമയം നടത്താനും കഴിയും."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"അനുവദിക്കൂ"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index f0d1b8e4c8eb..cfb85c6352c9 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -103,7 +103,7 @@ <string name="serviceClassVoice" msgid="2065556932043454987">"व्हॉइस"</string> <string name="serviceClassData" msgid="4148080018967300248">"डेटा"</string> <string name="serviceClassFAX" msgid="2561653371698904118">"फॅक्स"</string> - <string name="serviceClassSMS" msgid="1547664561704509004">"SMS"</string> + <string name="serviceClassSMS" msgid="1547664561704509004">"एसएमएस"</string> <string name="serviceClassDataAsync" msgid="2029856900898545984">"असंकालिक"</string> <string name="serviceClassDataSync" msgid="7895071363569133704">"सिंक करा"</string> <string name="serviceClassPacket" msgid="1430642951399303804">"पॅकेट"</string> @@ -303,7 +303,7 @@ <string name="permgroupdesc_location" msgid="1995955142118450685">"या डिव्हाइसच्या स्थानावर प्रवेश"</string> <string name="permgrouplab_calendar" msgid="6426860926123033230">"कॅलेंडर"</string> <string name="permgroupdesc_calendar" msgid="6762751063361489379">"आपल्या कॅलेंडरवर प्रवेश"</string> - <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string> + <string name="permgrouplab_sms" msgid="795737735126084874">"एसएमएस"</string> <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS मेसेज पाठवणे आणि पाहणे हे"</string> <string name="permgrouplab_storage" msgid="5570124978732352858">"फाइल आणि दस्तऐवज"</string> <string name="permgroupdesc_storage" msgid="8352226729501080525">"तुमच्या डिव्हाइसवर फाइल आणि दस्तऐवज अॅक्सेस करा"</string> @@ -1688,7 +1688,7 @@ <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"स्क्रीन पहा आणि नियंत्रित करा"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ते स्क्रीनवरील सर्व आशय वाचू शकते आणि इतर ॲप्सवर आशय प्रदर्शित करू शकते."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"पहा आणि क्रिया करा"</string> - <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"तुम्ही ॲप किंवा हार्डवेअर सेन्सर कसे वापरता याचा हे मागोवा घेऊ शकते आणि इतर ॲप्ससोबत तुमच्या वतीने काम करू शकते."</string> + <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"हे तुम्ही ॲप किंवा हार्डवेअर सेन्सर कसे वापरता ते ट्रॅक करू शकते आणि इतर ॲप्ससोबत तुमच्या वतीने संवाद साधू शकते."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"अनुमती द्या"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"नकार द्या"</string> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"वैशिष्ट्य वापरणे सुरू करण्यासाठी त्यावर टॅप करा:"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index c00e7ba94e0f..ea8023415a76 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1686,7 +1686,7 @@ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> ကို သင့်စက်အား အပြည့်အဝထိန်းချုပ်ခွင့် ပေးလိုပါသလား။"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"အများသုံးစွဲနိုင်မှု လိုအပ်ချက်များအတွက် အထောက်အကူပြုသည့် အက်ပ်များအား အပြည့်အဝ ထိန်းချုပ်ခွင့်ပေးခြင်းသည် သင့်လျော်သော်လည်း အက်ပ်အများစုအတွက် မသင့်လျော်ပါ။"</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"ဖန်သားပြင်ကို ကြည့်ရှုထိန်းချုပ်ခြင်း"</string> - <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"၎င်းသည် မျက်နှာပြင်ပေါ်ရှိ အကြောင်းအရာများအားလုံးကို ဖတ်နိုင်ပြီး အခြားအက်ပ်များအပေါ်တွင် ထိုအကြောင်းအရာကို ဖော်ပြနိုင်သည်။"</string> + <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"၎င်းသည် မျက်နှာပြင်ပေါ်ရှိ အကြောင်းအရာအားလုံးကို ဖတ်နိုင်ပြီး အခြားအက်ပ်များအပေါ်တွင် အကြောင်းအရာကို ဖော်ပြနိုင်သည်။"</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"လုပ်ဆောင်ချက်များကို ကြည့်ရှုဆောင်ရွက်ခြင်း"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"၎င်းသည် အက်ပ်တစ်ခု သို့မဟုတ် အာရုံခံကိရိယာကို အသုံးပြု၍ သင့်ပြန်လှန်တုံ့ပြန်မှုများကို မှတ်သားနိုင်ပြီး သင့်ကိုယ်စား အက်ပ်များနှင့် ပြန်လှန်တုံ့ပြန်နိုင်သည်။"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ခွင့်ပြုရန်"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index e61d38e59391..c59ba63bc9ed 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1684,9 +1684,9 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AAN"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"UIT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Toestaan dat <xliff:g id="SERVICE">%1$s</xliff:g> volledige controle over je apparaat heeft?"</string> - <string name="accessibility_service_warning_description" msgid="291674995220940133">"Volledige controle is gepast voor apps die je helpen met toegankelijkheid, maar voor de meeste apps is het ongepast."</string> + <string name="accessibility_service_warning_description" msgid="291674995220940133">"Volledige controle is gepast voor apps die je helpen met toegankelijkheid, maar niet voor de meeste apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Scherm bekijken en bedienen"</string> - <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"De functie kan alle content op het scherm lezen en content bovenop andere apps weergeven"</string> + <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"De functie kan alle content op het scherm lezen en content bovenop andere apps weergeven."</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Acties bekijken en uitvoeren"</string> <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"De functie kan je interacties met een app of een hardwaresensor bijhouden en namens jou met apps communiceren."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Toestaan"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 28bfaa138373..183940d2ec8b 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -351,7 +351,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Aplikaciji omogoča razširjanje ali strnjevanje vrstice stanja."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Prikaz obvestil kot celozaslonskih dejavnosti v zaklenjeni napravi"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Aplikaciji dovoli, da prikaže obvestila kot celozaslonske dejavnosti v zaklenjeni napravi."</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"nameščanje bližnjic"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Nameščanje bližnjic"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Aplikaciji omogoča dodajanje bližnjic na začetni zaslon brez posredovanja uporabnika."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odstranjevanje bližnjic"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Aplikaciji omogoča odstranjevanje bližnjic z začetnega zaslona brez posredovanja uporabnika."</string> @@ -1704,7 +1704,7 @@ <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija barv"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Popravljanje barv"</string> <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enoročni način"</string> - <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Zelo zatemnjeno"</string> + <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Zelo zatemnjen zaslon"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Za uporabo storitve <xliff:g id="SERVICE_NAME">%1$s</xliff:g> pritisnite obe tipki za glasnost in ju pridržite tri sekunde"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index ded84dfcc4c5..2298c1ce3b46 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1684,7 +1684,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"เปิด"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ปิด"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"อนุญาตให้ <xliff:g id="SERVICE">%1$s</xliff:g> ควบคุมอุปกรณ์อย่างเต็มที่ไหม"</string> - <string name="accessibility_service_warning_description" msgid="291674995220940133">"การควบคุมอย่างเต็มที่เหมาะสำหรับแอปที่ช่วยคุณในเรื่องความต้องการความช่วยเหลือพิเศษแต่ไม่เหมาะสำหรับแอปส่วนใหญ่"</string> + <string name="accessibility_service_warning_description" msgid="291674995220940133">"การควบคุมอย่างเต็มที่เหมาะสำหรับแอปเกี่ยวกับความช่วยเหลือพิเศษ แต่ไม่เหมาะสำหรับแอปส่วนใหญ่"</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"ดูและควบคุมหน้าจอ"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"การควบคุมนี้สามารถอ่านเนื้อหาทั้งหมดบนหน้าจอและแสดงเนื้อหาทับแอปอื่นๆ"</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"ดูและดำเนินการ"</string> @@ -1717,7 +1717,7 @@ <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> + <string name="guest_name" msgid="8502103277839834324">"ผู้ใช้ชั่วคราว"</string> <string name="error_message_title" msgid="4082495589294631966">"ข้อผิดพลาด"</string> <string name="error_message_change_not_allowed" msgid="843159705042381454">"ผู้ดูแลระบบไม่อนุญาตให้ทำการเปลี่ยนแปลงนี้"</string> <string name="app_not_found" msgid="3429506115332341800">"ไม่พบแอปพลิเคชันสำหรับการทำงานนี้"</string> @@ -1963,7 +1963,7 @@ <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"เชื่อมต่อ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> แล้ว"</string> <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"แตะเพื่อดูไฟล์"</string> <string name="pin_target" msgid="8036028973110156895">"ปักหมุด"</string> - <string name="pin_specific_target" msgid="7824671240625957415">"ตรึง <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="pin_specific_target" msgid="7824671240625957415">"ปักหมุด <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="unpin_target" msgid="3963318576590204447">"เลิกปักหมุด"</string> <string name="unpin_specific_target" msgid="3859828252160908146">"เลิกปักหมุด <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="app_info" msgid="6113278084877079851">"ข้อมูลแอป"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 6d1ed06bf024..75e72e2b653d 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -1686,9 +1686,9 @@ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> کو آپ کے آلے کا مکمل کنٹرول حاصل کرنے کی اجازت دیں؟"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"مکمل کنٹرول ان ایپس کے لیے مناسب ہے جو ایکسیسبیلٹی کی ضروریات میں آپ کی مدد کرتی ہیں، لیکن زیادہ تر ایپس کیلئے مناسب نہیں۔"</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"اسکرین کو دیکھیں اور کنٹرول کریں"</string> - <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"یہ تمام مواد کو اسکرین پر پڑھ اور دیگر ایپس پر مواد کو ڈسپلے کر سکتا ہے۔"</string> + <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"یہ اسکرین پر موجود تمام مواد کو پڑھ سکتا ہے اور دیگر ایپس پر مواد کو ڈسپلے کر سکتا ہے۔"</string> <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"کارروائیاں دیکھیں اور انجام دیں"</string> - <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"یہ آپ کے تعاملات کو ایپ یا ہارڈویئر سینسر کے ذریعے ٹریک کر سکتا ہے، اور آپ کی طرف سے ایپ کے ساتھ تعمل کر سکتا ہے۔"</string> + <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"یہ کسی ایپ یا ہارڈویئر سینسر کے ساتھ آپ کے تعاملات کو ٹریک کر سکتا ہے، اور آپ کی طرف سے ایپس کے ساتھ تعامل کر سکتا ہے۔"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"اجازت دیں"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"مسترد کریں"</string> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ایک خصوصیت کا استعمال شروع کرنے کیلئے اسے تھپتھپائیں:"</string> @@ -1702,7 +1702,7 @@ <string name="color_inversion_feature_name" msgid="326050048927789012">"رنگوں کی تقلیب"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"رنگ کی تصحیح"</string> <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ایک ہاتھ کی وضع"</string> - <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"اضافی دھندلا"</string> + <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"اضافی مدھم"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آن ہے۔"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آف ہے۔"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> کا استعمال کرنے کے لیے 3 سیکنڈ تک والیوم کی دونوں کلیدوں کو چھوئیں اور دبائے رکھیں"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 9be893965360..985af204367d 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -581,7 +581,7 @@ <string name="biometric_error_user_canceled" msgid="6732303949695293730">"已取消驗證"</string> <string name="biometric_not_recognized" msgid="5106687642694635888">"未能識別"</string> <string name="biometric_error_canceled" msgid="8266582404844179778">"已取消驗證"</string> - <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN、圖形或密碼"</string> + <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN、圖案或密碼"</string> <string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定解鎖憑證"</string> @@ -781,7 +781,7 @@ <string name="policylab_setGlobalProxy" msgid="215332221188670221">"設定裝置的全域代理伺服器"</string> <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"設定政策啟用時所要使用的裝置全域代理伺服器,只有裝置擁有者可以設定全域代理伺服器。"</string> <string name="policylab_expirePassword" msgid="6015404400532459169">"設定螢幕鎖定密碼期限"</string> - <string name="policydesc_expirePassword" msgid="9136524319325960675">"變更螢幕鎖定密碼、PIN 或圖形的更改頻率。"</string> + <string name="policydesc_expirePassword" msgid="9136524319325960675">"變更螢幕鎖定密碼、PIN 或圖案的更改頻率。"</string> <string name="policylab_encryptedStorage" msgid="9012936958126670110">"設定儲存裝置加密"</string> <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"必須為儲存的應用程式資料加密。"</string> <string name="policylab_disableCamera" msgid="5749486347810162018">"停用相機"</string> @@ -916,7 +916,7 @@ <string name="lockscreen_screen_locked" msgid="7364905540516041817">"螢幕已鎖定。"</string> <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"按選單鍵解鎖或撥打緊急電話。"</string> <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"按選單鍵解鎖。"</string> - <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"畫出解鎖圖形來為螢幕解鎖"</string> + <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"畫出解鎖圖案來為螢幕解鎖"</string> <string name="lockscreen_emergency_call" msgid="7500692654885445299">"緊急電話"</string> <string name="lockscreen_return_to_call" msgid="3156883574692006382">"返回通話"</string> <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"正確!"</string> @@ -945,12 +945,12 @@ <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"請參閱使用者指南或與客戶服務中心聯絡。"</string> <string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"SIM 卡處於鎖定狀態。"</string> <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"正在解除 SIM 卡鎖定..."</string> - <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> + <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用 Google 登入資料將 Android TV 裝置解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用 Google 登入資料將 Android TV 裝置解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"您嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,平板電腦將恢復原廠設定,所有使用者資料均會遺失。"</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"您嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,手機將恢復原廠設定,所有使用者資料均會遺失。"</string> @@ -958,9 +958,9 @@ <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次無法解鎖 Android TV 裝置,Android TV 裝置現在將回復原廠設定。"</string> <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"您嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。手機現在會重設為原廠預設值。"</string> <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"<xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string> - <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"忘記圖形?"</string> + <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"忘記圖案?"</string> <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"帳戶解鎖"</string> - <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"圖形嘗試次數過多"</string> + <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"圖案嘗試次數過多"</string> <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"如要解鎖,請以 Google 帳戶登入。"</string> <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"使用者名稱 (電子郵件)"</string> <string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"密碼"</string> @@ -971,12 +971,12 @@ <string name="lockscreen_unlock_label" msgid="4648257878373307582">"解除鎖定"</string> <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"開啟音效"</string> <string name="lockscreen_sound_off_label" msgid="2331496559245450053">"關閉音效"</string> - <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"已開始繪畫解鎖圖形"</string> - <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"已清除解鎖圖形"</string> + <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"已開始繪畫解鎖圖案"</string> + <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"已清除解鎖圖案"</string> <string name="lockscreen_access_pattern_cell_added" msgid="6746676335293144163">"已加入一格"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="2931364927622563465">"已加入 <xliff:g id="CELL_INDEX">%1$s</xliff:g> 點"</string> - <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"已畫出解鎖圖形"</string> - <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"圖形區域。"</string> + <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"已畫出解鎖圖案"</string> + <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"圖案區域。"</string> <string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</string> <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"新增小工具。"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"空白"</string> @@ -992,13 +992,13 @@ <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>小工具已刪除。"</string> <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"展開解鎖區域。"</string> <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"滑動解鎖。"</string> - <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"圖形解鎖。"</string> + <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"圖案解鎖。"</string> <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"面孔解鎖。"</string> <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"PIN 解鎖。"</string> <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIM 卡 PIN 碼解鎖。"</string> <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIM 卡 PUK 解鎖。"</string> <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"密碼解鎖。"</string> - <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"圖形區域。"</string> + <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"圖案區域。"</string> <string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"滑動區域。"</string> <string name="password_keyboard_label_symbol_key" msgid="2716255580853511949">"?123"</string> <string name="password_keyboard_label_alpha_key" msgid="5294837425652726684">"ABC"</string> @@ -1632,11 +1632,11 @@ <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"重疊效果 #<xliff:g id="ID">%1$d</xliff:g>"</string> <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>:<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>,<xliff:g id="DPI">%4$d</xliff:g> dpi"</string> <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">"(安全)"</string> - <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"忘記了圖形"</string> - <string name="kg_wrong_pattern" msgid="1342812634464179931">"圖形錯誤"</string> + <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"忘記了圖案"</string> + <string name="kg_wrong_pattern" msgid="1342812634464179931">"圖案錯誤"</string> <string name="kg_wrong_password" msgid="2384677900494439426">"密碼錯誤"</string> <string name="kg_wrong_pin" msgid="3680925703673166482">"PIN 錯誤"</string> - <string name="kg_pattern_instructions" msgid="8366024510502517748">"畫出圖形"</string> + <string name="kg_pattern_instructions" msgid="8366024510502517748">"畫出圖案"</string> <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"輸入 SIM 卡 PIN 碼"</string> <string name="kg_pin_instructions" msgid="7355933174673539021">"輸入 PIN 碼"</string> <string name="kg_password_instructions" msgid="7179782578809398050">"輸入密碼"</string> @@ -1649,7 +1649,7 @@ <string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK 碼應由 8 位數字組成。"</string> <string name="kg_invalid_puk" msgid="4809502818518963344">"請重新輸入正確的 PUK 碼。如果嘗試輸入的次數過多,SIM 卡將永久停用。"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN 碼不符"</string> - <string name="kg_login_too_many_attempts" msgid="699292728290654121">"圖形嘗試次數過多"</string> + <string name="kg_login_too_many_attempts" msgid="699292728290654121">"圖案嘗試次數過多"</string> <string name="kg_login_instructions" msgid="3619844310339066827">"如要解鎖,請以 Google 帳戶登入。"</string> <string name="kg_login_username_hint" msgid="1765453775467133251">"使用者名稱 (電子郵件)"</string> <string name="kg_login_password_hint" msgid="3330530727273164402">"密碼"</string> @@ -1659,16 +1659,16 @@ <string name="kg_login_checking_password" msgid="4676010303243317253">"正在檢查帳戶…"</string> <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> - <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> + <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"您嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有使用者資料均會失去。"</string> <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string> <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"您嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,手機將回復原廠設定,所有使用者資料均會失去。"</string> <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。平板電腦現在將回復原廠設定。"</string> <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次無法解鎖 Android TV 裝置,Android TV 裝置現在將回復原廠設定。"</string> <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。手機現在將回復原廠設定。"</string> - <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> - <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用電郵帳戶解鎖 Android TV 裝置。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> - <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> + <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> + <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用電郵帳戶解鎖 Android TV 裝置。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"移除"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量 (比建議的音量更大聲) 嗎?\n\n長時間聆聽高分貝音量可能會導致您的聽力受損。"</string> @@ -1848,7 +1848,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"第二個工作<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"第三個工作<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"取消固定時必須輸入 PIN"</string> - <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須提供解鎖圖形"</string> + <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須提供解鎖圖案"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string> <string name="package_installed_device_owner" msgid="7035926868974878525">"已由您的管理員安裝"</string> <string name="package_updated_device_owner" msgid="7560272363805506941">"已由您的管理員更新"</string> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 5df3dde82b3e..b515abc4000f 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -448,5 +448,6 @@ <color name="accessibility_color_inversion_background">#546E7A</color> <!-- Color of camera light when camera is in use --> - <color name="camera_privacy_light">#FFFFFF</color> + <color name="camera_privacy_light_day">#FFFFFF</color> + <color name="camera_privacy_light_night">#FFFFFF</color> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index e38b5b6fbc39..4641cd75d7f0 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -5133,16 +5133,24 @@ --> <color name="config_letterboxBackgroundColor">@android:color/system_neutral2_900</color> - <!-- Horizonal position of a center of the letterboxed app window. + <!-- Horizontal position of a center of the letterboxed app window. 0 corresponds to the left side of the screen and 1 to the right side. If given value < 0 - or > 1, it is ignored and central positionis used (0.5). --> + or > 1, it is ignored and central position is used (0.5). --> <item name="config_letterboxHorizontalPositionMultiplier" format="float" type="dimen">0.5</item> - <!-- Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape - device orientation. --> - <bool name="config_letterboxIsReachabilityEnabled">false</bool> + <!-- Vertical position of a center of the letterboxed app window. + 0 corresponds to the upper side of the screen and 1 to the lower side. If given value < 0 + or > 1, it is ignored and central position is used (0.5). --> + <item name="config_letterboxVerticalPositionMultiplier" format="float" type="dimen">0.5</item> - <!-- Default horizonal position of the letterboxed app window when reachability is + <!-- Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps. + --> + <bool name="config_letterboxIsHorizontalReachabilityEnabled">false</bool> + + <!-- Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps. --> + <bool name="config_letterboxIsVerticalReachabilityEnabled">false</bool> + + <!-- Default horizontal position of the letterboxed app window when reachability is enabled and an app is fullscreen in landscape device orientation. When reachability is enabled, the position can change between left, center and right. This config defines the default one: @@ -5150,7 +5158,17 @@ - Option 1 - Center. - Option 2 - Right. If given value is outside of this range, the option 1 (center) is assummed. --> - <integer name="config_letterboxDefaultPositionForReachability">1</integer> + <integer name="config_letterboxDefaultPositionForHorizontalReachability">1</integer> + + <!-- Default vertical position of the letterboxed app window when reachability is + enabled and an app is fullscreen in portrait device orientation. When reachability is + enabled, the position can change between top, center and bottom. This config defines the + default one: + - Option 0 - Top. + - Option 1 - Center. + - Option 2 - Bottom. + If given value is outside of this range, the option 1 (center) is assummed. --> + <integer name="config_letterboxDefaultPositionForVerticalReachability">1</integer> <!-- Whether displaying letterbox education is enabled for letterboxed fullscreen apps. --> <bool name="config_letterboxIsEducationEnabled">false</bool> @@ -5665,6 +5683,9 @@ <!-- Whether or not to enable the lock screen entry point for the QR code scanner. --> <bool name="config_enableQrCodeScannerOnLockScreen">false</bool> + <!-- Default component for QR code scanner --> + <string name="config_defaultQrCodeComponent"></string> + <!-- Whether Low Power Standby is supported and can be enabled. --> <bool name="config_lowPowerStandbySupported">false</bool> @@ -5790,4 +5811,9 @@ <!-- List of the labels of requestable device state config values --> <string-array name="config_deviceStatesAvailableForAppRequests"/> + + <!-- Interval in milliseconds to average light sensor values for camera light brightness --> + <integer name="config_cameraPrivacyLightAlsAveragingIntervalMillis">3000</integer> + <!-- Light sensor's lux value to use as the threshold between using day or night brightness --> + <integer name="config_cameraPrivacyLightAlsNightThreshold">4</integer> </resources> diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml index d9ac5164f705..682ce46d132d 100644 --- a/core/res/res/values/config_telephony.xml +++ b/core/res/res/values/config_telephony.xml @@ -35,7 +35,7 @@ rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max If this is configured as an empty string, the system default will be applied. --> - <string name="config_tcp_buffers" translatable="false"></string> + <string name="config_tcp_buffers" translatable="false">2097152,6291456,16777216,512000,2097152,8388608</string> <java-symbol type="string" name="config_tcp_buffers" /> <!-- What source to use to estimate link upstream and downstream bandwidth capacities. diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f505ffb21e2f..ed723500081c 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4384,8 +4384,11 @@ <java-symbol type="integer" name="config_letterboxBackgroundType" /> <java-symbol type="color" name="config_letterboxBackgroundColor" /> <java-symbol type="dimen" name="config_letterboxHorizontalPositionMultiplier" /> - <java-symbol type="bool" name="config_letterboxIsReachabilityEnabled" /> - <java-symbol type="integer" name="config_letterboxDefaultPositionForReachability" /> + <java-symbol type="dimen" name="config_letterboxVerticalPositionMultiplier" /> + <java-symbol type="bool" name="config_letterboxIsHorizontalReachabilityEnabled" /> + <java-symbol type="bool" name="config_letterboxIsVerticalReachabilityEnabled" /> + <java-symbol type="integer" name="config_letterboxDefaultPositionForHorizontalReachability" /> + <java-symbol type="integer" name="config_letterboxDefaultPositionForVerticalReachability" /> <java-symbol type="bool" name="config_letterboxIsEducationEnabled" /> <java-symbol type="bool" name="config_isCameraCompatControlForStretchedIssuesEnabled" /> @@ -4714,6 +4717,7 @@ <java-symbol type="string" name="config_wearSysUiPackage"/> <java-symbol type="string" name="config_wearSysUiMainActivity"/> + <java-symbol type="string" name="config_defaultQrCodeComponent"/> <java-symbol type="dimen" name="secondary_rounded_corner_radius" /> <java-symbol type="dimen" name="secondary_rounded_corner_radius_top" /> @@ -4759,7 +4763,10 @@ <!-- For VirtualDeviceManager --> <java-symbol type="string" name="vdm_camera_access_denied" /> - <java-symbol type="color" name="camera_privacy_light"/> + <java-symbol type="color" name="camera_privacy_light_day"/> + <java-symbol type="color" name="camera_privacy_light_night"/> + <java-symbol type="integer" name="config_cameraPrivacyLightAlsAveragingIntervalMillis"/> + <java-symbol type="integer" name="config_cameraPrivacyLightAlsNightThreshold"/> <java-symbol type="bool" name="config_bg_current_drain_monitor_enabled" /> <java-symbol type="array" name="config_bg_current_drain_threshold_to_restricted_bucket" /> diff --git a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java index c9a18dafe11d..c9e02f8a998d 100644 --- a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java +++ b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java @@ -38,8 +38,8 @@ import static org.junit.Assert.assertTrue; import android.os.Parcel; import android.platform.test.annotations.Presubmit; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; import com.android.internal.widget.PasswordValidationError; @@ -324,9 +324,59 @@ public class PasswordMetricsTest { PasswordValidationError.WEAK_CREDENTIAL_TYPE, 0); } + @Test + public void testValidatePasswordMetrics_pinAndComplexityHigh() { + PasswordMetrics adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PIN); + PasswordMetrics actualMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PIN); + actualMetrics.length = 6; + actualMetrics.seqLength = 1; + + assertValidationErrors( + validatePasswordMetrics(adminMetrics, PASSWORD_COMPLEXITY_HIGH, actualMetrics), + PasswordValidationError.TOO_SHORT, 8); + } + + @Test + public void testValidatePasswordMetrics_nonAllNumberPasswordAndComplexityHigh() { + PasswordMetrics adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PASSWORD); + PasswordMetrics actualMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PASSWORD); + actualMetrics.length = 5; + actualMetrics.nonNumeric = 1; + actualMetrics.seqLength = 1; + + assertValidationErrors( + validatePasswordMetrics(adminMetrics, PASSWORD_COMPLEXITY_HIGH, actualMetrics), + PasswordValidationError.TOO_SHORT, 6); + } + + @Test + public void testValidatePasswordMetrics_allNumberPasswordAndComplexityHigh() { + PasswordMetrics adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PASSWORD); + PasswordMetrics actualMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PASSWORD); + actualMetrics.length = 6; + actualMetrics.seqLength = 1; + + assertValidationErrors( + validatePasswordMetrics(adminMetrics, PASSWORD_COMPLEXITY_HIGH, actualMetrics), + PasswordValidationError.TOO_SHORT_WHEN_ALL_NUMERIC, 8); + } + + @Test + public void testValidatePasswordMetrics_allNumberPasswordAndRequireNonNumeric() { + PasswordMetrics adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PASSWORD); + adminMetrics.nonNumeric = 1; + PasswordMetrics actualMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PASSWORD); + actualMetrics.length = 6; + actualMetrics.seqLength = 1; + + assertValidationErrors( + validatePasswordMetrics(adminMetrics, PASSWORD_COMPLEXITY_HIGH, actualMetrics), + PasswordValidationError.NOT_ENOUGH_NON_DIGITS, 1); + } + /** * @param expected sequense of validation error codes followed by requirement values, must have - * even number of elements. Empty means no errors. + * even number of elements. Empty means no errors. */ private void assertValidationErrors( List<PasswordValidationError> actualErrors, int... expected) { diff --git a/core/tests/coretests/src/android/content/pm/AppSearchShortcutInfoTest.java b/core/tests/coretests/src/android/content/pm/AppSearchShortcutInfoTest.java index 969357f66dde..22feecbd899f 100644 --- a/core/tests/coretests/src/android/content/pm/AppSearchShortcutInfoTest.java +++ b/core/tests/coretests/src/android/content/pm/AppSearchShortcutInfoTest.java @@ -24,7 +24,6 @@ import android.content.Intent; import android.platform.test.annotations.Presubmit; import android.util.ArraySet; -import org.junit.Ignore; import org.junit.Test; import java.util.Set; @@ -32,7 +31,6 @@ import java.util.Set; @Presubmit public class AppSearchShortcutInfoTest { - @Ignore("b/208375334") @Test public void testBuildShortcutAndGetValue() { final String category = @@ -51,7 +49,7 @@ public class AppSearchShortcutInfoTest { final Intent shortcutIntent = new Intent(Intent.ACTION_VIEW); final ShortcutInfo shortcut = new AppSearchShortcutInfo.Builder(/*packageName=*/"", id) .setActivity(activity) - .setLongLabel(id) + .setShortLabel(id) .setIconResName(shortcutIconResName) .setIntent(shortcutIntent) .setPerson(person) @@ -64,11 +62,13 @@ public class AppSearchShortcutInfoTest { assertThat(shortcut.getId()).isEqualTo(id); assertThat(shortcut.getShortLabel()).isEqualTo(id); assertThat(shortcut.getIconResName()).isEqualTo(shortcutIconResName); - assertThat(shortcut.getIntent().toString()).isEqualTo(shortcut.toString()); + assertThat(shortcut.getIntent().toString()).isEqualTo(shortcutIntent.toString()); assertThat(shortcut.getPersons().length).isEqualTo(1); - assertThat(shortcut.getPersons()[0]).isEqualTo(person); + final Person target = shortcut.getPersons()[0]; + assertThat(target.getName()).isEqualTo(person.getName()); + assertThat(target.isBot()).isEqualTo(person.isBot()); + assertThat(target.isImportant()).isEqualTo(person.isImportant()); assertThat(shortcut.getCategories()).isEqualTo(categorySet); - assertThat(shortcut.getFlags()).isEqualTo(ShortcutInfo.FLAG_LONG_LIVED); assertThat(shortcut.getActivity()).isEqualTo(activity); } } diff --git a/core/tests/coretests/src/android/view/RenderNodeAnimatorTest.java b/core/tests/coretests/src/android/view/RenderNodeAnimatorTest.java index 786c22bf04f6..9b6bcda8aed0 100644 --- a/core/tests/coretests/src/android/view/RenderNodeAnimatorTest.java +++ b/core/tests/coretests/src/android/view/RenderNodeAnimatorTest.java @@ -19,17 +19,24 @@ package android.view; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.app.Activity; import android.content.Context; +import android.widget.FrameLayout; import androidx.test.InstrumentationRegistry; import androidx.test.annotation.UiThreadTest; import androidx.test.filters.MediumTest; import androidx.test.rule.ActivityTestRule; +import org.junit.Assert; import org.junit.Rule; import org.junit.Test; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + @MediumTest public class RenderNodeAnimatorTest { @Rule @@ -57,4 +64,46 @@ public class RenderNodeAnimatorTest { anim.start(); // should initialize mTransformationInfo assertNotNull(view.mTransformationInfo); } + + @Test + public void testViewDetachCancelsRenderNodeAnimator() { + // Start a RenderNodeAnimator with a long duration time, then detach the target view + // before the animation completes. Detaching of a View from a window should force cancel all + // RenderNodeAnimators + CountDownLatch latch = new CountDownLatch(1); + + FrameLayout container = new FrameLayout(getContext()); + View view = new View(getContext()); + + getActivity().runOnUiThread(() -> { + container.addView(view, new FrameLayout.LayoutParams(100, 100)); + getActivity().setContentView(container); + }); + getActivity().runOnUiThread(() -> { + RenderNodeAnimator anim = new RenderNodeAnimator(0, 0, 10f, 30f); + anim.setDuration(10000); + anim.setTarget(view); + anim.addListener(new AnimatorListenerAdapter() { + + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + latch.countDown(); + } + }); + + anim.start(); + }); + + getActivity().runOnUiThread(()-> { + container.removeView(view); + }); + + try { + Assert.assertTrue("onAnimationEnd not invoked", + latch.await(3000, TimeUnit.MILLISECONDS)); + } catch (InterruptedException excep) { + Assert.fail("Interrupted waiting for onAnimationEnd callback"); + } + } } diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java index 0c009a055e2b..4cf9c3fe75b9 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java @@ -39,6 +39,10 @@ public class ResolverWrapperActivity extends ResolverActivity { static final OverrideData sOverrides = new OverrideData(); private UsageStatsManager mUsm; + public ResolverWrapperActivity() { + super(/* isIntentPicker= */ true); + } + @Override public ResolverListAdapter createResolverListAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java index 2262c057d842..385879210d4a 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java @@ -35,6 +35,7 @@ import java.io.File; @RunWith(AndroidJUnit4.class) @SmallTest +@SuppressWarnings("GuardedBy") public class BatteryStatsHistoryIteratorTest { private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; @@ -124,7 +125,10 @@ public class BatteryStatsHistoryIteratorTest { // More than 32k strings final int eventCount = 0x7FFF + 100; for (int i = 0; i < eventCount; i++) { - mBatteryStats.noteAlarmStartLocked("a" + i, null, APP_UID, 3_000_000, 2_000_000); + // Names repeat in order to verify de-duping of identical history tags. + String name = "a" + (i % 10); + mBatteryStats.noteAlarmStartLocked(name, null, APP_UID, 3_000_000, 2_000_000); + mBatteryStats.noteAlarmFinishLocked(name, null, APP_UID, 3_500_000, 2_500_000); } final BatteryStatsHistoryIterator iterator = @@ -149,10 +153,23 @@ public class BatteryStatsHistoryIteratorTest { assertThat(item.time).isEqualTo(2_000_000); for (int i = 0; i < eventCount; i++) { + String name = "a" + (i % 10); assertThat(iterator.next(item)).isTrue(); + // Skip a blank event inserted at the start of every buffer + if (item.eventCode == BatteryStats.HistoryItem.EVENT_NONE) { + assertThat(iterator.next(item)).isTrue(); + } assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_START); - assertThat(item.eventTag.string).isEqualTo("a" + i); + assertThat(item.eventTag.string).isEqualTo(name); + + assertThat(iterator.next(item)).isTrue(); + if (item.eventCode == BatteryStats.HistoryItem.EVENT_NONE) { + assertThat(iterator.next(item)).isTrue(); + } + assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_ALARM + | BatteryStats.HistoryItem.EVENT_FLAG_FINISH); + assertThat(item.eventTag.string).isEqualTo(name); } assertThat(iterator.next(item)).isFalse(); diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml index ebf5832147f7..f030d80a3533 100644 --- a/data/etc/com.android.systemui.xml +++ b/data/etc/com.android.systemui.xml @@ -80,5 +80,6 @@ <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" /> <permission name="android.permission.READ_DEVICE_CONFIG" /> <permission name="android.permission.READ_SAFETY_CENTER_STATUS" /> + <permission name="android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS" /> </privapp-permissions> </permissions> diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java index 5fd53adc409a..dadbd8d2d1aa 100644 --- a/graphics/java/android/graphics/RenderNode.java +++ b/graphics/java/android/graphics/RenderNode.java @@ -1611,6 +1611,11 @@ public final class RenderNode { nEndAllAnimators(mNativeRenderNode); } + /** @hide */ + public void forceEndAnimators() { + nForceEndAnimators(mNativeRenderNode); + } + /////////////////////////////////////////////////////////////////////////// // Regular JNI methods /////////////////////////////////////////////////////////////////////////// @@ -1633,6 +1638,8 @@ public final class RenderNode { private static native void nEndAllAnimators(long renderNode); + private static native void nForceEndAnimators(long renderNode); + /////////////////////////////////////////////////////////////////////////// // @CriticalNative methods /////////////////////////////////////////////////////////////////////////// diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPrivateKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPrivateKey.java new file mode 100644 index 000000000000..4855ad0f7293 --- /dev/null +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPrivateKey.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security.keystore2; + +import android.annotation.NonNull; +import android.security.KeyStoreSecurityLevel; +import android.system.keystore2.Authorization; +import android.system.keystore2.KeyDescriptor; + +import java.security.PrivateKey; +import java.security.interfaces.EdECKey; +import java.security.spec.NamedParameterSpec; + +/** + * EdEC private key (instance of {@link PrivateKey} and {@link EdECKey}) backed by keystore. + * + * @hide + */ +public class AndroidKeyStoreEdECPrivateKey extends AndroidKeyStorePrivateKey implements EdECKey { + public AndroidKeyStoreEdECPrivateKey( + @NonNull KeyDescriptor descriptor, long keyId, + @NonNull Authorization[] authorizations, + @NonNull String algorithm, + @NonNull KeyStoreSecurityLevel securityLevel) { + super(descriptor, keyId, authorizations, algorithm, securityLevel); + } + + @Override + public NamedParameterSpec getParams() { + return NamedParameterSpec.ED25519; + } +} diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPublicKey.java new file mode 100644 index 000000000000..642e08813291 --- /dev/null +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPublicKey.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security.keystore2; + +import android.annotation.NonNull; +import android.security.KeyStoreSecurityLevel; +import android.system.keystore2.KeyDescriptor; +import android.system.keystore2.KeyMetadata; + +import java.math.BigInteger; +import java.security.interfaces.EdECPublicKey; +import java.security.spec.EdECPoint; +import java.security.spec.NamedParameterSpec; +import java.util.Arrays; +import java.util.Objects; + +/** + * {@link EdECPublicKey} backed by keystore. + * + * @hide + */ +public class AndroidKeyStoreEdECPublicKey extends AndroidKeyStorePublicKey + implements EdECPublicKey { + /** + * DER sequence, as defined in https://datatracker.ietf.org/doc/html/rfc8410#section-4 and + * https://datatracker.ietf.org/doc/html/rfc5280#section-4.1. + * SEQUENCE (2 elem) + * SEQUENCE (1 elem) + * OBJECT IDENTIFIER 1.3.101.112 curveEd25519 (EdDSA 25519 signature algorithm) + * as defined in https://datatracker.ietf.org/doc/html/rfc8410#section-3 + * BIT STRING (256 bit) as defined in + * https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2 + */ + private static final byte[] DER_KEY_PREFIX = new byte[] { + 0x30, + 0x2a, + 0x30, + 0x05, + 0x06, + 0x03, + 0x2b, + 0x65, + 0x70, + 0x03, + 0x21, + 0x00, + }; + private static final int ED25519_KEY_SIZE_BYTES = 32; + + private byte[] mEncodedKey; + private EdECPoint mPoint; + + public AndroidKeyStoreEdECPublicKey( + @NonNull KeyDescriptor descriptor, + @NonNull KeyMetadata metadata, + @NonNull String algorithm, + @NonNull KeyStoreSecurityLevel iSecurityLevel, + @NonNull byte[] encodedKey) { + super(descriptor, metadata, encodedKey, algorithm, iSecurityLevel); + mEncodedKey = encodedKey; + + int preambleLength = matchesPreamble(DER_KEY_PREFIX, encodedKey); + if (preambleLength == 0) { + throw new IllegalArgumentException("Key size is not correct size"); + } + + mPoint = pointFromKeyByteArray( + Arrays.copyOfRange(encodedKey, preambleLength, encodedKey.length)); + } + + @Override + AndroidKeyStorePrivateKey getPrivateKey() { + return new AndroidKeyStoreEdECPrivateKey( + getUserKeyDescriptor(), + getKeyIdDescriptor().nspace, + getAuthorizations(), + "EdDSA", + getSecurityLevel()); + } + + @Override + public NamedParameterSpec getParams() { + return NamedParameterSpec.ED25519; + } + + @Override + public EdECPoint getPoint() { + return mPoint; + } + + private static int matchesPreamble(byte[] preamble, byte[] encoded) { + if (encoded.length != (preamble.length + ED25519_KEY_SIZE_BYTES)) { + return 0; + } + if (Arrays.compare(preamble, Arrays.copyOf(encoded, preamble.length)) != 0) { + return 0; + } + return preamble.length; + } + + private static EdECPoint pointFromKeyByteArray(byte[] coordinates) { + Objects.requireNonNull(coordinates); + + // Oddity of the key is the most-significant bit of the last byte. + boolean isOdd = (0x80 & coordinates[coordinates.length - 1]) != 0; + // Zero out the oddity bit. + coordinates[coordinates.length - 1] &= (byte) 0x7f; + // Representation of Y is in little-endian, according to rfc8032 section-3.1. + reverse(coordinates); + // The integer representing Y starts from the first bit in the coordinates array. + BigInteger y = new BigInteger(1, coordinates); + return new EdECPoint(isOdd, y); + } + + private static void reverse(byte[] coordinateArray) { + int start = 0; + int end = coordinateArray.length - 1; + while (start < end) { + byte tmp = coordinateArray[start]; + coordinateArray[start] = coordinateArray[end]; + coordinateArray[end] = tmp; + start++; + end--; + } + } + + @Override + public byte[] getEncoded() { + return mEncodedKey.clone(); + } +} diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java index d31499e8b36d..0355628b8135 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java @@ -224,7 +224,6 @@ public class AndroidKeyStoreProvider extends Provider { String jcaKeyAlgorithm = publicKey.getAlgorithm(); - KeyStoreSecurityLevel securityLevel = iSecurityLevel; if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(jcaKeyAlgorithm)) { return new AndroidKeyStoreECPublicKey(descriptor, metadata, iSecurityLevel, (ECPublicKey) publicKey); @@ -232,8 +231,9 @@ public class AndroidKeyStoreProvider extends Provider { return new AndroidKeyStoreRSAPublicKey(descriptor, metadata, iSecurityLevel, (RSAPublicKey) publicKey); } else if (ED25519_OID.equalsIgnoreCase(jcaKeyAlgorithm)) { - //TODO(b/214203951) missing classes in conscrypt - throw new ProviderException("Curve " + ED25519_OID + " not supported yet"); + final byte[] publicKeyEncoded = publicKey.getEncoded(); + return new AndroidKeyStoreEdECPublicKey(descriptor, metadata, ED25519_OID, + iSecurityLevel, publicKeyEncoded); } else if (X25519_ALIAS.equalsIgnoreCase(jcaKeyAlgorithm)) { //TODO(b/214203951) missing classes in conscrypt throw new ProviderException("Curve " + X25519_ALIAS + " not supported yet"); diff --git a/keystore/tests/src/android/security/keystore2/AndroidKeyStoreEdECPublicKeyTest.java b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreEdECPublicKeyTest.java new file mode 100644 index 000000000000..5bd5797859c9 --- /dev/null +++ b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreEdECPublicKeyTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security.keystore2; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import android.security.KeyStoreSecurityLevel; +import android.system.keystore2.Authorization; +import android.system.keystore2.Domain; +import android.system.keystore2.KeyDescriptor; +import android.system.keystore2.KeyMetadata; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +import java.math.BigInteger; +import java.util.Base64; + +@RunWith(AndroidJUnit4.class) +public class AndroidKeyStoreEdECPublicKeyTest { + private static KeyDescriptor descriptor() { + final KeyDescriptor keyDescriptor = new KeyDescriptor(); + keyDescriptor.alias = "key"; + keyDescriptor.blob = null; + keyDescriptor.domain = Domain.APP; + keyDescriptor.nspace = -1; + return keyDescriptor; + } + + private static KeyMetadata metadata(byte[] cert, byte[] certChain) { + KeyMetadata metadata = new KeyMetadata(); + metadata.authorizations = new Authorization[0]; + metadata.certificate = cert; + metadata.certificateChain = certChain; + metadata.key = descriptor(); + metadata.modificationTimeMs = 0; + metadata.keySecurityLevel = 1; + return metadata; + } + + @Mock + private KeyStoreSecurityLevel mKeystoreSecurityLevel; + + private static class EdECTestVector { + public final byte[] encodedKeyBytes; + public final boolean isOdd; + public final BigInteger yValue; + + EdECTestVector(String b64KeyBytes, boolean isOdd, String yValue) { + this.encodedKeyBytes = Base64.getDecoder().decode(b64KeyBytes); + this.isOdd = isOdd; + this.yValue = new BigInteger(yValue); + } + } + + private static final EdECTestVector[] ED_EC_TEST_VECTORS = new EdECTestVector[]{ + new EdECTestVector("MCowBQYDK2VwAyEADE+wvQqNHxaERPhAZ0rCFlgFbfWLs/YonPXdSTw0VSo=", + false, + "19147682157189290216699341180089409126316261024914226007941553249095116672780" + ), + new EdECTestVector("MCowBQYDK2VwAyEA/0E1IRNzGj85Ot/TPeXqifkqTkdk4voleH0hIq59D9w=", + true, + "41640152188550647350742178040529506688513911269563908889464821205156322689535" + ), + new EdECTestVector("MCowBQYDK2VwAyEAunOvGuenetl9GQSXGVo5L3RIr4OOIpFIv/Zre8qTc/8=", + true, + "57647939198144376128225770417635248407428273266444593100194116168980378907578" + ), + new EdECTestVector("MCowBQYDK2VwAyEA2hHqaZ5IolswN1Yd58Y4hzhmUMCCqc4PW5A/SFLmTX8=", + false, + "57581368614046789120409806291852629847774713088410311752049592044694364885466" + ), + }; + + @Test + public void testParsingOfValidKeys() { + for (EdECTestVector testVector : ED_EC_TEST_VECTORS) { + AndroidKeyStoreEdECPublicKey pkey = new AndroidKeyStoreEdECPublicKey(descriptor(), + metadata(null, null), "EdDSA", mKeystoreSecurityLevel, + testVector.encodedKeyBytes); + + assertEquals(pkey.getPoint().isXOdd(), testVector.isOdd); + assertEquals(pkey.getPoint().getY(), testVector.yValue); + } + } + + @Test + public void testFailedParsingOfKeysWithDifferentOid() { + final byte[] testVectorWithIncorrectOid = Base64.getDecoder().decode( + "MCowBQYDLGVwAyEADE+wvQqNHxaERPhAZ0rCFlgFbfWLs/YonPXdSTw0VSo="); + assertThrows("OID should be unrecognized", IllegalArgumentException.class, + () -> new AndroidKeyStoreEdECPublicKey(descriptor(), metadata(null, null), "EdDSA", + mKeystoreSecurityLevel, testVectorWithIncorrectOid)); + } + + @Test + public void testFailedParsingOfKeysWithWrongSize() { + final byte[] testVectorWithIncorrectKeySize = Base64.getDecoder().decode( + "MCwwBQYDK2VwAyMADE+wvQqNHxaERPhAZ0rCFlgFbfWLs/YonPXdSTw0VSrOzg=="); + assertThrows("Key length should be invalid", IllegalArgumentException.class, + () -> new AndroidKeyStoreEdECPublicKey(descriptor(), metadata(null, null), "EdDSA", + mKeystoreSecurityLevel, testVectorWithIncorrectKeySize)); + } +} + diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index faada1aa03ef..9713c2735a9c 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -422,6 +422,18 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen launchPlaceholderIfNecessary(activity); } + @VisibleForTesting + void onActivityDestroyed(@NonNull Activity activity) { + // Remove any pending appeared activity, as the server won't send finished activity to the + // organizer. + for (int i = mTaskContainers.size() - 1; i >= 0; i--) { + mTaskContainers.valueAt(i).cleanupPendingAppearedActivity(activity); + } + // We didn't trigger the callback if there were any pending appeared activities, so check + // again after the pending is removed. + updateCallbackIfNecessary(); + } + /** * Called when we have been waiting too long for the TaskFragment to become non-empty after * creation. @@ -465,12 +477,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen if (activityInTask == null) { throw new IllegalArgumentException("activityInTask must not be null,"); } - final TaskFragmentContainer container = new TaskFragmentContainer(activity, taskId, this); if (!mTaskContainers.contains(taskId)) { mTaskContainers.put(taskId, new TaskContainer(taskId)); } final TaskContainer taskContainer = mTaskContainers.get(taskId); - taskContainer.mContainers.add(container); + final TaskFragmentContainer container = new TaskFragmentContainer(activity, taskContainer, + this); if (!taskContainer.isTaskBoundsInitialized()) { // Get the initial bounds before the TaskFragment has appeared. final Rect taskBounds = SplitPresenter.getTaskBoundsFromActivity(activityInTask); @@ -500,14 +512,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen if (splitRule instanceof SplitPairRule && ((SplitPairRule) splitRule).shouldClearTop()) { removeExistingSecondaryContainers(wct, primaryContainer); } - mTaskContainers.get(primaryContainer.getTaskId()).mSplitContainers.add(splitContainer); + primaryContainer.getTaskContainer().mSplitContainers.add(splitContainer); } /** Cleanups all the dependencies when the TaskFragment is entering PIP. */ private void cleanupForEnterPip(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container) { - final int taskId = container.getTaskId(); - final TaskContainer taskContainer = mTaskContainers.get(taskId); + final TaskContainer taskContainer = container.getTaskContainer(); if (taskContainer == null) { return; } @@ -545,8 +556,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen */ void removeContainer(@NonNull TaskFragmentContainer container) { // Remove all split containers that included this one - final int taskId = container.getTaskId(); - final TaskContainer taskContainer = mTaskContainers.get(taskId); + final TaskContainer taskContainer = container.getTaskContainer(); if (taskContainer == null) { return; } @@ -637,8 +647,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen if (splitContainer == null) { return; } - final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId()) - .mSplitContainers; + final List<SplitContainer> splitContainers = container.getTaskContainer().mSplitContainers; if (splitContainer != splitContainers.get(splitContainers.size() - 1)) { // Skip position update - it isn't the topmost split. return; @@ -660,8 +669,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen */ @Nullable private SplitContainer getActiveSplitForContainer(@NonNull TaskFragmentContainer container) { - final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId()) - .mSplitContainers; + final List<SplitContainer> splitContainers = container.getTaskContainer().mSplitContainers; if (splitContainers.isEmpty()) { return null; } @@ -683,11 +691,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen private SplitContainer getActiveSplitForContainers( @NonNull TaskFragmentContainer firstContainer, @NonNull TaskFragmentContainer secondContainer) { - final List<SplitContainer> splitContainers = mTaskContainers.get(firstContainer.getTaskId()) + final List<SplitContainer> splitContainers = firstContainer.getTaskContainer() .mSplitContainers; - if (splitContainers == null) { - return null; - } for (int i = splitContainers.size() - 1; i >= 0; i--) { final SplitContainer splitContainer = splitContainers.get(i); final TaskFragmentContainer primary = splitContainer.getPrimaryContainer(); @@ -856,11 +861,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen if (container == null) { return false; } - final List<SplitContainer> splitContainers = mTaskContainers.get(container.getTaskId()) - .mSplitContainers; - if (splitContainers == null) { - return true; - } + final List<SplitContainer> splitContainers = container.getTaskContainer().mSplitContainers; for (SplitContainer splitContainer : splitContainers) { if (container.equals(splitContainer.getPrimaryContainer()) || container.equals(splitContainer.getSecondaryContainer())) { @@ -1046,6 +1047,11 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen public void onActivityConfigurationChanged(Activity activity) { SplitController.this.onActivityConfigurationChanged(activity); } + + @Override + public void onActivityPostDestroyed(Activity activity) { + SplitController.this.onActivityDestroyed(activity); + } } /** Executor that posts on the main application thread. */ diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java index 06c1d4ec8d32..b32f4fa67906 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java @@ -291,8 +291,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { // When placeholder is shown in split, we should keep the focus on the primary. wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken()); } - final TaskContainer taskContainer = mController.getTaskContainer( - updatedContainer.getTaskId()); + final TaskContainer taskContainer = updatedContainer.getTaskContainer(); final int windowingMode = taskContainer.getWindowingModeForSplitTaskFragment( primaryRectBounds); updateTaskFragmentWindowingModeIfRegistered(wct, primaryContainer, windowingMode); @@ -456,12 +455,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { @NonNull Rect getParentContainerBounds(@NonNull TaskFragmentContainer container) { - final int taskId = container.getTaskId(); - final TaskContainer taskContainer = mController.getTaskContainer(taskId); - if (taskContainer == null) { - throw new IllegalStateException("Can't find TaskContainer taskId=" + taskId); - } - return taskContainer.getTaskBounds(); + return container.getTaskContainer().getTaskBounds(); } @NonNull diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java index 57628435419e..dba71ef21946 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java @@ -16,12 +16,14 @@ package androidx.window.extensions.embedding; +import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.Activity; import android.app.WindowConfiguration; import android.app.WindowConfiguration.WindowingMode; import android.graphics.Rect; @@ -62,6 +64,9 @@ class TaskContainer { final Set<IBinder> mFinishedContainer = new ArraySet<>(); TaskContainer(int taskId) { + if (taskId == INVALID_TASK_ID) { + throw new IllegalArgumentException("Invalid Task id"); + } mTaskId = taskId; } @@ -130,4 +135,11 @@ class TaskContainer { boolean isEmpty() { return mContainers.isEmpty() && mFinishedContainer.isEmpty(); } + + /** Removes the pending appeared activity from all TaskFragments in this Task. */ + void cleanupPendingAppearedActivity(@NonNull Activity pendingAppearedActivity) { + for (TaskFragmentContainer container : mContainers) { + container.removePendingAppearedActivity(pendingAppearedActivity); + } + } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java index 26bbcbb937f0..6693755ee102 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java @@ -16,7 +16,6 @@ package androidx.window.extensions.embedding; -import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import android.annotation.NonNull; @@ -52,8 +51,9 @@ class TaskFragmentContainer { @NonNull private final IBinder mToken; - /** Parent leaf Task id. */ - private final int mTaskId; + /** Parent leaf Task. */ + @NonNull + private final TaskContainer mTaskContainer; /** * Server-provided task fragment information. @@ -100,14 +100,12 @@ class TaskFragmentContainer { * Creates a container with an existing activity that will be re-parented to it in a window * container transaction. */ - TaskFragmentContainer(@Nullable Activity activity, int taskId, + TaskFragmentContainer(@Nullable Activity activity, @NonNull TaskContainer taskContainer, @NonNull SplitController controller) { mController = controller; mToken = new Binder("TaskFragmentContainer"); - if (taskId == INVALID_TASK_ID) { - throw new IllegalArgumentException("Invalid Task id"); - } - mTaskId = taskId; + mTaskContainer = taskContainer; + taskContainer.mContainers.add(this); if (activity != null) { addPendingAppearedActivity(activity); } @@ -162,9 +160,18 @@ class TaskFragmentContainer { } void addPendingAppearedActivity(@NonNull Activity pendingAppearedActivity) { + if (hasActivity(pendingAppearedActivity.getActivityToken())) { + return; + } + // Remove the pending activity from other TaskFragments. + mTaskContainer.cleanupPendingAppearedActivity(pendingAppearedActivity); mPendingAppearedActivities.add(pendingAppearedActivity); } + void removePendingAppearedActivity(@NonNull Activity pendingAppearedActivity) { + mPendingAppearedActivities.remove(pendingAppearedActivity); + } + boolean hasActivity(@NonNull IBinder token) { if (mInfo != null && mInfo.getActivities().contains(token)) { return true; @@ -376,7 +383,13 @@ class TaskFragmentContainer { /** Gets the parent leaf Task id. */ int getTaskId() { - return mTaskId; + return mTaskContainer.getTaskId(); + } + + /** Gets the parent Task. */ + @NonNull + TaskContainer getTaskContainer() { + return mTaskContainer; } @Override @@ -392,6 +405,7 @@ class TaskFragmentContainer { */ private String toString(boolean includeContainersToFinishOnExit) { return "TaskFragmentContainer{" + + " parentTaskId=" + getTaskId() + " token=" + mToken + " topNonFinishingActivity=" + getTopNonFinishingActivity() + " runningActivityCount=" + getRunningActivityCount() diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java index 7aa47ef11cb1..792a53168a0d 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java @@ -113,8 +113,9 @@ public class JetpackTaskFragmentOrganizerTest { @Test public void testExpandTaskFragment() { + final TaskContainer taskContainer = new TaskContainer(TASK_ID); final TaskFragmentContainer container = new TaskFragmentContainer(null /* activity */, - TASK_ID, mSplitController); + taskContainer, mSplitController); final TaskFragmentInfo info = createMockInfo(container); mOrganizer.mFragmentInfos.put(container.getTaskFragmentToken(), info); container.setInfo(info); diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java index 983208c974a1..34cde9bca763 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java @@ -22,8 +22,10 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; @@ -35,6 +37,7 @@ import android.app.Activity; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; +import android.os.Binder; import android.os.Handler; import android.platform.test.annotations.Presubmit; import android.window.TaskFragmentInfo; @@ -96,20 +99,18 @@ public class SplitControllerTest { @Test public void testGetTopActiveContainer() { - TaskContainer taskContainer = new TaskContainer(TASK_ID); - // tf3 is finished so is not active. - TaskFragmentContainer tf3 = mock(TaskFragmentContainer.class); - doReturn(true).when(tf3).isFinished(); - doReturn(false).when(tf3).isWaitingActivityAppear(); + final TaskContainer taskContainer = new TaskContainer(TASK_ID); + // tf1 has no running activity so is not active. + final TaskFragmentContainer tf1 = new TaskFragmentContainer(null /* activity */, + taskContainer, mSplitController); // tf2 has running activity so is active. - TaskFragmentContainer tf2 = mock(TaskFragmentContainer.class); + final TaskFragmentContainer tf2 = mock(TaskFragmentContainer.class); doReturn(1).when(tf2).getRunningActivityCount(); - // tf1 has no running activity so is not active. - TaskFragmentContainer tf1 = new TaskFragmentContainer(null /* activity */, TASK_ID, - mSplitController); - - taskContainer.mContainers.add(tf1); taskContainer.mContainers.add(tf2); + // tf3 is finished so is not active. + final TaskFragmentContainer tf3 = mock(TaskFragmentContainer.class); + doReturn(true).when(tf3).isFinished(); + doReturn(false).when(tf3).isWaitingActivityAppear(); taskContainer.mContainers.add(tf3); mSplitController.mTaskContainers.put(TASK_ID, taskContainer); @@ -164,6 +165,18 @@ public class SplitControllerTest { } @Test + public void testOnActivityDestroyed() { + doReturn(new Binder()).when(mActivity).getActivityToken(); + final TaskFragmentContainer tf = mSplitController.newContainer(mActivity, TASK_ID); + + assertTrue(tf.hasActivity(mActivity.getActivityToken())); + + mSplitController.onActivityDestroyed(mActivity); + + assertFalse(tf.hasActivity(mActivity.getActivityToken())); + } + + @Test public void testNewContainer() { // Must pass in a valid activity. assertThrows(IllegalArgumentException.class, () -> diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java index c40bab8d9ae3..0de94b0dc26f 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskContainerTest.java @@ -137,9 +137,8 @@ public class TaskContainerTest { assertTrue(taskContainer.isEmpty()); - final TaskFragmentContainer tf = new TaskFragmentContainer(null /* activity */, TASK_ID, - mController); - taskContainer.mContainers.add(tf); + final TaskFragmentContainer tf = new TaskFragmentContainer(null /* activity */, + taskContainer, mController); assertFalse(taskContainer.isEmpty()); diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java index d80f2b939bf0..ce80cbf323b2 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java @@ -76,7 +76,8 @@ public class TaskFragmentContainerTest { @Test public void testFinish() { - final TaskFragmentContainer container = new TaskFragmentContainer(mActivity, TASK_ID, + final TaskContainer taskContainer = new TaskContainer(TASK_ID); + final TaskFragmentContainer container = new TaskFragmentContainer(mActivity, taskContainer, mController); final WindowContainerTransaction wct = new WindowContainerTransaction(); @@ -107,8 +108,9 @@ public class TaskFragmentContainerTest { @Test public void testIsWaitingActivityAppear() { + final TaskContainer taskContainer = new TaskContainer(TASK_ID); final TaskFragmentContainer container = new TaskFragmentContainer(null /* activity */, - TASK_ID, mController); + taskContainer, mController); assertTrue(container.isWaitingActivityAppear()); @@ -127,8 +129,9 @@ public class TaskFragmentContainerTest { @Test public void testAppearEmptyTimeout() { + final TaskContainer taskContainer = new TaskContainer(TASK_ID); final TaskFragmentContainer container = new TaskFragmentContainer(null /* activity */, - TASK_ID, mController); + taskContainer, mController); assertNull(container.mAppearEmptyTimeout); diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index caa335a96222..67b9a433dc03 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -23,7 +23,7 @@ <string name="pip_phone_enter_split" msgid="7042877263880641911">"Sartu pantaila zatituan"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menua"</string> <string name="pip_notification_title" msgid="1347104727641353453">"Pantaila txiki gainjarrian dago <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="pip_notification_message" msgid="8854051911700302620">"Ez baduzu nahi <xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string> + <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> zerbitzuak eginbide hori erabiltzea nahi ez baduzu, sakatu hau ezarpenak ireki eta aukera desaktibatzeko."</string> <string name="pip_play" msgid="3496151081459417097">"Erreproduzitu"</string> <string name="pip_pause" msgid="690688849510295232">"Pausatu"</string> <string name="pip_skip_to_next" msgid="8403429188794867653">"Joan hurrengora"</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java index 3876533a922e..b04a1fa93bbd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java @@ -19,6 +19,7 @@ import android.annotation.DrawableRes; import android.annotation.Nullable; import android.content.Context; import android.content.res.TypedArray; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Outline; import android.graphics.Path; @@ -350,16 +351,19 @@ public class BadgedImageView extends ConstraintLayout { } void showBadge() { - if (mBubble.getAppBadge() == null) { + Bitmap appBadgeBitmap = mBubble.getAppBadge(); + if (appBadgeBitmap == null) { mAppIcon.setVisibility(GONE); return; } + int translationX; if (mOnLeft) { - translationX = -(mBubbleIcon.getWidth() - mAppIcon.getWidth()); + translationX = -(mBubble.getBubbleIcon().getWidth() - appBadgeBitmap.getWidth()); } else { translationX = 0; } + mAppIcon.setTranslationX(translationX); mAppIcon.setVisibility(VISIBLE); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java index dfd4362e2373..1ea5e21a2c1e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java @@ -18,6 +18,7 @@ package com.android.wm.shell.dagger; import android.content.Context; import android.os.Handler; +import android.os.SystemClock; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; @@ -39,6 +40,7 @@ import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.pip.PipTransitionState; import com.android.wm.shell.pip.PipUiEventLogger; import com.android.wm.shell.pip.tv.TvPipBoundsAlgorithm; +import com.android.wm.shell.pip.tv.TvPipBoundsController; import com.android.wm.shell.pip.tv.TvPipBoundsState; import com.android.wm.shell.pip.tv.TvPipController; import com.android.wm.shell.pip.tv.TvPipMenuController; @@ -64,6 +66,7 @@ public abstract class TvPipModule { Context context, TvPipBoundsState tvPipBoundsState, TvPipBoundsAlgorithm tvPipBoundsAlgorithm, + TvPipBoundsController tvPipBoundsController, PipAppOpsListener pipAppOpsListener, PipTaskOrganizer pipTaskOrganizer, TvPipMenuController tvPipMenuController, @@ -74,13 +77,13 @@ public abstract class TvPipModule { PipParamsChangedForwarder pipParamsChangedForwarder, DisplayController displayController, WindowManagerShellWrapper windowManagerShellWrapper, - @ShellMainThread ShellExecutor mainExecutor, - @ShellMainThread Handler mainHandler) { + @ShellMainThread ShellExecutor mainExecutor) { return Optional.of( TvPipController.create( context, tvPipBoundsState, tvPipBoundsAlgorithm, + tvPipBoundsController, pipAppOpsListener, pipTaskOrganizer, pipTransitionController, @@ -91,8 +94,22 @@ public abstract class TvPipModule { pipParamsChangedForwarder, displayController, windowManagerShellWrapper, - mainExecutor, - mainHandler)); + mainExecutor)); + } + + @WMSingleton + @Provides + static TvPipBoundsController provideTvPipBoundsController( + Context context, + @ShellMainThread Handler mainHandler, + TvPipBoundsState tvPipBoundsState, + TvPipBoundsAlgorithm tvPipBoundsAlgorithm) { + return new TvPipBoundsController( + context, + SystemClock::uptimeMillis, + mainHandler, + tvPipBoundsState, + tvPipBoundsAlgorithm); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java index f8f9d6b8f8a0..65cb7ac1e5f7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeSettingsObserver.java @@ -16,13 +16,18 @@ package com.android.wm.shell.kidsmode; +import android.annotation.NonNull; +import android.app.ActivityManager; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; +import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; +import java.util.Collection; + /** * A ContentObserver for listening kids mode relative setting keys: * - {@link Settings.Secure#NAVIGATION_MODE} @@ -64,7 +69,11 @@ public class KidsModeSettingsObserver extends ContentObserver { } @Override - public void onChange(boolean selfChange) { + public void onChange(boolean selfChange, @NonNull Collection<Uri> uris, int flags, int userId) { + if (userId != ActivityManager.getCurrentUser()) { + return; + } + if (mOnChangeRunnable != null) { mOnChangeRunnable.run(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java index dc703583a449..b4c87b6cbf95 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java @@ -23,7 +23,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; import android.app.ActivityManager; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Binder; @@ -87,6 +90,13 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer { private KidsModeSettingsObserver mKidsModeSettingsObserver; private boolean mEnabled; + private final BroadcastReceiver mUserSwitchIntentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + updateKidsModeState(); + } + }; + DisplayController.OnDisplaysChangedListener mOnDisplaysChangedListener = new DisplayController.OnDisplaysChangedListener() { @Override @@ -169,12 +179,15 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer { public void initialize(StartingWindowController startingWindowController) { initStartingWindow(startingWindowController); if (mKidsModeSettingsObserver == null) { - mKidsModeSettingsObserver = new KidsModeSettingsObserver( - mMainHandler, mContext); + mKidsModeSettingsObserver = new KidsModeSettingsObserver(mMainHandler, mContext); } mKidsModeSettingsObserver.setOnChangeRunnable(() -> updateKidsModeState()); updateKidsModeState(); mKidsModeSettingsObserver.register(); + + final IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_USER_SWITCHED); + mContext.registerReceiverForAllUsers(mUserSwitchIntentReceiver, filter, null, mMainHandler); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java index c0734e95ecb7..3b3091a9caf3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java @@ -44,11 +44,6 @@ public interface Pip { } /** - * Hides the PIP menu. - */ - default void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {} - - /** * Called when configuration is changed. */ default void onConfigurationChanged(Configuration newConfig) { @@ -125,6 +120,23 @@ public interface Pip { default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { } /** + * Called when the visibility of keyguard is changed. + * @param showing {@code true} if keyguard is now showing, {@code false} otherwise. + * @param animating {@code true} if system is animating between keyguard and surface behind, + * this only makes sense when showing is {@code false}. + */ + default void onKeyguardVisibilityChanged(boolean showing, boolean animating) { } + + /** + * Called when the dismissing animation keyguard and surfaces behind is finished. + * See also {@link #onKeyguardVisibilityChanged(boolean, boolean)}. + * + * TODO(b/206741900) deprecate this path once we're able to animate the PiP window as part of + * keyguard dismiss animation. + */ + default void onKeyguardDismissAnimationFinished() { } + + /** * Dump the current state and information if need. * * @param pw The stream to dump information to. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index b114d8177484..57d7168b1d3c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -969,6 +969,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mDeferredAnimEndTransaction = null; } + /** Explicitly set the visibility of PiP window. */ + public void setPipVisibility(boolean visible) { + if (!isInPip()) { + return; + } + final SurfaceControl.Transaction tx = + mSurfaceControlTransactionFactory.getTransaction(); + mSurfaceTransactionHelper.alpha(tx, mLeash, visible ? 1f : 0f); + tx.apply(); + } + @Override public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) { mCurrentRotation = newConfig.windowConfiguration.getRotation(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 492b5d959c46..4b1e5f8c0d7c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -129,6 +129,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb protected PinnedStackListenerForwarder.PinnedTaskListener mPinnedTaskListener = new PipControllerPinnedTaskListener(); + private boolean mIsKeyguardShowingOrAnimating; + private interface PipAnimationListener { /** * Notifies the listener that the Pip animation is started. @@ -613,6 +615,33 @@ public class PipController implements PipTransitionController.PipTransitionCallb } /** + * If {@param keyguardShowing} is {@code false} and {@param animating} is {@code true}, + * we would wait till the dismissing animation of keyguard and surfaces behind to be + * finished first to reset the visibility of PiP window. + * See also {@link #onKeyguardDismissAnimationFinished()} + */ + private void onKeyguardVisibilityChanged(boolean keyguardShowing, boolean animating) { + if (!mPipTaskOrganizer.isInPip()) { + return; + } + if (keyguardShowing) { + mIsKeyguardShowingOrAnimating = true; + hidePipMenu(null /* onStartCallback */, null /* onEndCallback */); + mPipTaskOrganizer.setPipVisibility(false); + } else if (!animating) { + mIsKeyguardShowingOrAnimating = false; + mPipTaskOrganizer.setPipVisibility(true); + } + } + + private void onKeyguardDismissAnimationFinished() { + if (mPipTaskOrganizer.isInPip()) { + mIsKeyguardShowingOrAnimating = false; + mPipTaskOrganizer.setPipVisibility(true); + } + } + + /** * Sets a customized touch gesture that replaces the default one. */ public void setTouchGesture(PipTouchGesture gesture) { @@ -623,7 +652,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb * Sets both shelf visibility and its height. */ private void setShelfHeight(boolean visible, int height) { - setShelfHeightLocked(visible, height); + if (!mIsKeyguardShowingOrAnimating) { + setShelfHeightLocked(visible, height); + } } private void setShelfHeightLocked(boolean visible, int height) { @@ -854,13 +885,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @Override - public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) { - mMainExecutor.execute(() -> { - PipController.this.hidePipMenu(onStartCallback, onEndCallback); - }); - } - - @Override public void expandPip() { mMainExecutor.execute(() -> { PipController.this.expandPip(); @@ -938,6 +962,18 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @Override + public void onKeyguardVisibilityChanged(boolean showing, boolean animating) { + mMainExecutor.execute(() -> { + PipController.this.onKeyguardVisibilityChanged(showing, animating); + }); + } + + @Override + public void onKeyguardDismissAnimationFinished() { + mMainExecutor.execute(PipController.this::onKeyguardDismissAnimationFinished); + } + + @Override public void dump(PrintWriter pw) { try { mMainExecutor.executeBlocking(() -> { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java index 21d5d401835d..a2eadcdf6210 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java @@ -29,7 +29,6 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.Rect; -import android.os.SystemClock; import android.util.ArraySet; import android.util.Size; import android.view.Gravity; @@ -66,7 +65,7 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { @NonNull PipSnapAlgorithm pipSnapAlgorithm) { super(context, tvPipBoundsState, pipSnapAlgorithm); this.mTvPipBoundsState = tvPipBoundsState; - this.mKeepClearAlgorithm = new TvPipKeepClearAlgorithm(SystemClock::uptimeMillis); + this.mKeepClearAlgorithm = new TvPipKeepClearAlgorithm(); reloadResources(context); } @@ -80,7 +79,6 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { res.getDimensionPixelSize(R.dimen.pip_keep_clear_area_padding)); mKeepClearAlgorithm.setMaxRestrictedDistanceFraction( res.getFraction(R.fraction.config_pipMaxRestrictedMoveDistance, 1, 1)); - mKeepClearAlgorithm.setStashDuration(res.getInteger(R.integer.config_pipStashDuration)); } @Override @@ -104,7 +102,7 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { updateGravityOnExpandToggled(Gravity.NO_GRAVITY, true); } mTvPipBoundsState.setTvPipExpanded(isPipExpanded); - return getTvPipBounds().getBounds(); + return adjustBoundsForTemporaryDecor(getTvPipPlacement().getBounds()); } /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ @@ -114,13 +112,27 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: getAdjustedDestinationBounds: %f", TAG, newAspectRatio); } - return getTvPipBounds().getBounds(); + return adjustBoundsForTemporaryDecor(getTvPipPlacement().getBounds()); + } + + Rect adjustBoundsForTemporaryDecor(Rect bounds) { + Rect boundsWithDecor = new Rect(bounds); + Insets decorInset = mTvPipBoundsState.getPipMenuTemporaryDecorInsets(); + Insets pipDecorReverseInsets = Insets.subtract(Insets.NONE, decorInset); + boundsWithDecor.inset(decorInset); + Gravity.apply(mTvPipBoundsState.getTvPipGravity(), + boundsWithDecor.width(), boundsWithDecor.height(), bounds, boundsWithDecor); + + // remove temporary decoration again + boundsWithDecor.inset(pipDecorReverseInsets); + return boundsWithDecor; } /** * Calculates the PiP bounds. */ - public Placement getTvPipBounds() { + @NonNull + public Placement getTvPipPlacement() { final Size pipSize = getPipSize(); final Rect displayBounds = mTvPipBoundsState.getDisplayBounds(); final Size screenSize = new Size(displayBounds.width(), displayBounds.height()); @@ -153,8 +165,6 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { mKeepClearAlgorithm.setStashOffset(mTvPipBoundsState.getStashOffset()); mKeepClearAlgorithm.setPipPermanentDecorInsets( mTvPipBoundsState.getPipMenuPermanentDecorInsets()); - mKeepClearAlgorithm.setPipTemporaryDecorInsets( - mTvPipBoundsState.getPipMenuTemporaryDecorInsets()); final Placement placement = mKeepClearAlgorithm.calculatePipPosition( pipSize, @@ -407,8 +417,4 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm { TAG, expandedSize.getWidth(), expandedSize.getHeight()); } } - - void keepUnstashedForCurrentKeepClearAreas() { - mKeepClearAlgorithm.keepUnstashedForCurrentKeepClearAreas(); - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java new file mode 100644 index 000000000000..3a6ce81821ec --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.pip.tv; + +import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Rect; +import android.os.Handler; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.protolog.common.ProtoLog; +import com.android.wm.shell.R; +import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement; +import com.android.wm.shell.protolog.ShellProtoLogGroup; + +import java.util.Objects; +import java.util.function.Supplier; + +/** + * Controller managing the PiP's position. + * Manages debouncing of PiP movements and scheduling of unstashing. + */ +public class TvPipBoundsController { + private static final boolean DEBUG = false; + private static final String TAG = "TvPipBoundsController"; + + /** + * Time the calculated PiP position needs to be stable before PiP is moved there, + * to avoid erratic movement. + * Some changes will cause the PiP to be repositioned immediately, such as changes to + * unrestricted keep clear areas. + */ + @VisibleForTesting + static final long POSITION_DEBOUNCE_TIMEOUT_MILLIS = 300L; + + private final Context mContext; + private final Supplier<Long> mClock; + private final Handler mMainHandler; + private final TvPipBoundsState mTvPipBoundsState; + private final TvPipBoundsAlgorithm mTvPipBoundsAlgorithm; + + @Nullable + private PipBoundsListener mListener; + + private int mResizeAnimationDuration; + private int mStashDurationMs; + private Rect mCurrentPlacementBounds; + private Rect mPipTargetBounds; + + private final Runnable mApplyPendingPlacementRunnable = this::applyPendingPlacement; + private boolean mPendingStash; + private Placement mPendingPlacement; + private int mPendingPlacementAnimationDuration; + private Runnable mUnstashRunnable; + + public TvPipBoundsController( + Context context, + Supplier<Long> clock, + Handler mainHandler, + TvPipBoundsState tvPipBoundsState, + TvPipBoundsAlgorithm tvPipBoundsAlgorithm) { + mContext = context; + mClock = clock; + mMainHandler = mainHandler; + mTvPipBoundsState = tvPipBoundsState; + mTvPipBoundsAlgorithm = tvPipBoundsAlgorithm; + + loadConfigurations(); + } + + private void loadConfigurations() { + final Resources res = mContext.getResources(); + mResizeAnimationDuration = res.getInteger(R.integer.config_pipResizeAnimationDuration); + mStashDurationMs = res.getInteger(R.integer.config_pipStashDuration); + } + + void setListener(PipBoundsListener listener) { + mListener = listener; + } + + /** + * Update the PiP bounds based on the state of the PiP, decors, and keep clear areas. + * Unless {@code immediate} is {@code true}, the PiP does not move immediately to avoid + * keep clear areas, but waits for a new position to stay uncontested for + * {@link #POSITION_DEBOUNCE_TIMEOUT_MILLIS} before moving to it. + * Temporary decor changes are applied immediately. + * + * @param stayAtAnchorPosition If true, PiP will be placed at the anchor position + * @param disallowStashing If true, PiP will not be placed off-screen in a stashed position + * @param animationDuration Duration of the animation to the new position + * @param immediate If true, PiP will move immediately to avoid keep clear areas + */ + @VisibleForTesting + void recalculatePipBounds(boolean stayAtAnchorPosition, boolean disallowStashing, + int animationDuration, boolean immediate) { + final Placement placement = mTvPipBoundsAlgorithm.getTvPipPlacement(); + + final int stashType = disallowStashing ? STASH_TYPE_NONE : placement.getStashType(); + mTvPipBoundsState.setStashed(stashType); + if (stayAtAnchorPosition) { + cancelScheduledPlacement(); + applyPlacementBounds(placement.getAnchorBounds(), animationDuration); + } else if (disallowStashing) { + cancelScheduledPlacement(); + applyPlacementBounds(placement.getUnstashedBounds(), animationDuration); + } else if (immediate) { + cancelScheduledPlacement(); + applyPlacementBounds(placement.getBounds(), animationDuration); + scheduleUnstashIfNeeded(placement); + } else { + applyPlacementBounds(mCurrentPlacementBounds, animationDuration); + schedulePinnedStackPlacement(placement, animationDuration); + } + } + + private void schedulePinnedStackPlacement(@NonNull final Placement placement, + int animationDuration) { + if (DEBUG) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: schedulePinnedStackPlacement() - pip bounds: %s", + TAG, placement.getBounds().toShortString()); + } + + if (mPendingPlacement != null && Objects.equals(mPendingPlacement.getBounds(), + placement.getBounds())) { + mPendingStash = mPendingStash || placement.getTriggerStash(); + return; + } + + mPendingStash = placement.getStashType() != STASH_TYPE_NONE + && (mPendingStash || placement.getTriggerStash()); + + mMainHandler.removeCallbacks(mApplyPendingPlacementRunnable); + mPendingPlacement = placement; + mPendingPlacementAnimationDuration = animationDuration; + mMainHandler.postAtTime(mApplyPendingPlacementRunnable, + mClock.get() + POSITION_DEBOUNCE_TIMEOUT_MILLIS); + } + + private void scheduleUnstashIfNeeded(final Placement placement) { + if (mUnstashRunnable != null) { + mMainHandler.removeCallbacks(mUnstashRunnable); + mUnstashRunnable = null; + } + if (placement.getUnstashDestinationBounds() != null) { + mUnstashRunnable = () -> { + applyPlacementBounds(placement.getUnstashDestinationBounds(), + mResizeAnimationDuration); + mUnstashRunnable = null; + }; + mMainHandler.postAtTime(mUnstashRunnable, mClock.get() + mStashDurationMs); + } + } + + private void applyPendingPlacement() { + if (DEBUG) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: applyPendingPlacement()", TAG); + } + if (mPendingPlacement != null) { + if (mPendingStash) { + mPendingStash = false; + scheduleUnstashIfNeeded(mPendingPlacement); + } + + if (mUnstashRunnable != null) { + // currently stashed, use stashed pos + applyPlacementBounds(mPendingPlacement.getBounds(), + mPendingPlacementAnimationDuration); + } else { + applyPlacementBounds(mPendingPlacement.getUnstashedBounds(), + mPendingPlacementAnimationDuration); + } + } + + mPendingPlacement = null; + } + + void onPipDismissed() { + mCurrentPlacementBounds = null; + mPipTargetBounds = null; + cancelScheduledPlacement(); + } + + private void cancelScheduledPlacement() { + mMainHandler.removeCallbacks(mApplyPendingPlacementRunnable); + mPendingPlacement = null; + + if (mUnstashRunnable != null) { + mMainHandler.removeCallbacks(mUnstashRunnable); + mUnstashRunnable = null; + } + } + + private void applyPlacementBounds(Rect bounds, int animationDuration) { + if (bounds == null) { + return; + } + + mCurrentPlacementBounds = bounds; + Rect adjustedBounds = mTvPipBoundsAlgorithm.adjustBoundsForTemporaryDecor(bounds); + movePipTo(adjustedBounds, animationDuration); + } + + /** Animates the PiP to the given bounds with the given animation duration. */ + private void movePipTo(Rect bounds, int animationDuration) { + if (Objects.equals(mPipTargetBounds, bounds)) { + return; + } + + mPipTargetBounds = bounds; + if (DEBUG) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: movePipTo() - new pip bounds: %s", TAG, bounds.toShortString()); + } + + if (mListener != null) { + mListener.onPipTargetBoundsChange(bounds, animationDuration); + } + } + + /** + * Interface being notified of changes to the PiP bounds as calculated by + * @link TvPipBoundsController}. + */ + public interface PipBoundsListener { + /** + * Called when the calculated PiP bounds are changing. + * + * @param newTargetBounds The new bounds of the PiP. + * @param animationDuration The animation duration for the PiP movement. + */ + void onPipTargetBoundsChange(Rect newTargetBounds, int animationDuration); + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java index 766779413094..fa48def9c7d7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java @@ -25,12 +25,10 @@ import android.app.ActivityTaskManager; import android.app.PendingIntent; import android.app.RemoteAction; import android.app.TaskInfo; -import android.content.ComponentName; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; -import android.os.Handler; import android.os.RemoteException; import android.view.Gravity; @@ -46,25 +44,24 @@ import com.android.wm.shell.pip.PinnedStackListenerForwarder; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipAnimationController; import com.android.wm.shell.pip.PipAppOpsListener; -import com.android.wm.shell.pip.PipBoundsState; import com.android.wm.shell.pip.PipMediaController; import com.android.wm.shell.pip.PipParamsChangedForwarder; import com.android.wm.shell.pip.PipTaskOrganizer; import com.android.wm.shell.pip.PipTransitionController; -import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement; import com.android.wm.shell.protolog.ShellProtoLogGroup; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; +import java.util.Objects; import java.util.Set; /** * Manages the picture-in-picture (PIP) UI and states. */ public class TvPipController implements PipTransitionController.PipTransitionCallback, - TvPipMenuController.Delegate, TvPipNotificationController.Delegate, - DisplayController.OnDisplaysChangedListener { + TvPipBoundsController.PipBoundsListener, TvPipMenuController.Delegate, + TvPipNotificationController.Delegate, DisplayController.OnDisplaysChangedListener { private static final String TAG = "TvPipController"; static final boolean DEBUG = false; @@ -98,19 +95,18 @@ public class TvPipController implements PipTransitionController.PipTransitionCal private final TvPipBoundsState mTvPipBoundsState; private final TvPipBoundsAlgorithm mTvPipBoundsAlgorithm; + private final TvPipBoundsController mTvPipBoundsController; private final PipAppOpsListener mAppOpsListener; private final PipTaskOrganizer mPipTaskOrganizer; private final PipMediaController mPipMediaController; private final TvPipNotificationController mPipNotificationController; private final TvPipMenuController mTvPipMenuController; private final ShellExecutor mMainExecutor; - private final Handler mMainHandler; private final TvPipImpl mImpl = new TvPipImpl(); private @State int mState = STATE_NO_PIP; private int mPreviousGravity = TvPipBoundsState.DEFAULT_TV_GRAVITY; private int mPinnedTaskId = NONEXISTENT_TASK_ID; - private Runnable mUnstashRunnable; private RemoteAction mCloseAction; // How long the shell will wait for the app to close the PiP if a custom action is set. @@ -123,6 +119,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal Context context, TvPipBoundsState tvPipBoundsState, TvPipBoundsAlgorithm tvPipBoundsAlgorithm, + TvPipBoundsController tvPipBoundsController, PipAppOpsListener pipAppOpsListener, PipTaskOrganizer pipTaskOrganizer, PipTransitionController pipTransitionController, @@ -133,12 +130,12 @@ public class TvPipController implements PipTransitionController.PipTransitionCal PipParamsChangedForwarder pipParamsChangedForwarder, DisplayController displayController, WindowManagerShellWrapper wmShell, - ShellExecutor mainExecutor, - Handler mainHandler) { + ShellExecutor mainExecutor) { return new TvPipController( context, tvPipBoundsState, tvPipBoundsAlgorithm, + tvPipBoundsController, pipAppOpsListener, pipTaskOrganizer, pipTransitionController, @@ -149,14 +146,14 @@ public class TvPipController implements PipTransitionController.PipTransitionCal pipParamsChangedForwarder, displayController, wmShell, - mainExecutor, - mainHandler).mImpl; + mainExecutor).mImpl; } private TvPipController( Context context, TvPipBoundsState tvPipBoundsState, TvPipBoundsAlgorithm tvPipBoundsAlgorithm, + TvPipBoundsController tvPipBoundsController, PipAppOpsListener pipAppOpsListener, PipTaskOrganizer pipTaskOrganizer, PipTransitionController pipTransitionController, @@ -167,16 +164,16 @@ public class TvPipController implements PipTransitionController.PipTransitionCal PipParamsChangedForwarder pipParamsChangedForwarder, DisplayController displayController, WindowManagerShellWrapper wmShell, - ShellExecutor mainExecutor, - Handler mainHandler) { + ShellExecutor mainExecutor) { mContext = context; mMainExecutor = mainExecutor; - mMainHandler = mainHandler; mTvPipBoundsState = tvPipBoundsState; mTvPipBoundsState.setDisplayId(context.getDisplayId()); mTvPipBoundsState.setDisplayLayout(new DisplayLayout(context, context.getDisplay())); mTvPipBoundsAlgorithm = tvPipBoundsAlgorithm; + mTvPipBoundsController = tvPipBoundsController; + mTvPipBoundsController.setListener(this); mPipMediaController = pipMediaController; @@ -227,7 +224,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal /** * Starts the process if bringing up the Pip menu if by issuing a command to move Pip * task/window to the "Menu" position. We'll show the actual Menu UI (eg. actions) once the Pip - * task/window is properly positioned in {@link #onPipTransitionFinished(ComponentName, int)}. + * task/window is properly positioned in {@link #onPipTransitionFinished(int)}. */ @Override public void showPictureInPictureMenu() { @@ -256,7 +253,6 @@ public class TvPipController implements PipTransitionController.PipTransitionCal "%s: closeMenu(), state before=%s", TAG, stateToName(mState)); } setState(STATE_PIP); - mTvPipBoundsAlgorithm.keepUnstashedForCurrentKeepClearAreas(); updatePinnedStackBounds(); } @@ -331,68 +327,35 @@ public class TvPipController implements PipTransitionController.PipTransitionCal public void onKeepClearAreasChanged(int displayId, Set<Rect> restricted, Set<Rect> unrestricted) { if (mTvPipBoundsState.getDisplayId() == displayId) { + boolean unrestrictedAreasChanged = !Objects.equals(unrestricted, + mTvPipBoundsState.getUnrestrictedKeepClearAreas()); mTvPipBoundsState.setKeepClearAreas(restricted, unrestricted); - updatePinnedStackBounds(); + updatePinnedStackBounds(mResizeAnimationDuration, unrestrictedAreasChanged); } } private void updatePinnedStackBounds() { - updatePinnedStackBounds(mResizeAnimationDuration); + updatePinnedStackBounds(mResizeAnimationDuration, true); } /** * Update the PiP bounds based on the state of the PiP and keep clear areas. - * Animates to the current PiP bounds, and schedules unstashing the PiP if necessary. */ - private void updatePinnedStackBounds(int animationDuration) { + private void updatePinnedStackBounds(int animationDuration, boolean immediate) { if (mState == STATE_NO_PIP) { return; } - final boolean stayAtAnchorPosition = mTvPipMenuController.isInMoveMode(); final boolean disallowStashing = mState == STATE_PIP_MENU || stayAtAnchorPosition; - final Placement placement = mTvPipBoundsAlgorithm.getTvPipBounds(); - - int stashType = - disallowStashing ? PipBoundsState.STASH_TYPE_NONE : placement.getStashType(); - mTvPipBoundsState.setStashed(stashType); - - if (stayAtAnchorPosition) { - movePinnedStackTo(placement.getAnchorBounds()); - } else if (disallowStashing) { - movePinnedStackTo(placement.getUnstashedBounds()); - } else { - movePinnedStackTo(placement.getBounds()); - } - - if (mUnstashRunnable != null) { - mMainHandler.removeCallbacks(mUnstashRunnable); - mUnstashRunnable = null; - } - if (!disallowStashing && placement.getUnstashDestinationBounds() != null) { - mUnstashRunnable = () -> { - movePinnedStackTo(placement.getUnstashDestinationBounds(), animationDuration); - }; - mMainHandler.postAtTime(mUnstashRunnable, placement.getUnstashTime()); - } - } - - /** Animates the PiP to the given bounds. */ - private void movePinnedStackTo(Rect bounds) { - movePinnedStackTo(bounds, mResizeAnimationDuration); + mTvPipBoundsController.recalculatePipBounds(stayAtAnchorPosition, disallowStashing, + animationDuration, immediate); } - /** Animates the PiP to the given bounds with the given animation duration. */ - private void movePinnedStackTo(Rect bounds, int animationDuration) { - if (DEBUG) { - ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: movePinnedStack() - new pip bounds: %s", TAG, bounds.toShortString()); - } - mPipTaskOrganizer.scheduleAnimateResizePip(bounds, - animationDuration, rect -> { - mTvPipMenuController.updateExpansionState(); - }); - mTvPipMenuController.onPipTransitionStarted(bounds); + @Override + public void onPipTargetBoundsChange(Rect newTargetBounds, int animationDuration) { + mPipTaskOrganizer.scheduleAnimateResizePip(newTargetBounds, + animationDuration, rect -> mTvPipMenuController.updateExpansionState()); + mTvPipMenuController.onPipTransitionStarted(newTargetBounds); } /** @@ -431,7 +394,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal @Override public void closeEduText() { - updatePinnedStackBounds(mEduTextWindowExitAnimationDurationMs); + updatePinnedStackBounds(mEduTextWindowExitAnimationDurationMs, false); } private void registerSessionListenerForCurrentUser() { @@ -473,6 +436,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal mPipNotificationController.dismiss(); mTvPipMenuController.closeMenu(); mTvPipBoundsState.resetTvPipState(); + mTvPipBoundsController.onPipDismissed(); setState(STATE_NO_PIP); mPinnedTaskId = NONEXISTENT_TASK_ID; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt index 07dccd58abfd..1e54436ebce9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt @@ -33,17 +33,14 @@ import kotlin.math.min import kotlin.math.roundToInt private const val DEFAULT_PIP_MARGINS = 48 -private const val DEFAULT_STASH_DURATION = 5000L private const val RELAX_DEPTH = 1 private const val DEFAULT_MAX_RESTRICTED_DISTANCE_FRACTION = 0.15 /** * This class calculates an appropriate position for a Picture-In-Picture (PiP) window, taking * into account app defined keep clear areas. - * - * @param clock A function returning a current timestamp (in milliseconds) */ -class TvPipKeepClearAlgorithm(private val clock: () -> Long) { +class TvPipKeepClearAlgorithm() { /** * Result of the positioning algorithm. * @@ -51,17 +48,17 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { * @param anchorBounds The bounds of the PiP anchor position * (where the PiP would be placed if there were no keep clear areas) * @param stashType Where the PiP has been stashed, if at all - * @param unstashDestinationBounds If stashed, the PiP should move to this position after - * [stashDuration] has passed. - * @param unstashTime If stashed, the time at which the PiP should move - * to [unstashDestinationBounds] + * @param unstashDestinationBounds If stashed, the PiP should move to this position when + * unstashing. + * @param triggerStash Whether this placement should trigger the PiP to stash, or extend + * the unstash timeout if already stashed. */ data class Placement( val bounds: Rect, val anchorBounds: Rect, @PipBoundsState.StashType val stashType: Int = STASH_TYPE_NONE, val unstashDestinationBounds: Rect? = null, - val unstashTime: Long = 0L + val triggerStash: Boolean = false ) { /** Bounds to use if the PiP should not be stashed. */ fun getUnstashedBounds() = unstashDestinationBounds ?: bounds @@ -79,12 +76,6 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { /** The distance the PiP peeks into the screen when stashed */ var stashOffset = DEFAULT_PIP_MARGINS - /** - * How long (in milliseconds) the PiP should stay stashed for after the last time the - * keep clear areas causing the PiP to stash have changed. - */ - var stashDuration = DEFAULT_STASH_DURATION - /** The fraction of screen width/height restricted keep clear areas can move the PiP */ var maxRestrictedDistanceFraction = DEFAULT_MAX_RESTRICTED_DISTANCE_FRACTION @@ -93,14 +84,10 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { private var transformedMovementBounds = Rect() private var lastAreasOverlappingUnstashPosition: Set<Rect> = emptySet() - private var lastStashTime: Long = Long.MIN_VALUE /** Spaces around the PiP that we should leave space for when placing the PiP. Permanent PiP * decorations are relevant for calculating intersecting keep clear areas */ private var pipPermanentDecorInsets = Insets.NONE - /** Spaces around the PiP that we should leave space for when placing the PiP. Temporary PiP - * decorations are not relevant for calculating intersecting keep clear areas */ - private var pipTemporaryDecorInsets = Insets.NONE /** * Calculates the position the PiP should be placed at, taking into consideration the @@ -113,8 +100,8 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { * always try to respect these areas. * * If no free space the PiP is allowed to move to can be found, a stashed position is returned - * as [Placement.bounds], along with a position to move to once [Placement.unstashTime] has - * passed as [Placement.unstashDestinationBounds]. + * as [Placement.bounds], along with a position to move to when the PiP unstashes + * as [Placement.unstashDestinationBounds]. * * @param pipSize The size of the PiP window * @param restrictedAreas The restricted keep clear areas @@ -130,13 +117,11 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { val transformedUnrestrictedAreas = transformAndFilterAreas(unrestrictedAreas) val pipSizeWithAllDecors = addDecors(pipSize) - val pipAnchorBoundsWithAllDecors = + val pipAnchorBoundsWithDecors = getNormalPipAnchorBounds(pipSizeWithAllDecors, transformedMovementBounds) - val pipAnchorBoundsWithPermanentDecors = - removeTemporaryDecorsTransformed(pipAnchorBoundsWithAllDecors) val result = calculatePipPositionTransformed( - pipAnchorBoundsWithPermanentDecors, + pipAnchorBoundsWithDecors, transformedRestrictedAreas, transformedUnrestrictedAreas ) @@ -152,7 +137,7 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { anchorBounds, getStashType(pipBounds, unstashedDestBounds), unstashedDestBounds, - result.unstashTime + result.triggerStash ) } @@ -213,26 +198,13 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { !lastAreasOverlappingUnstashPosition.containsAll(areasOverlappingUnstashPosition) lastAreasOverlappingUnstashPosition = areasOverlappingUnstashPosition - val now = clock() - if (areasOverlappingUnstashPositionChanged) { - lastStashTime = now - } - - // If overlapping areas haven't changed and the stash duration has passed, we can - // place the PiP at the unstash position - val unstashTime = lastStashTime + stashDuration - if (now >= unstashTime) { - return Placement(unstashBounds, pipAnchorBounds) - } - - // Otherwise, we'll stash it close to the unstash position val stashedBounds = getNearbyStashedPosition(unstashBounds, keepClearAreas) return Placement( stashedBounds, pipAnchorBounds, getStashType(stashedBounds, unstashBounds), unstashBounds, - unstashTime + areasOverlappingUnstashPositionChanged ) } @@ -439,14 +411,6 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { } /** - * Prevents the PiP from being stashed for the current set of keep clear areas. - * The PiP may stash again if keep clear areas change. - */ - fun keepUnstashedForCurrentKeepClearAreas() { - lastStashTime = Long.MIN_VALUE - } - - /** * Updates the size of the screen. * * @param size The new size of the screen @@ -492,10 +456,6 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { pipPermanentDecorInsets = insets } - fun setPipTemporaryDecorInsets(insets: Insets) { - pipTemporaryDecorInsets = insets - } - /** * @param open Whether this event marks the opening of an occupied segment * @param pos The coordinate of this event @@ -790,7 +750,6 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { private fun addDecors(size: Size): Size { val bounds = Rect(0, 0, size.width, size.height) bounds.inset(pipPermanentDecorInsets) - bounds.inset(pipTemporaryDecorInsets) return Size(bounds.width(), bounds.height()) } @@ -805,19 +764,6 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { return bounds } - /** - * Removes the space that was reserved for temporary decorations around the PiP - * @param bounds the bounds (in base case) to remove the insets from - */ - private fun removeTemporaryDecorsTransformed(bounds: Rect): Rect { - if (pipTemporaryDecorInsets == Insets.NONE) return bounds - - val reverseInsets = Insets.subtract(Insets.NONE, pipTemporaryDecorInsets) - val boundsInScreenSpace = fromTransformedSpace(bounds) - boundsInScreenSpace.inset(reverseInsets) - return toTransformedSpace(boundsInScreenSpace) - } - private fun Rect.offsetCopy(dx: Int, dy: Int) = Rect(this).apply { offset(dx, dy) } private fun Rect.intersectsX(other: Rect) = right >= other.left && left <= other.right private fun Rect.intersectsY(other: Rect) = bottom >= other.top && top <= other.bottom diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java index 132c04481bce..4ce45e142c64 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java @@ -209,7 +209,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMovementMenuOnly()", TAG); } - mInMoveMode = true; + setInMoveMode(true); mCloseAfterExitMoveMenu = true; showMenuInternal(); } @@ -219,7 +219,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis if (DEBUG) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMenu()", TAG); } - mInMoveMode = false; + setInMoveMode(false); mCloseAfterExitMoveMenu = false; showMenuInternal(); } @@ -293,6 +293,17 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis return mInMoveMode; } + private void setInMoveMode(boolean moveMode) { + if (mInMoveMode == moveMode) { + return; + } + + mInMoveMode = moveMode; + if (mDelegate != null) { + mDelegate.onInMoveModeChanged(); + } + } + @Override public void onEnterMoveMode() { if (DEBUG) { @@ -300,7 +311,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis "%s: onEnterMoveMode - %b, close when exiting move menu: %b", TAG, mInMoveMode, mCloseAfterExitMoveMenu); } - mInMoveMode = true; + setInMoveMode(true); mPipMenuView.showMoveMenu(mDelegate.getPipGravity()); } @@ -312,13 +323,13 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis mCloseAfterExitMoveMenu); } if (mCloseAfterExitMoveMenu) { - mInMoveMode = false; + setInMoveMode(false); mCloseAfterExitMoveMenu = false; closeMenu(); return true; } if (mInMoveMode) { - mInMoveMode = false; + setInMoveMode(false); mPipMenuView.showButtonsMenu(); return true; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java index 64017e176fc3..d04c34916256 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java @@ -40,6 +40,8 @@ public enum ShellProtoLogGroup implements IProtoLogGroup { Consts.TAG_WM_SHELL), WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM_SHELL), + WM_SHELL_SPLIT_SCREEN(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM_SHELL), TEST_GROUP(true, true, false, "WindowManagerShellProtoLogTest"); private final boolean mEnabled; 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 06f7eda00d1f..f9e1b2fa4c7c 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 @@ -54,6 +54,9 @@ import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_P import static com.android.wm.shell.transition.Transitions.isClosingType; import static com.android.wm.shell.transition.Transitions.isOpeningType; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; @@ -68,6 +71,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.hardware.devicestate.DeviceStateManager; import android.os.Bundle; +import android.os.Debug; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -150,7 +154,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private final int mDisplayId; private SplitLayout mSplitLayout; + private ValueAnimator mDividerFadeInAnimator; private boolean mDividerVisible; + private boolean mKeyguardShowing; private final SyncTransactionQueue mSyncQueue; private final ShellTaskOrganizer mTaskOrganizer; private final Context mContext; @@ -407,6 +413,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSplitLayout.init(); // Set false to avoid record new bounds with old task still on top; mShouldUpdateRecents = false; + mIsDividerRemoteAnimating = true; final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction evictWct = new WindowContainerTransaction(); prepareEvictChildTasks(SPLIT_POSITION_TOP_OR_LEFT, evictWct); @@ -420,7 +427,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, final IRemoteAnimationFinishedCallback finishedCallback) { - mIsDividerRemoteAnimating = true; RemoteAnimationTarget[] augmentedNonApps = new RemoteAnimationTarget[nonApps.length + 1]; for (int i = 0; i < nonApps.length; ++i) { @@ -497,8 +503,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } // Using legacy transitions, so we can't use blast sync since it conflicts. mTaskOrganizer.applyTransaction(wct); - mSyncQueue.runInSync(t -> - updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */)); + mSyncQueue.runInSync(t -> { + setDividerVisibility(true, t); + updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); + }); } private void onRemoteAnimationFinishedOrCancelled(WindowContainerTransaction evictWct) { @@ -513,10 +521,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, ? mSideStage : mMainStage, EXIT_REASON_UNKNOWN)); } else { mSyncQueue.queue(evictWct); - mSyncQueue.runInSync(t -> { - setDividerVisibility(true, t); - updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); - }); } } @@ -626,16 +630,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } void onKeyguardVisibilityChanged(boolean showing) { + mKeyguardShowing = showing; if (!mMainStage.isActive()) { return; } - if (ENABLE_SHELL_TRANSITIONS) { - // Update divider visibility so it won't float on top of keyguard. - setDividerVisibility(!showing, null /* transaction */); - } - - if (!showing && mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) { + if (!mKeyguardShowing && mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) { if (ENABLE_SHELL_TRANSITIONS) { final WindowContainerTransaction wct = new WindowContainerTransaction(); prepareExitSplitScreen(mTopStageAfterFoldDismiss, wct); @@ -646,7 +646,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mTopStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage, EXIT_REASON_DEVICE_FOLDED); } + return; } + + setDividerVisibility(!mKeyguardShowing, null); } void onFinishedWakingUp() { @@ -730,6 +733,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, setResizingSplits(false /* resizing */); t.setWindowCrop(mMainStage.mRootLeash, null) .setWindowCrop(mSideStage.mRootLeash, null); + setDividerVisibility(false, t); }); onTransitionAnimationComplete(); @@ -976,6 +980,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, updateUnfoldBounds(); return; } + // Clear the divider remote animating flag as the divider will be re-rendered to apply + // the new rotation config. + mIsDividerRemoteAnimating = false; mSplitLayout.update(null /* t */); onLayoutSizeChanged(mSplitLayout); } @@ -1055,8 +1062,31 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } private void setDividerVisibility(boolean visible, @Nullable SurfaceControl.Transaction t) { + if (visible == mDividerVisible) { + return; + } + + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "%s: Request to %s divider bar from %s.", TAG, + (visible ? "show" : "hide"), Debug.getCaller()); + + // Defer showing divider bar after keyguard dismissed, so it won't interfere with keyguard + // dismissing animation. + if (visible && mKeyguardShowing) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "%s: Defer showing divider bar due to keyguard showing.", TAG); + return; + } + mDividerVisible = visible; sendSplitVisibilityChanged(); + + if (mIsDividerRemoteAnimating) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "%s: Skip animating divider bar due to it's remote animating.", TAG); + return; + } + if (t != null) { applyDividerVisibility(t); } else { @@ -1066,15 +1096,56 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void applyDividerVisibility(SurfaceControl.Transaction t) { final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash(); - if (mIsDividerRemoteAnimating || dividerLeash == null) return; + if (dividerLeash == null) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "%s: Skip animating divider bar due to divider leash not ready.", TAG); + return; + } + if (mIsDividerRemoteAnimating) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "%s: Skip animating divider bar due to it's remote animating.", TAG); + return; + } + + if (mDividerFadeInAnimator != null && mDividerFadeInAnimator.isRunning()) { + mDividerFadeInAnimator.cancel(); + } if (mDividerVisible) { - t.show(dividerLeash); - t.setAlpha(dividerLeash, 1); - t.setLayer(dividerLeash, Integer.MAX_VALUE); - t.setPosition(dividerLeash, - mSplitLayout.getRefDividerBounds().left, - mSplitLayout.getRefDividerBounds().top); + final SurfaceControl.Transaction transaction = mTransactionPool.acquire(); + mDividerFadeInAnimator = ValueAnimator.ofFloat(0f, 1f); + mDividerFadeInAnimator.addUpdateListener(animation -> { + if (dividerLeash == null) { + mDividerFadeInAnimator.cancel(); + return; + } + transaction.setAlpha(dividerLeash, (float) animation.getAnimatedValue()); + transaction.apply(); + }); + mDividerFadeInAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + if (dividerLeash == null) { + mDividerFadeInAnimator.cancel(); + return; + } + transaction.show(dividerLeash); + transaction.setAlpha(dividerLeash, 0); + transaction.setLayer(dividerLeash, Integer.MAX_VALUE); + transaction.setPosition(dividerLeash, + mSplitLayout.getRefDividerBounds().left, + mSplitLayout.getRefDividerBounds().top); + transaction.apply(); + } + + @Override + public void onAnimationEnd(Animator animation) { + mTransactionPool.release(transaction); + mDividerFadeInAnimator = null; + } + }); + + mDividerFadeInAnimator.start(); } else { t.hide(dividerLeash); } @@ -1096,10 +1167,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSplitLayout.init(); prepareEnterSplitScreen(wct); mSyncQueue.queue(wct); - mSyncQueue.runInSync(t -> { - updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); - setDividerVisibility(true, t); - }); + mSyncQueue.runInSync(t -> + updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */)); } if (mMainStageListener.mHasChildren && mSideStageListener.mHasChildren) { mShouldUpdateRecents = true; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java index d89ddd2074f0..8cee4f1dc8fb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java @@ -35,6 +35,8 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; @@ -53,6 +55,7 @@ import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.util.ArrayMap; +import android.util.DisplayMetrics; import android.util.Slog; import android.view.ContextThemeWrapper; import android.view.SurfaceControl; @@ -68,7 +71,6 @@ import com.android.internal.graphics.palette.VariationalKMeansQuantizer; import com.android.internal.protolog.common.ProtoLog; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.IconProvider; -import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.protolog.ShellProtoLogGroup; @@ -102,7 +104,7 @@ public class SplashscreenContentDrawer { */ private static final float NO_BACKGROUND_SCALE = 192f / 160; private final Context mContext; - private final IconProvider mIconProvider; + private final HighResIconProvider mHighResIconProvider; private int mIconSize; private int mDefaultIconSize; @@ -115,12 +117,10 @@ public class SplashscreenContentDrawer { private final Handler mSplashscreenWorkerHandler; @VisibleForTesting final ColorCache mColorCache; - private final ShellExecutor mSplashScreenExecutor; - SplashscreenContentDrawer(Context context, IconProvider iconProvider, TransactionPool pool, - ShellExecutor splashScreenExecutor) { + SplashscreenContentDrawer(Context context, IconProvider iconProvider, TransactionPool pool) { mContext = context; - mIconProvider = iconProvider; + mHighResIconProvider = new HighResIconProvider(mContext, iconProvider); mTransactionPool = pool; // Initialize Splashscreen worker thread @@ -131,7 +131,6 @@ public class SplashscreenContentDrawer { shellSplashscreenWorkerThread.start(); mSplashscreenWorkerHandler = shellSplashscreenWorkerThread.getThreadHandler(); mColorCache = new ColorCache(mContext, mSplashscreenWorkerHandler); - mSplashScreenExecutor = splashScreenExecutor; } /** @@ -416,18 +415,16 @@ public class SplashscreenContentDrawer { || mTmpAttrs.mIconBgColor == mThemeColor) { mFinalIconSize *= NO_BACKGROUND_SCALE; } - createIconDrawable(iconDrawable, false); + createIconDrawable(iconDrawable, false /* legacy */, false /* loadInDetail */); } else { final float iconScale = (float) mIconSize / (float) mDefaultIconSize; final int densityDpi = mContext.getResources().getConfiguration().densityDpi; final int scaledIconDpi = (int) (0.5f + iconScale * densityDpi * NO_BACKGROUND_SCALE); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "getIcon"); - iconDrawable = mIconProvider.getIcon(mActivityInfo, scaledIconDpi); + iconDrawable = mHighResIconProvider.getIcon( + mActivityInfo, densityDpi, scaledIconDpi); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - if (iconDrawable == null) { - iconDrawable = mContext.getPackageManager().getDefaultActivityIcon(); - } if (!processAdaptiveIcon(iconDrawable)) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW, "The icon is not an AdaptiveIconDrawable"); @@ -437,7 +434,8 @@ public class SplashscreenContentDrawer { scaledIconDpi, mFinalIconSize); final Bitmap bitmap = factory.createScaledBitmapWithoutShadow(iconDrawable); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - createIconDrawable(new BitmapDrawable(bitmap), true); + createIconDrawable(new BitmapDrawable(bitmap), true, + mHighResIconProvider.mLoadInDetail); } } @@ -450,14 +448,16 @@ public class SplashscreenContentDrawer { } } - private void createIconDrawable(Drawable iconDrawable, boolean legacy) { + private void createIconDrawable(Drawable iconDrawable, boolean legacy, + boolean loadInDetail) { if (legacy) { mFinalIconDrawables = SplashscreenIconDrawableFactory.makeLegacyIconDrawable( - iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler); + iconDrawable, mDefaultIconSize, mFinalIconSize, loadInDetail, + mSplashscreenWorkerHandler); } else { mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable( mTmpAttrs.mIconBgColor, mThemeColor, iconDrawable, mDefaultIconSize, - mFinalIconSize, mSplashscreenWorkerHandler); + mFinalIconSize, loadInDetail, mSplashscreenWorkerHandler); } } @@ -506,11 +506,11 @@ public class SplashscreenContentDrawer { // Using AdaptiveIconDrawable here can help keep the shape consistent with the // current settings. mFinalIconSize = (int) (0.5f + mIconSize * noBgScale); - createIconDrawable(iconForeground, false); + createIconDrawable(iconForeground, false, mHighResIconProvider.mLoadInDetail); } else { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW, "processAdaptiveIcon: draw whole icon"); - createIconDrawable(iconDrawable, false); + createIconDrawable(iconDrawable, false, mHighResIconProvider.mLoadInDetail); } Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); return true; @@ -1015,4 +1015,77 @@ public class SplashscreenContentDrawer { playAnimation.run(); } } + + /** + * When loading a BitmapDrawable object with specific density, there will decode the image based + * on the density from display metrics, so even when load with higher override density, the + * final intrinsic size of a BitmapDrawable can still not big enough to draw on expect size. + * + * So here we use a standalone IconProvider object to load the Drawable object for higher + * density, and the resources object won't affect the entire system. + * + */ + private static class HighResIconProvider { + private final Context mSharedContext; + private final IconProvider mSharedIconProvider; + private boolean mLoadInDetail; + + // only create standalone icon provider when the density dpi is low. + private Context mStandaloneContext; + private IconProvider mStandaloneIconProvider; + + HighResIconProvider(Context context, IconProvider sharedIconProvider) { + mSharedContext = context; + mSharedIconProvider = sharedIconProvider; + } + + Drawable getIcon(ActivityInfo activityInfo, int currentDpi, int iconDpi) { + mLoadInDetail = false; + Drawable drawable; + if (currentDpi < iconDpi && currentDpi < DisplayMetrics.DENSITY_XHIGH) { + drawable = loadFromStandalone(activityInfo, currentDpi, iconDpi); + } else { + drawable = mSharedIconProvider.getIcon(activityInfo, iconDpi); + } + + if (drawable == null) { + drawable = mSharedContext.getPackageManager().getDefaultActivityIcon(); + } + return drawable; + } + + private Drawable loadFromStandalone(ActivityInfo activityInfo, int currentDpi, + int iconDpi) { + if (mStandaloneContext == null) { + final Configuration defConfig = mSharedContext.getResources().getConfiguration(); + mStandaloneContext = mSharedContext.createConfigurationContext(defConfig); + mStandaloneIconProvider = new IconProvider(mStandaloneContext); + } + Resources resources; + try { + resources = mStandaloneContext.getPackageManager() + .getResourcesForApplication(activityInfo.applicationInfo); + } catch (PackageManager.NameNotFoundException | Resources.NotFoundException exc) { + resources = null; + } + if (resources != null) { + updateResourcesDpi(resources, iconDpi); + } + final Drawable drawable = mStandaloneIconProvider.getIcon(activityInfo, iconDpi); + mLoadInDetail = true; + // reset density dpi + if (resources != null) { + updateResourcesDpi(resources, currentDpi); + } + return drawable; + } + + private void updateResourcesDpi(Resources resources, int densityDpi) { + final Configuration config = resources.getConfiguration(); + final DisplayMetrics displayMetrics = resources.getDisplayMetrics(); + config.densityDpi = densityDpi; + displayMetrics.densityDpi = densityDpi; + resources.updateConfiguration(config, displayMetrics); + } + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java index 5f52071bf950..7f6bfd23f72b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java @@ -62,7 +62,7 @@ public class SplashscreenIconDrawableFactory { */ static Drawable[] makeIconDrawable(@ColorInt int backgroundColor, @ColorInt int themeColor, @NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize, - Handler splashscreenWorkerHandler) { + boolean loadInDetail, Handler splashscreenWorkerHandler) { Drawable foreground; Drawable background = null; boolean drawBackground = @@ -74,13 +74,13 @@ public class SplashscreenIconDrawableFactory { // If the icon is Adaptive, we already use the icon background. drawBackground = false; foreground = new ImmobileIconDrawable(foregroundDrawable, - srcIconSize, iconSize, splashscreenWorkerHandler); + srcIconSize, iconSize, loadInDetail, splashscreenWorkerHandler); } else { // Adaptive icon don't handle transparency so we draw the background of the adaptive // icon with the same color as the window background color instead of using two layers foreground = new ImmobileIconDrawable( new AdaptiveForegroundDrawable(foregroundDrawable), - srcIconSize, iconSize, splashscreenWorkerHandler); + srcIconSize, iconSize, loadInDetail, splashscreenWorkerHandler); } if (drawBackground) { @@ -91,9 +91,9 @@ public class SplashscreenIconDrawableFactory { } static Drawable[] makeLegacyIconDrawable(@NonNull Drawable iconDrawable, int srcIconSize, - int iconSize, Handler splashscreenWorkerHandler) { + int iconSize, boolean loadInDetail, Handler splashscreenWorkerHandler) { return new Drawable[]{new ImmobileIconDrawable(iconDrawable, srcIconSize, iconSize, - splashscreenWorkerHandler)}; + loadInDetail, splashscreenWorkerHandler)}; } /** @@ -106,11 +106,16 @@ public class SplashscreenIconDrawableFactory { private final Matrix mMatrix = new Matrix(); private Bitmap mIconBitmap; - ImmobileIconDrawable(Drawable drawable, int srcIconSize, int iconSize, + ImmobileIconDrawable(Drawable drawable, int srcIconSize, int iconSize, boolean loadInDetail, Handler splashscreenWorkerHandler) { - final float scale = (float) iconSize / srcIconSize; - mMatrix.setScale(scale, scale); - splashscreenWorkerHandler.post(() -> preDrawIcon(drawable, srcIconSize)); + // This icon has lower density, don't scale it. + if (loadInDetail) { + splashscreenWorkerHandler.post(() -> preDrawIcon(drawable, iconSize)); + } else { + final float scale = (float) iconSize / srcIconSize; + mMatrix.setScale(scale, scale); + splashscreenWorkerHandler.post(() -> preDrawIcon(drawable, srcIconSize)); + } } private void preDrawIcon(Drawable drawable, int size) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java index 464ab1ae2a8c..54d62edf2570 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java @@ -153,8 +153,7 @@ public class StartingSurfaceDrawer { mContext = context; mDisplayManager = mContext.getSystemService(DisplayManager.class); mSplashScreenExecutor = splashScreenExecutor; - mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconProvider, pool, - mSplashScreenExecutor); + mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconProvider, pool); mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance()); mWindowManagerGlobal = WindowManagerGlobal.getInstance(); mDisplayManager.getDisplay(DEFAULT_DISPLAY); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index 98eee7ba33a0..903dfc20eaf7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -23,6 +23,7 @@ import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; +import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT; @@ -287,12 +288,14 @@ public class Transitions implements RemoteCallable<Transitions> { finishT.setAlpha(leash, 1.f); } } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) { - // Wallpaper is a bit of an anomaly: it's visibility is tied to other WindowStates. - // As a result, we actually can't hide it's WindowToken because there may not be a - // transition associated with it becoming visible again. Fortunately, since it is - // always z-ordered to the back, we don't have to worry about it flickering to the - // front during reparenting, so the hide here isn't necessary for it. - if ((change.getFlags() & FLAG_IS_WALLPAPER) == 0) { + // Wallpaper/IME are anomalies: their visibility is tied to other WindowStates. + // As a result, we actually can't hide their WindowTokens because there may not be a + // transition associated with them becoming visible again. Fortunately, since + // wallpapers are always z-ordered to the back, we don't have to worry about it + // flickering to the front during reparenting. Similarly, the IME is reparented to + // the associated app, so its visibility is coupled. So, an explicit hide is not + // needed visually anyways. + if ((change.getFlags() & (FLAG_IS_WALLPAPER | FLAG_IS_INPUT_METHOD)) == 0) { finishT.hide(leash); } } diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp index a899709c1405..ea10be564351 100644 --- a/libs/WindowManager/Shell/tests/unittest/Android.bp +++ b/libs/WindowManager/Shell/tests/unittest/Android.bp @@ -37,6 +37,7 @@ android_test { "androidx.test.ext.junit", "androidx.dynamicanimation_dynamicanimation", "dagger2", + "frameworks-base-testutils", "kotlinx-coroutines-android", "kotlinx-coroutines-core", "mockito-target-extended-minus-junit4", diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipBoundsControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipBoundsControllerTest.kt new file mode 100644 index 000000000000..05e472245b4a --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipBoundsControllerTest.kt @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.pip.tv + +import android.content.Context +import android.content.res.Resources +import android.graphics.Rect +import android.os.Handler +import android.os.test.TestLooper +import android.testing.AndroidTestingRunner + +import com.android.wm.shell.R +import com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT +import com.android.wm.shell.pip.tv.TvPipBoundsController.POSITION_DEBOUNCE_TIMEOUT_MILLIS +import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement + +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.AdditionalAnswers.returnsFirstArg +import org.mockito.Mock +import org.mockito.Mockito.`when` as whenever +import org.mockito.Mockito.any +import org.mockito.Mockito.anyInt +import org.mockito.Mockito.eq +import org.mockito.Mockito.never +import org.mockito.Mockito.reset +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +class TvPipBoundsControllerTest { + val ANIMATION_DURATION = 100 + val STASH_DURATION = 5000 + val FAR_FUTURE = 60 * 60000L + val ANCHOR_BOUNDS = Rect(90, 90, 100, 100) + val STASHED_BOUNDS = Rect(99, 90, 109, 100) + val MOVED_BOUNDS = Rect(90, 80, 100, 90) + val STASHED_MOVED_BOUNDS = Rect(99, 80, 109, 90) + val ANCHOR_PLACEMENT = Placement(ANCHOR_BOUNDS, ANCHOR_BOUNDS) + val STASHED_PLACEMENT = Placement(STASHED_BOUNDS, ANCHOR_BOUNDS, + STASH_TYPE_RIGHT, ANCHOR_BOUNDS, false) + val STASHED_PLACEMENT_RESTASH = Placement(STASHED_BOUNDS, ANCHOR_BOUNDS, + STASH_TYPE_RIGHT, ANCHOR_BOUNDS, true) + val MOVED_PLACEMENT = Placement(MOVED_BOUNDS, ANCHOR_BOUNDS) + val STASHED_MOVED_PLACEMENT = Placement(STASHED_MOVED_BOUNDS, ANCHOR_BOUNDS, + STASH_TYPE_RIGHT, MOVED_BOUNDS, false) + val STASHED_MOVED_PLACEMENT_RESTASH = Placement(STASHED_MOVED_BOUNDS, ANCHOR_BOUNDS, + STASH_TYPE_RIGHT, MOVED_BOUNDS, true) + + lateinit var boundsController: TvPipBoundsController + var time = 0L + lateinit var testLooper: TestLooper + lateinit var mainHandler: Handler + + var inMenu = false + var inMoveMode = false + + @Mock + lateinit var context: Context + @Mock + lateinit var resources: Resources + @Mock + lateinit var tvPipBoundsState: TvPipBoundsState + @Mock + lateinit var tvPipBoundsAlgorithm: TvPipBoundsAlgorithm + @Mock + lateinit var listener: TvPipBoundsController.PipBoundsListener + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + time = 0L + inMenu = false + inMoveMode = false + + testLooper = TestLooper { time } + mainHandler = Handler(testLooper.getLooper()) + + whenever(context.resources).thenReturn(resources) + whenever(resources.getInteger(R.integer.config_pipStashDuration)).thenReturn(STASH_DURATION) + whenever(tvPipBoundsAlgorithm.adjustBoundsForTemporaryDecor(any())) + .then(returnsFirstArg<Rect>()) + + boundsController = TvPipBoundsController( + context, + { time }, + mainHandler, + tvPipBoundsState, + tvPipBoundsAlgorithm) + boundsController.setListener(listener) + } + + @Test + fun testPlacement_MovedAfterDebounceTimeout() { + triggerPlacement(MOVED_PLACEMENT) + assertMovementAt(POSITION_DEBOUNCE_TIMEOUT_MILLIS, MOVED_BOUNDS) + assertNoMovementUpTo(time + FAR_FUTURE) + } + + @Test + fun testStashedPlacement_MovedAfterDebounceTimeout_Unstashes() { + triggerPlacement(STASHED_PLACEMENT_RESTASH) + assertMovementAt(POSITION_DEBOUNCE_TIMEOUT_MILLIS, STASHED_BOUNDS) + assertMovementAt(POSITION_DEBOUNCE_TIMEOUT_MILLIS + STASH_DURATION, ANCHOR_BOUNDS) + } + + @Test + fun testDebounceSamePlacement_MovesDebounceTimeoutAfterFirstPlacement() { + triggerPlacement(MOVED_PLACEMENT) + advanceTimeTo(POSITION_DEBOUNCE_TIMEOUT_MILLIS / 2) + triggerPlacement(MOVED_PLACEMENT) + + assertMovementAt(POSITION_DEBOUNCE_TIMEOUT_MILLIS, MOVED_BOUNDS) + } + + @Test + fun testNoMovementUntilPlacementStabilizes() { + triggerPlacement(ANCHOR_PLACEMENT) + advanceTimeTo(time + POSITION_DEBOUNCE_TIMEOUT_MILLIS / 10) + triggerPlacement(MOVED_PLACEMENT) + advanceTimeTo(time + POSITION_DEBOUNCE_TIMEOUT_MILLIS / 10) + triggerPlacement(ANCHOR_PLACEMENT) + advanceTimeTo(time + POSITION_DEBOUNCE_TIMEOUT_MILLIS / 10) + triggerPlacement(MOVED_PLACEMENT) + + assertMovementAt(time + POSITION_DEBOUNCE_TIMEOUT_MILLIS, MOVED_BOUNDS) + } + + @Test + fun testUnstashIfStashNoLongerNecessary() { + triggerPlacement(STASHED_PLACEMENT_RESTASH) + assertMovementAt(POSITION_DEBOUNCE_TIMEOUT_MILLIS, STASHED_BOUNDS) + + triggerPlacement(ANCHOR_PLACEMENT) + assertMovementAt(time + POSITION_DEBOUNCE_TIMEOUT_MILLIS, ANCHOR_BOUNDS) + } + + @Test + fun testRestashingPlacementDelaysUnstash() { + triggerPlacement(STASHED_PLACEMENT_RESTASH) + assertMovementAt(POSITION_DEBOUNCE_TIMEOUT_MILLIS, STASHED_BOUNDS) + + assertNoMovementUpTo(time + STASH_DURATION / 2) + triggerPlacement(STASHED_PLACEMENT_RESTASH) + assertNoMovementUpTo(time + POSITION_DEBOUNCE_TIMEOUT_MILLIS) + assertMovementAt(time + STASH_DURATION, ANCHOR_BOUNDS) + } + + @Test + fun testNonRestashingPlacementDoesNotDelayUnstash() { + triggerPlacement(STASHED_PLACEMENT_RESTASH) + assertMovementAt(POSITION_DEBOUNCE_TIMEOUT_MILLIS, STASHED_BOUNDS) + + assertNoMovementUpTo(time + STASH_DURATION / 2) + triggerPlacement(STASHED_PLACEMENT) + assertMovementAt(POSITION_DEBOUNCE_TIMEOUT_MILLIS + STASH_DURATION, ANCHOR_BOUNDS) + } + + @Test + fun testImmediatePlacement() { + triggerImmediatePlacement(STASHED_PLACEMENT_RESTASH) + assertMovement(STASHED_BOUNDS) + assertMovementAt(time + STASH_DURATION, ANCHOR_BOUNDS) + } + + @Test + fun testInMoveMode_KeepAtAnchor() { + startMoveMode() + triggerImmediatePlacement(STASHED_MOVED_PLACEMENT_RESTASH) + assertMovement(ANCHOR_BOUNDS) + assertNoMovementUpTo(time + FAR_FUTURE) + } + + @Test + fun testInMenu_Unstashed() { + openPipMenu() + triggerImmediatePlacement(STASHED_MOVED_PLACEMENT_RESTASH) + assertMovement(MOVED_BOUNDS) + assertNoMovementUpTo(time + FAR_FUTURE) + } + + @Test + fun testCloseMenu_DoNotRestash() { + openPipMenu() + triggerImmediatePlacement(STASHED_MOVED_PLACEMENT_RESTASH) + assertMovement(MOVED_BOUNDS) + + closePipMenu() + triggerPlacement(STASHED_MOVED_PLACEMENT) + assertNoMovementUpTo(time + FAR_FUTURE) + } + + fun assertMovement(bounds: Rect) { + verify(listener).onPipTargetBoundsChange(eq(bounds), anyInt()) + reset(listener) + } + + fun assertMovementAt(timeMs: Long, bounds: Rect) { + assertNoMovementUpTo(timeMs - 1) + advanceTimeTo(timeMs) + assertMovement(bounds) + } + + fun assertNoMovementUpTo(timeMs: Long) { + advanceTimeTo(timeMs) + verify(listener, never()).onPipTargetBoundsChange(any(), anyInt()) + } + + fun triggerPlacement(placement: Placement, immediate: Boolean = false) { + whenever(tvPipBoundsAlgorithm.getTvPipPlacement()).thenReturn(placement) + val stayAtAnchorPosition = inMoveMode + val disallowStashing = inMenu || stayAtAnchorPosition + boundsController.recalculatePipBounds(stayAtAnchorPosition, disallowStashing, + ANIMATION_DURATION, immediate) + } + + fun triggerImmediatePlacement(placement: Placement) { + triggerPlacement(placement, true) + } + + fun openPipMenu() { + inMenu = true + inMoveMode = false + } + + fun closePipMenu() { + inMenu = false + inMoveMode = false + } + + fun startMoveMode() { + inMenu = true + inMoveMode = true + } + + fun advanceTimeTo(ms: Long) { + time = ms + testLooper.dispatchAll() + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt index 46f388d0ce0e..0fcc5cf384c9 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithmTest.kt @@ -30,7 +30,9 @@ import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement import org.junit.Before import org.junit.Test import junit.framework.Assert.assertEquals +import junit.framework.Assert.assertFalse import junit.framework.Assert.assertNull +import junit.framework.Assert.assertTrue @RunWith(AndroidTestingRunner::class) class TvPipKeepClearAlgorithmTest { @@ -46,7 +48,6 @@ class TvPipKeepClearAlgorithmTest { private lateinit var pipSize: Size private lateinit var movementBounds: Rect private lateinit var algorithm: TvPipKeepClearAlgorithm - private var currentTime = 0L private var restrictedAreas = mutableSetOf<Rect>() private var unrestrictedAreas = mutableSetOf<Rect>() private var gravity: Int = 0 @@ -58,16 +59,14 @@ class TvPipKeepClearAlgorithmTest { restrictedAreas.clear() unrestrictedAreas.clear() - currentTime = 0L pipSize = DEFAULT_PIP_SIZE gravity = Gravity.BOTTOM or Gravity.RIGHT - algorithm = TvPipKeepClearAlgorithm({ currentTime }) + algorithm = TvPipKeepClearAlgorithm() algorithm.setScreenSize(SCREEN_SIZE) algorithm.setMovementBounds(movementBounds) algorithm.pipAreaPadding = PADDING algorithm.stashOffset = STASH_OFFSET - algorithm.stashDuration = 5000L algorithm.setGravity(gravity) algorithm.maxRestrictedDistanceFraction = 0.3 } @@ -265,7 +264,7 @@ class TvPipKeepClearAlgorithmTest { assertEquals(expectedBounds, placement.bounds) assertEquals(STASH_TYPE_BOTTOM, placement.stashType) assertEquals(getExpectedAnchorBounds(), placement.unstashDestinationBounds) - assertEquals(algorithm.stashDuration, placement.unstashTime) + assertTrue(placement.triggerStash) } @Test @@ -305,7 +304,7 @@ class TvPipKeepClearAlgorithmTest { assertEquals(expectedBounds, placement.bounds) assertEquals(STASH_TYPE_RIGHT, placement.stashType) assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds) - assertEquals(algorithm.stashDuration, placement.unstashTime) + assertTrue(placement.triggerStash) } @Test @@ -352,9 +351,7 @@ class TvPipKeepClearAlgorithmTest { assertEquals(expectedBounds, placement.bounds) assertEquals(STASH_TYPE_RIGHT, placement.stashType) assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds) - assertEquals(algorithm.stashDuration, placement.unstashTime) - - currentTime += 1000 + assertTrue(placement.triggerStash) restrictedAreas.remove(sideBar) placement = getActualPlacement() @@ -363,7 +360,7 @@ class TvPipKeepClearAlgorithmTest { } @Test - fun test_Stashed_UnstashBoundsStaysObstructed_UnstashesAfterTimeout() { + fun test_Stashed_UnstashBoundsStaysObstructed_DoesNotTriggerStash() { gravity = Gravity.BOTTOM or Gravity.RIGHT val bottomBar = makeBottomBar(BOTTOM_SHEET_HEIGHT) @@ -384,13 +381,13 @@ class TvPipKeepClearAlgorithmTest { assertEquals(expectedBounds, placement.bounds) assertEquals(STASH_TYPE_RIGHT, placement.stashType) assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds) - assertEquals(algorithm.stashDuration, placement.unstashTime) - - currentTime += algorithm.stashDuration + assertTrue(placement.triggerStash) placement = getActualPlacement() - assertEquals(expectedUnstashBounds, placement.bounds) - assertNotStashed(placement) + assertEquals(expectedBounds, placement.bounds) + assertEquals(STASH_TYPE_RIGHT, placement.stashType) + assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds) + assertFalse(placement.triggerStash) } @Test @@ -415,9 +412,7 @@ class TvPipKeepClearAlgorithmTest { assertEquals(expectedBounds, placement.bounds) assertEquals(STASH_TYPE_RIGHT, placement.stashType) assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds) - assertEquals(algorithm.stashDuration, placement.unstashTime) - - currentTime += 1000 + assertTrue(placement.triggerStash) val newObstruction = Rect( 0, @@ -431,7 +426,7 @@ class TvPipKeepClearAlgorithmTest { assertEquals(expectedBounds, placement.bounds) assertEquals(STASH_TYPE_RIGHT, placement.stashType) assertEquals(expectedUnstashBounds, placement.unstashDestinationBounds) - assertEquals(currentTime + algorithm.stashDuration, placement.unstashTime) + assertTrue(placement.triggerStash) } @Test @@ -458,21 +453,9 @@ class TvPipKeepClearAlgorithmTest { @Test fun test_PipInsets() { - val permInsets = Insets.of(-1, -2, -3, -4) - algorithm.setPipPermanentDecorInsets(permInsets) - testInsetsForAllPositions(permInsets) - - val tempInsets = Insets.of(-4, -3, -2, -1) - algorithm.setPipPermanentDecorInsets(Insets.NONE) - algorithm.setPipTemporaryDecorInsets(tempInsets) - testInsetsForAllPositions(tempInsets) - - algorithm.setPipPermanentDecorInsets(permInsets) - algorithm.setPipTemporaryDecorInsets(tempInsets) - testInsetsForAllPositions(Insets.add(permInsets, tempInsets)) - } + val insets = Insets.of(-1, -2, -3, -4) + algorithm.setPipPermanentDecorInsets(insets) - private fun testInsetsForAllPositions(insets: Insets) { gravity = Gravity.BOTTOM or Gravity.RIGHT testAnchorPositionWithInsets(insets) @@ -546,6 +529,6 @@ class TvPipKeepClearAlgorithmTest { private fun assertNotStashed(actual: Placement) { assertEquals(STASH_TYPE_NONE, actual.stashType) assertNull(actual.unstashDestinationBounds) - assertEquals(0L, actual.unstashTime) + assertFalse(actual.triggerStash) } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java index 0e39527a9e5f..b52690487944 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java @@ -139,6 +139,7 @@ public class SplitTransitionTests extends ShellTestCase { } @Test + @UiThreadTest public void testLaunchToSide() { ActivityManager.RunningTaskInfo newTask = new TestRunningTaskInfoBuilder() .setParentTaskId(mSideStage.mRootTaskInfo.taskId).build(); @@ -173,6 +174,7 @@ public class SplitTransitionTests extends ShellTestCase { } @Test + @UiThreadTest public void testLaunchPair() { TransitionInfo info = createEnterPairInfo(); @@ -195,6 +197,7 @@ public class SplitTransitionTests extends ShellTestCase { } @Test + @UiThreadTest public void testMonitorInSplit() { enterSplit(); @@ -251,6 +254,7 @@ public class SplitTransitionTests extends ShellTestCase { } @Test + @UiThreadTest public void testEnterRecents() { enterSplit(); @@ -288,6 +292,7 @@ public class SplitTransitionTests extends ShellTestCase { } @Test + @UiThreadTest public void testDismissFromBeingOccluded() { enterSplit(); @@ -325,6 +330,7 @@ public class SplitTransitionTests extends ShellTestCase { } @Test + @UiThreadTest public void testDismissFromMultiWindowSupport() { enterSplit(); @@ -346,6 +352,7 @@ public class SplitTransitionTests extends ShellTestCase { } @Test + @UiThreadTest public void testDismissSnap() { enterSplit(); @@ -370,6 +377,7 @@ public class SplitTransitionTests extends ShellTestCase { } @Test + @UiThreadTest public void testDismissFromAppFinish() { enterSplit(); diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp index 4826d5a0c8da..078041411a21 100644 --- a/libs/hwui/AnimatorManager.cpp +++ b/libs/hwui/AnimatorManager.cpp @@ -31,7 +31,8 @@ static void detach(sp<BaseRenderNodeAnimator>& animator) { animator->detach(); } -AnimatorManager::AnimatorManager(RenderNode& parent) : mParent(parent), mAnimationHandle(nullptr) {} +AnimatorManager::AnimatorManager(RenderNode& parent) + : mParent(parent), mAnimationHandle(nullptr), mCancelAllAnimators(false) {} AnimatorManager::~AnimatorManager() { for_each(mNewAnimators.begin(), mNewAnimators.end(), detach); @@ -82,8 +83,16 @@ void AnimatorManager::pushStaging() { } mNewAnimators.clear(); } - for (auto& animator : mAnimators) { - animator->pushStaging(mAnimationHandle->context()); + + if (mCancelAllAnimators) { + for (auto& animator : mAnimators) { + animator->forceEndNow(mAnimationHandle->context()); + } + mCancelAllAnimators = false; + } else { + for (auto& animator : mAnimators) { + animator->pushStaging(mAnimationHandle->context()); + } } } @@ -184,5 +193,9 @@ void AnimatorManager::endAllActiveAnimators() { mAnimationHandle->release(); } +void AnimatorManager::forceEndAnimators() { + mCancelAllAnimators = true; +} + } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h index a0df01d5962c..6002661dc82a 100644 --- a/libs/hwui/AnimatorManager.h +++ b/libs/hwui/AnimatorManager.h @@ -16,11 +16,11 @@ #ifndef ANIMATORMANAGER_H #define ANIMATORMANAGER_H -#include <vector> - #include <cutils/compiler.h> #include <utils/StrongPointer.h> +#include <vector> + #include "utils/Macros.h" namespace android { @@ -56,6 +56,8 @@ public: // Hard-ends all animators. May only be called on the UI thread. void endAllStagingAnimators(); + void forceEndAnimators(); + // Hard-ends all animators that have been pushed. Used for cleanup if // the ActivityContext is being destroyed void endAllActiveAnimators(); @@ -71,6 +73,8 @@ private: // To improve the efficiency of resizing & removing from the vector std::vector<sp<BaseRenderNodeAnimator> > mNewAnimators; std::vector<sp<BaseRenderNodeAnimator> > mAnimators; + + bool mCancelAllAnimators; }; } /* namespace uirenderer */ diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp index 944393c63ad6..db7639029187 100644 --- a/libs/hwui/jni/android_graphics_RenderNode.cpp +++ b/libs/hwui/jni/android_graphics_RenderNode.cpp @@ -543,6 +543,12 @@ static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz, renderNode->animators().endAllStagingAnimators(); } +static void android_view_RenderNode_forceEndAnimators(JNIEnv* env, jobject clazz, + jlong renderNodePtr) { + RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); + renderNode->animators().forceEndAnimators(); +} + // ---------------------------------------------------------------------------- // SurfaceView position callback // ---------------------------------------------------------------------------- @@ -745,6 +751,7 @@ static const JNINativeMethod gMethods[] = { {"nGetAllocatedSize", "(J)I", (void*)android_view_RenderNode_getAllocatedSize}, {"nAddAnimator", "(JJ)V", (void*)android_view_RenderNode_addAnimator}, {"nEndAllAnimators", "(J)V", (void*)android_view_RenderNode_endAllAnimators}, + {"nForceEndAnimators", "(J)V", (void*)android_view_RenderNode_forceEndAnimators}, {"nRequestPositionUpdates", "(JLjava/lang/ref/WeakReference;)V", (void*)android_view_RenderNode_requestPositionUpdates}, diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java index 11cacd01f53d..44b4662cdca5 100644 --- a/media/java/android/media/AudioDeviceVolumeManager.java +++ b/media/java/android/media/AudioDeviceVolumeManager.java @@ -235,13 +235,7 @@ public class AudioDeviceVolumeManager { mDeviceVolumeDispatcherStub = new DeviceVolumeDispatcherStub(); } } else { - for (ListenerInfo info : mDeviceVolumeListeners) { - if (info.mListener == vclistener) { - throw new IllegalArgumentException( - "attempt to call setDeviceAbsoluteMultiVolumeBehavior() " - + "on a previously registered listener"); - } - } + mDeviceVolumeListeners.removeIf(info -> info.mDevice.equalTypeAddress(device)); } mDeviceVolumeListeners.add(listenerInfo); mDeviceVolumeDispatcherStub.register(true, device, volumes, handlesVolumeAdjustment); diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 55c558f36880..85cd342b5e11 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -2910,6 +2910,10 @@ public class AudioTrack extends PlayerBase * For portability, an application should prime the data path to the maximum allowed * by writing data until the write() method returns a short transfer count. * This allows play() to start immediately, and reduces the chance of underrun. + *<p> + * As of {@link android.os.Build.VERSION_CODES#S} the minimum level to start playing + * can be obtained using {@link #getStartThresholdInFrames()} and set with + * {@link #setStartThresholdInFrames(int)}. * * @throws IllegalStateException if the track isn't properly initialized */ diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index ef0270b5414c..e5673a613b59 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -1728,7 +1728,9 @@ public class Tuner implements AutoCloseable { } int res = nativeSetMaxNumberOfFrontends(frontendType, maxNumber); if (res == RESULT_SUCCESS) { - // TODO: b/211778848 Update Tuner Resource Manager. + if (!mTunerResourceManager.setMaxNumberOfFrontends(frontendType, maxNumber)) { + res = RESULT_INVALID_ARGUMENT; + } } return res; } @@ -1749,7 +1751,13 @@ public class Tuner implements AutoCloseable { TunerVersionChecker.TUNER_VERSION_2_0, "Set maximum Frontends")) { return -1; } - return nativeGetMaxNumberOfFrontends(frontendType); + int maxNumFromHAL = nativeGetMaxNumberOfFrontends(frontendType); + int maxNumFromTRM = mTunerResourceManager.getMaxNumberOfFrontends(frontendType); + if (maxNumFromHAL != maxNumFromTRM) { + Log.w(TAG, "max num of usable frontend is out-of-sync b/w " + maxNumFromHAL + + " != " + maxNumFromTRM); + } + return maxNumFromHAL; } /** @hide */ diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java index 5ada89e9dea7..15175a783924 100644 --- a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java +++ b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java @@ -401,6 +401,43 @@ public class TunerResourceManager { } /** + * Sets the maximum usable frontends number of a given frontend type. It is used to enable or + * disable frontends when cable connection status is changed by user. + * + * @param frontendType the frontendType which the maximum usable number will be set for. + * @param maxNum the new maximum usable number. + * + * @return true if successful and false otherwise. + */ + public boolean setMaxNumberOfFrontends(int frontendType, int maxNum) { + boolean result = false; + try { + result = mService.setMaxNumberOfFrontends(frontendType, maxNum); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + return result; + } + + /** + * Get the maximum usable frontends number of a given frontend type. + * + * @param frontendType the frontendType which the maximum usable number will be queried for. + * + * @return the maximum usable number of the queried frontend type. Returns -1 when the + * frontendType is invalid + */ + public int getMaxNumberOfFrontends(int frontendType) { + int result = -1; + try { + result = mService.getMaxNumberOfFrontends(frontendType); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + return result; + } + + /** * Requests from the client to share frontend with an existing client. * * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called diff --git a/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl b/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl index d16fc6ca1dc7..144b98c36655 100644 --- a/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl +++ b/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl @@ -166,6 +166,27 @@ interface ITunerResourceManager { boolean requestFrontend(in TunerFrontendRequest request, out int[] frontendHandle); /* + * Sets the maximum usable frontends number of a given frontend type. It is used to enable or + * disable frontends when cable connection status is changed by user. + * + * @param frontendType the frontendType which the maximum usable number will be set for. + * @param maxNumber the new maximum usable number. + * + * @return true if successful and false otherwise. + */ + boolean setMaxNumberOfFrontends(in int frontendType, in int maxNum); + + /* + * Get the maximum usable frontends number of a given frontend type. + * + * @param frontendType the frontendType which the maximum usable number will be queried for. + * + * @return the maximum usable number of the queried frontend type. Returns -1 when the + * frontendType is invalid + */ + int getMaxNumberOfFrontends(in int frontendType); + + /* * Requests to share frontend with an existing client. * * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp index f4a39b3469bb..b7ad6dcf9354 100644 --- a/media/jni/android_media_Utils.cpp +++ b/media/jni/android_media_Utils.cpp @@ -18,10 +18,10 @@ #define LOG_TAG "AndroidMediaUtils" #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h> -#include <hardware/camera3.h> #include <ui/GraphicBufferMapper.h> #include <ui/GraphicTypes.h> #include <utils/Log.h> + #include "android_media_Utils.h" #define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) ) @@ -122,8 +122,8 @@ uint32_t Image_getBlobSize(LockedImage* buffer, bool usingRGBAOverride) { } // First check for BLOB transport header at the end of the buffer - uint8_t* header = blobBuffer + (width - sizeof(struct camera3_jpeg_blob)); - struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header); + uint8_t* header = blobBuffer + (width - sizeof(struct camera3_jpeg_blob_v2)); + struct camera3_jpeg_blob_v2 *blob = (struct camera3_jpeg_blob_v2*)(header); if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID || blob->jpeg_blob_id == CAMERA3_HEIC_BLOB_ID) { size = blob->jpeg_size; diff --git a/media/jni/android_media_Utils.h b/media/jni/android_media_Utils.h index 4feb4f516f1e..c12cec129ede 100644 --- a/media/jni/android_media_Utils.h +++ b/media/jni/android_media_Utils.h @@ -50,6 +50,20 @@ int getBufferWidth(BufferItem *buffer); int getBufferHeight(BufferItem *buffer); +// Must be in sync with AIDL CameraBlob : android.hardware.camera.device.CameraBlob +// HALs must NOT copy this definition. +// for details: http://b/229688810 +typedef struct camera3_jpeg_blob_v2 { + uint32_t jpeg_blob_id; + uint32_t jpeg_size; +} camera3_jpeg_blobv2_t; + +// Must be in sync with AIDL CameraBlob : android.hardware.camera.device.CameraBlobId +enum { + CAMERA3_JPEG_BLOB_ID = 0x00FF, + CAMERA3_JPEG_APP_SEGMENTS_BLOB_ID = 0x0100, +}; + }; // namespace android #endif // _ANDROID_MEDIA_UTILS_H_ diff --git a/packages/BackupRestoreConfirmation/res/values-eu/strings.xml b/packages/BackupRestoreConfirmation/res/values-eu/strings.xml index 5b522787032c..6f734a37cdae 100644 --- a/packages/BackupRestoreConfirmation/res/values-eu/strings.xml +++ b/packages/BackupRestoreConfirmation/res/values-eu/strings.xml @@ -18,10 +18,10 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="backup_confirm_title" msgid="827563724209303345">"Babeskopia osoa"</string> <string name="restore_confirm_title" msgid="5469365809567486602">"Leheneratze osoa"</string> - <string name="backup_confirm_text" msgid="1878021282758896593">"Datu guztien babeskopia egitea eta konektatutako ordenagailu batean gordetzea eskatu da. Horretarako baimena eman nahi duzu?\n\nEz baduzu babeskopia egitea zuk eskatu, ez eman eragiketarekin jarraitzeko baimena."</string> + <string name="backup_confirm_text" msgid="1878021282758896593">"Datu guztien babeskopia egitea eta konektatutako ordenagailu batean gordetzea eskatu da. Horretarako baimena eman nahi duzu?\n\nBabeskopia egitea zeuk eskatu ez baduzu, ez eman eragiketarekin jarraitzeko baimena."</string> <string name="allow_backup_button_label" msgid="4217228747769644068">"Egin datuen babeskopia"</string> <string name="deny_backup_button_label" msgid="6009119115581097708">"Ez egin babeskopia"</string> - <string name="restore_confirm_text" msgid="7499866728030461776">"Konektatutako ordenagailu bateko datu guztiak leheneratzeko eskatu da. Horretarako baimena eman nahi duzu?\n\nEz baduzu leheneratzea zuk eskatu, ez eman eragiketarekin jarraitzeko baimena. Eragiketa gauzatzen bada, gailuan dituzun datu guztiak ordeztuko dira!"</string> + <string name="restore_confirm_text" msgid="7499866728030461776">"Konektatutako ordenagailu bateko datu guztiak leheneratzeko eskatu da. Horretarako baimena eman nahi duzu?\n\nLeheneratzea zeuk eskatu ez baduzu, ez eman eragiketarekin jarraitzeko baimena. Eragiketa gauzatzen bada, gailuan dituzun datu guztiak ordeztuko dira!"</string> <string name="allow_restore_button_label" msgid="3081286752277127827">"Leheneratu datuak"</string> <string name="deny_restore_button_label" msgid="1724367334453104378">"Ez leheneratu"</string> <string name="current_password_text" msgid="8268189555578298067">"Idatzi babeskopien oraingo pasahitza behean:"</string> diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml index 8b5d214f7a10..16cd2e55136c 100644 --- a/packages/CompanionDeviceManager/AndroidManifest.xml +++ b/packages/CompanionDeviceManager/AndroidManifest.xml @@ -46,6 +46,7 @@ android:launchMode="singleInstance" android:excludeFromRecents="true" android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE" + android:configChanges="orientation|screenSize" android:theme="@style/ChooserActivity"/> <service diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml new file mode 100644 index 000000000000..8d7fa26acff4 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml @@ -0,0 +1,27 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="@android:color/system_accent1_200"> + <path + android:pathData="M6.2529,18.5H16.2529V17.5H18.2529V21.5C18.2529,22.6 17.3529,23.5 16.2529,23.5H6.2529C5.1529,23.5 4.2529,22.6 4.2529,21.5V3.5C4.2529,2.4 5.1529,1.51 6.2529,1.51L16.2529,1.5C17.3529,1.5 18.2529,2.4 18.2529,3.5V7.5H16.2529V6.5H6.2529V18.5ZM16.2529,3.5H6.2529V4.5H16.2529V3.5ZM6.2529,21.5V20.5H16.2529V21.5H6.2529ZM12.6553,9.4049C12.6553,8.8526 13.103,8.4049 13.6553,8.4049H20.5254C21.0776,8.4049 21.5254,8.8526 21.5254,9.4049V14.6055C21.5254,15.1578 21.0776,15.6055 20.5254,15.6055H14.355L12.6553,17.0871V9.4049Z" + android:fillColor="#3C4043" + android:fillType="evenOdd"/> +</vector>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_info.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_info.xml new file mode 100644 index 000000000000..5689e34d0886 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable-night/ic_info.xml @@ -0,0 +1,25 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="@android:color/system_accent1_200"> + <path android:fillColor="@android:color/white" + android:pathData="M11,17H13V11H11ZM12,9Q12.425,9 12.713,8.712Q13,8.425 13,8Q13,7.575 12.713,7.287Q12.425,7 12,7Q11.575,7 11.288,7.287Q11,7.575 11,8Q11,8.425 11.288,8.712Q11.575,9 12,9ZM12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12ZM12,20Q15.325,20 17.663,17.663Q20,15.325 20,12Q20,8.675 17.663,6.337Q15.325,4 12,4Q8.675,4 6.338,6.337Q4,8.675 4,12Q4,15.325 6.338,17.663Q8.675,20 12,20Z"/> +</vector>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml new file mode 100644 index 000000000000..06bfad5b8efd --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="@android:color/system_accent1_200"> + <path android:fillColor="@android:color/white" + android:pathData="M4,19V17H6V10Q6,7.925 7.25,6.312Q8.5,4.7 10.5,4.2V3.5Q10.5,2.875 10.938,2.438Q11.375,2 12,2Q12.625,2 13.062,2.438Q13.5,2.875 13.5,3.5V4.2Q15.5,4.7 16.75,6.312Q18,7.925 18,10V17H20V19ZM12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5ZM12,22Q11.175,22 10.588,21.413Q10,20.825 10,20H14Q14,20.825 13.413,21.413Q12.825,22 12,22ZM8,17H16V10Q16,8.35 14.825,7.175Q13.65,6 12,6Q10.35,6 9.175,7.175Q8,8.35 8,10Z"/> +</vector>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml new file mode 100644 index 000000000000..f8aef33c88ea --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml @@ -0,0 +1,25 @@ +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="@android:color/system_accent1_200"> + <path android:fillColor="@android:color/white" + android:pathData="M6,17H18L14.25,12L11.25,16L9,13ZM5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21ZM5,19H19Q19,19 19,19Q19,19 19,19V5Q19,5 19,5Q19,5 19,5H5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19ZM5,5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19Q5,19 5,19Q5,19 5,19V5Q5,5 5,5Q5,5 5,5Z"/> +</vector>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/helper_back_button.xml b/packages/CompanionDeviceManager/res/drawable/helper_back_button.xml index 8e92051faf6c..6ce1f1263638 100644 --- a/packages/CompanionDeviceManager/res/drawable/helper_back_button.xml +++ b/packages/CompanionDeviceManager/res/drawable/helper_back_button.xml @@ -18,6 +18,6 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@android:color/system_accent1_100"/> - <corners android:topLeftRadius="16dp" android:topRightRadius="16dp" - android:bottomLeftRadius="16dp" android:bottomRightRadius="16dp"/> + <corners android:topLeftRadius="20dp" android:topRightRadius="20dp" + android:bottomLeftRadius="20dp" android:bottomRightRadius="20dp"/> </shape>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable/ic_apps.xml index d1ec8637775c..7295e78b16cb 100644 --- a/packages/CompanionDeviceManager/res/drawable/ic_apps.xml +++ b/packages/CompanionDeviceManager/res/drawable/ic_apps.xml @@ -19,7 +19,8 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24"> + android:viewportHeight="24" + android:tint="@android:color/system_accent1_600"> <path android:pathData="M6.2529,18.5H16.2529V17.5H18.2529V21.5C18.2529,22.6 17.3529,23.5 16.2529,23.5H6.2529C5.1529,23.5 4.2529,22.6 4.2529,21.5V3.5C4.2529,2.4 5.1529,1.51 6.2529,1.51L16.2529,1.5C17.3529,1.5 18.2529,2.4 18.2529,3.5V7.5H16.2529V6.5H6.2529V18.5ZM16.2529,3.5H6.2529V4.5H16.2529V3.5ZM6.2529,21.5V20.5H16.2529V21.5H6.2529ZM12.6553,9.4049C12.6553,8.8526 13.103,8.4049 13.6553,8.4049H20.5254C21.0776,8.4049 21.5254,8.8526 21.5254,9.4049V14.6055C21.5254,15.1578 21.0776,15.6055 20.5254,15.6055H14.355L12.6553,17.0871V9.4049Z" android:fillColor="#3C4043" diff --git a/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml index e5825bcbf70c..7b1ef85ae5fd 100644 --- a/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml +++ b/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml @@ -20,7 +20,7 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:tint="@android:color/system_accent1_600"> <path android:fillColor="@android:color/white" android:pathData="M4,19V17H6V10Q6,7.925 7.25,6.312Q8.5,4.7 10.5,4.2V3.5Q10.5,2.875 10.938,2.438Q11.375,2 12,2Q12.625,2 13.062,2.438Q13.5,2.875 13.5,3.5V4.2Q15.5,4.7 16.75,6.312Q18,7.925 18,10V17H20V19ZM12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5ZM12,22Q11.175,22 10.588,21.413Q10,20.825 10,20H14Q14,20.825 13.413,21.413Q12.825,22 12,22ZM8,17H16V10Q16,8.35 14.825,7.175Q13.65,6 12,6Q10.35,6 9.175,7.175Q8,8.35 8,10Z"/> </vector>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable/ic_storage.xml index 406a3b5dada5..3e033d372e72 100644 --- a/packages/CompanionDeviceManager/res/drawable/ic_storage.xml +++ b/packages/CompanionDeviceManager/res/drawable/ic_storage.xml @@ -20,7 +20,7 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:tint="@android:color/system_accent1_600"> <path android:fillColor="@android:color/white" android:pathData="M6,17H18L14.25,12L11.25,16L9,13ZM5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21ZM5,19H19Q19,19 19,19Q19,19 19,19V5Q19,5 19,5Q19,5 19,5H5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19ZM5,5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19Q5,19 5,19Q5,19 5,19V5Q5,5 5,5Q5,5 5,5Z"/> </vector>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml index c0e6c09d69ed..520ade892f51 100644 --- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml +++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml @@ -12,135 +12,142 @@ See the License for the specific language governing permissions and limitations under the License. --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/activity_confirmation" +<ScrollView + xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:minWidth="340dp"> + android:layout_height="match_parent" + style="@style/ScrollViewStyle"> - <LinearLayout android:id="@+id/association_confirmation" - style="@style/ContainerLayout"> + <LinearLayout + android:id="@+id/activity_confirmation" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:baselineAligned="false"> - <!-- A header for selfManaged devices only. --> - <include layout="@layout/vendor_header" /> + <LinearLayout android:id="@+id/association_confirmation" + style="@style/ContainerLayout"> - <!-- Do NOT change the ID of the root LinearLayout above: it's referenced in CTS tests. --> + <!-- A header for selfManaged devices only. --> + <include layout="@layout/vendor_header" /> - <ImageView - android:id="@+id/profile_icon" - android:layout_width="match_parent" - android:layout_height="32dp" - android:gravity="center" - android:layout_marginTop="18dp" - android:tint="@android:color/system_accent1_600"/> + <!-- Do NOT change the ID of the root LinearLayout above: + it's referenced in CTS tests. --> - <LinearLayout style="@style/Description"> - <TextView - android:id="@+id/title" - style="@style/DescriptionTitle" /> + <ImageView + android:id="@+id/profile_icon" + android:layout_width="match_parent" + android:layout_height="32dp" + android:gravity="center" + android:layout_marginTop="18dp" + android:tint="@android:color/system_accent1_600"/> - <TextView - android:id="@+id/summary" - style="@style/DescriptionSummary" /> + <LinearLayout style="@style/Description"> + <TextView + android:id="@+id/title" + style="@style/DescriptionTitle" /> - </LinearLayout> + <TextView + android:id="@+id/summary" + style="@style/DescriptionSummary" /> - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1"> + </LinearLayout> - <LinearLayout - android:id="@+id/multiple_device_list" + <RelativeLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="12dp" - android:layout_marginBottom="12dp" - android:orientation="vertical" - android:visibility="gone"> + android:layout_height="0dp" + android:layout_weight="1"> + + <LinearLayout + android:id="@+id/multiple_device_list" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="12dp" + android:layout_marginBottom="12dp" + android:orientation="vertical" + android:visibility="gone"> + + <View + android:id="@+id/border_top" + style="@style/DeviceListBorder" /> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/device_list" + android:layout_width="match_parent" + android:scrollbars="vertical" + android:layout_marginBottom="12dp" + android:layout_height="200dp" /> - <View - android:id="@+id/border_top" - style="@style/DeviceListBorder" /> + <View + android:id="@+id/border_bottom" + style="@style/DeviceListBorder" /> + + </LinearLayout> <androidx.recyclerview.widget.RecyclerView - android:id="@+id/device_list" + android:id="@+id/permission_list" android:layout_width="match_parent" - android:scrollbars="vertical" - android:layout_marginBottom="12dp" - android:layout_height="200dp" /> + android:layout_height="wrap_content" /> - <View - android:id="@+id/border_bottom" - style="@style/DeviceListBorder" /> + <ProgressBar + android:id="@+id/spinner_multiple_device" + android:visibility="gone" + style="@style/Spinner" /> - </LinearLayout> + </RelativeLayout> - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/permission_list" + <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content" /> + android:layout_height="wrap_content" + android:gravity="center" + android:orientation="vertical" + android:layout_marginTop="16dp"> - <ProgressBar - android:id="@+id/spinner_multiple_device" - android:visibility="gone" - style="@style/Spinner" /> + <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. --> - </RelativeLayout> + <Button + android:id="@+id/btn_positive" + style="@style/PositiveButton" + android:text="@string/consent_yes" /> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:orientation="vertical" - android:layout_marginTop="16dp"> + <Button + android:id="@+id/btn_negative" + android:layout_marginBottom="12dp" + style="@style/NegativeButton" + android:text="@string/consent_no" /> - <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. --> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="bottom|end" + android:orientation="vertical" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp"> - <Button - android:id="@+id/btn_positive" - style="@style/PositiveButton" - android:text="@string/consent_yes" /> + <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. --> - <Button - android:id="@+id/btn_negative" - android:layout_marginBottom="12dp" - style="@style/NegativeButton" - android:text="@string/consent_no" /> + <Button + android:id="@+id/btn_negative_multiple_devices" + style="@style/NegativeButtonMultipleDevices" + android:textColor="?android:textColorPrimary" + android:visibility="gone" + android:text="@string/consent_no" /> + </LinearLayout> </LinearLayout> - <LinearLayout + <RelativeLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="bottom|right" - android:orientation="vertical" - android:layout_marginRight="16dp" - android:layout_marginBottom="16dp"> - - <!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. --> + android:layout_height="match_parent" + android:layout_weight="1"> - <Button - android:id="@+id/btn_negative_multiple_devices" - style="@style/NegativeButtonMultipleDevices" - android:textColor="?android:textColorPrimary" + <ProgressBar + android:id="@+id/spinner_single_device" android:visibility="gone" - android:text="@string/consent_no" /> - </LinearLayout> + style="@style/Spinner" /> + </RelativeLayout>> </LinearLayout> - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_weight="1"> - - <ProgressBar - android:id="@+id/spinner_single_device" - android:visibility="gone" - style="@style/Spinner" /> - </RelativeLayout>> - -</LinearLayout>
\ No newline at end of file +</ScrollView>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml index a9ace44d49b8..d0d46f715846 100644 --- a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml +++ b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml @@ -15,54 +15,67 @@ ~ limitations under the License. --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/helper_confirmation" - android:theme="@style/ChooserActivity" - android:padding="12dp" - style="@style/ContainerLayout"> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + style="@style/ScrollViewStyle"> - <ImageView - android:id="@+id/app_icon" + <LinearLayout android:layout_width="match_parent" - android:layout_height="32dp" - android:gravity="center" - android:layout_marginTop="12dp" - android:layout_marginBottom="12dp"/> + android:layout_height="wrap_content"> - <TextView - android:id="@+id/helper_title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:paddingHorizontal="12dp" - android:textColor="?android:attr/textColorPrimary" - android:textSize="22sp" /> + <LinearLayout + android:id="@+id/helper_confirmation" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/ChooserActivity" + android:padding="12dp" + style="@style/ContainerLayout"> - <TextView - android:id="@+id/helper_summary" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginLeft="24dp" - android:layout_marginRight="24dp" - android:layout_marginTop="12dp" - android:layout_marginBottom="24dp" - android:gravity="center" - android:textColor="?android:attr/textColorSecondary" - android:textSize="14sp" /> + <ImageView + android:id="@+id/app_icon" + android:layout_width="match_parent" + android:layout_height="48dp" + android:gravity="center" + android:layout_marginTop="12dp" + android:layout_marginBottom="12dp"/> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:layout_marginRight="12dp" - android:layout_marginBottom="12dp" - android:gravity="end"> + <TextView + android:id="@+id/helper_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:textColor="?android:attr/textColorPrimary" + android:textSize="22sp" /> + + <TextView + android:id="@+id/helper_summary" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="24dp" + android:layout_marginEnd="24dp" + android:layout_marginTop="12dp" + android:layout_marginBottom="32dp" + android:gravity="center" + android:textColor="?android:attr/textColorSecondary" + android:textSize="14sp" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:layout_marginEnd="12dp" + android:gravity="end"> + + <Button + android:id="@+id/btn_back" + style="@style/VendorHelperBackButton" + android:text="@string/consent_back" /> + + </LinearLayout> - <Button - android:id="@+id/btn_back" - style="@style/VendorHelperBackButton" - android:text="@string/consent_back" /> + </LinearLayout> </LinearLayout> -</LinearLayout>
\ No newline at end of file +</ScrollView>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml index eeb988f364b2..0a5afe4363ac 100644 --- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml +++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml @@ -28,14 +28,15 @@ android:id="@android:id/icon" android:layout_width="24dp" android:layout_height="24dp" - android:layout_marginLeft="24dp" - android:layout_marginRight="12dp" + android:layout_marginStart="24dp" android:tint="@android:color/system_accent1_600"/> <TextView android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingStart="24dp" + android:paddingEnd="24dp" android:singleLine="true" android:textAppearance="?android:attr/textAppearanceListItemSmall"/> diff --git a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml index 3dce38d0dc20..54916a24b7df 100644 --- a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml +++ b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml @@ -20,8 +20,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:paddingLeft="32dp" - android:paddingRight="32dp" + android:paddingStart="32dp" + android:paddingEnd="32dp" android:paddingBottom="14dp"> <ImageView @@ -30,7 +30,6 @@ android:layout_height="24dp" android:layout_marginTop="8dp" android:layout_marginEnd="12dp" - android:tint="@android:color/system_accent1_600" android:contentDescription="Permission Icon"/> <LinearLayout @@ -51,7 +50,6 @@ android:id="@+id/permission_summary" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingRight="24dp" android:textSize="14sp" android:textColor="?android:attr/textColorSecondary"/> diff --git a/packages/CompanionDeviceManager/res/layout/vendor_header.xml b/packages/CompanionDeviceManager/res/layout/vendor_header.xml index c35f59e7e8a0..14e74312dd2c 100644 --- a/packages/CompanionDeviceManager/res/layout/vendor_header.xml +++ b/packages/CompanionDeviceManager/res/layout/vendor_header.xml @@ -24,28 +24,32 @@ android:layout_gravity="center" android:paddingTop="24dp" android:paddingBottom="4dp" - android:paddingLeft="24dp" - android:paddingRight="24dp" + android:paddingStart="24dp" + android:paddingEnd="24dp" android:visibility="gone" > <ImageView android:id="@+id/vendor_header_image" - android:layout_width="31dp" - android:layout_height="32dp" /> + android:layout_width="48dp" + android:layout_height="48dp" + android:contentDescription="@string/vendor_icon_description" /> <TextView android:id="@+id/vendor_header_name" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginLeft="20dp" - android:layout_marginTop="5dp" - android:layout_toRightOf="@+id/header_image" /> + android:layout_marginStart="12dp" + android:layout_marginTop="12dp" + android:textSize="16sp" + android:layout_toEndOf="@+id/vendor_header_image" + android:textColor="?android:attr/textColorSecondary"/> <ImageButton android:id="@+id/vendor_header_button" android:background="@drawable/ic_info" - android:layout_width="31dp" - android:layout_height="32dp" - android:layout_alignParentRight="true" /> + android:layout_width="48dp" + android:layout_height="48dp" + android:contentDescription="@string/vendor_header_button_description" + android:layout_alignParentEnd="true" /> </RelativeLayout>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml index 663d7c5d9cc5..df9702b279d2 100644 --- a/packages/CompanionDeviceManager/res/values-fa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml @@ -39,7 +39,7 @@ <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه میخواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> برنامهها را بین دستگاههای شما جاریسازی کند"</string> <string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string> <string name="summary_generic" msgid="2346762210105903720"></string> - <string name="consent_yes" msgid="8344487259618762872">"مجاز است"</string> + <string name="consent_yes" msgid="8344487259618762872">"اجازه دادن"</string> <string name="consent_no" msgid="2640796915611404382">"مجاز نبودن"</string> <string name="consent_back" msgid="2560683030046918882">"برگشت"</string> <string name="permission_sync_confirmation_title" msgid="667074294393493186">"انتقال اجازههای برنامه به ساعت"</string> diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml index 586a0223b460..3d6bf152f93f 100644 --- a/packages/CompanionDeviceManager/res/values/strings.xml +++ b/packages/CompanionDeviceManager/res/values/strings.xml @@ -116,4 +116,10 @@ apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch\u2019s microphone and location.</string> + <!--Description for vendor icon [CHAR LIMIT=30]--> + <string name="vendor_icon_description">App Icon</string> + + <!--Description for information icon [CHAR LIMIT=30]--> + <string name="vendor_header_button_description">More Information Button</string> + </resources> diff --git a/packages/CompanionDeviceManager/res/values/styles.xml b/packages/CompanionDeviceManager/res/values/styles.xml index c38323f5f73c..428f2dc2eb35 100644 --- a/packages/CompanionDeviceManager/res/values/styles.xml +++ b/packages/CompanionDeviceManager/res/values/styles.xml @@ -59,9 +59,8 @@ <style name="VendorHelperBackButton" parent="@android:style/Widget.Material.Button.Borderless.Colored"> - <item name="android:layout_width">60dp</item> - <item name="android:layout_height">36dp</item> - <item name="android:layout_marginTop">20dp</item> + <item name="android:layout_width">70dp</item> + <item name="android:layout_height">48dp</item> <item name="android:textAllCaps">false</item> <item name="android:textColor">@android:color/system_neutral1_900</item> <item name="android:background">@drawable/helper_back_button</item> @@ -71,8 +70,6 @@ parent="@android:style/Widget.Material.Button.Borderless.Colored"> <item name="android:layout_width">300dp</item> <item name="android:layout_height">56dp</item> - <item name="android:layout_marginLeft">24dp</item> - <item name="android:layout_marginRight">24dp</item> <item name="android:layout_marginBottom">2dp</item> <item name="android:textAllCaps">false</item> <item name="android:textSize">14sp</item> @@ -84,8 +81,6 @@ parent="@android:style/Widget.Material.Button.Borderless.Colored"> <item name="android:layout_width">300dp</item> <item name="android:layout_height">56dp</item> - <item name="android:layout_marginLeft">24dp</item> - <item name="android:layout_marginRight">24dp</item> <item name="android:layout_marginTop">2dp</item> <item name="android:textAllCaps">false</item> <item name="android:textSize">14sp</item> @@ -115,4 +110,10 @@ <item name="android:indeterminate">true</item> <item name="android:layout_centerInParent">true</item> </style> + + <style name="ScrollViewStyle"> + <item name="android:scrollbars">none</item> + <item name="android:fillViewport">true</item> + <item name="android:clipChildren">false</item> + </style> </resources>
\ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/values/themes.xml b/packages/CompanionDeviceManager/res/values/themes.xml index e3fc67c50d75..1ea3968a5984 100644 --- a/packages/CompanionDeviceManager/res/values/themes.xml +++ b/packages/CompanionDeviceManager/res/values/themes.xml @@ -18,8 +18,8 @@ <style name="ChooserActivity" parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar"> - <item name="*android:windowFixedHeightMajor">100%</item> - <item name="*android:windowFixedHeightMinor">100%</item> + <item name="android:windowContentOverlay">@null</item> + <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@android:color/transparent</item> </style> diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java index 5e918641e49f..9e9ec04fbd93 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java @@ -51,6 +51,7 @@ import android.companion.CompanionDeviceManager; import android.companion.IAssociationRequestCallback; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.net.MacAddress; import android.os.Bundle; @@ -411,17 +412,19 @@ public class CompanionDeviceActivity extends FragmentActivity implements final Drawable vendorIcon; final CharSequence vendorName; final Spanned title; + int nightModeFlags = getResources().getConfiguration().uiMode + & Configuration.UI_MODE_NIGHT_MASK; mPermissionTypes = new ArrayList<>(); try { vendorIcon = getVendorHeaderIcon(this, packageName, userId); vendorName = getVendorHeaderName(this, packageName, userId); - mVendorHeaderImage.setImageDrawable(vendorIcon); if (hasVendorIcon(this, packageName, userId)) { - mVendorHeaderImage.setColorFilter(getResources().getColor( - android.R.color.system_accent1_600, /* Theme= */null)); + int color = nightModeFlags == Configuration.UI_MODE_NIGHT_YES + ? android.R.color.system_accent1_200 : android.R.color.system_accent1_600; + mVendorHeaderImage.setColorFilter(getResources().getColor(color, /* Theme= */null)); } } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Package u" + userId + "/" + packageName + " not found."); diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java index f333b86d4d52..fc5ff085139c 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java @@ -123,6 +123,7 @@ public class CompanionDeviceDiscoveryService extends Service { intent.setAction(ACTION_START_DISCOVERY); intent.putExtra(EXTRA_ASSOCIATION_REQUEST, associationRequest); sStateLiveData.setValue(DiscoveryState.STARTING); + sScanResultsLiveData.setValue(Collections.emptyList()); context.startService(intent); } @@ -173,7 +174,6 @@ public class CompanionDeviceDiscoveryService extends Service { @Override public void onDestroy() { - sScanResultsLiveData.setValue(Collections.emptyList()); super.onDestroy(); if (DEBUG) Log.d(TAG, "onDestroy()"); } @@ -187,7 +187,6 @@ public class CompanionDeviceDiscoveryService extends Service { mStopAfterFirstMatch = request.isSingleDevice(); mDiscoveryStarted = true; sStateLiveData.setValue(DiscoveryState.DISCOVERY_IN_PROGRESS); - sScanResultsLiveData.setValue(Collections.emptyList()); final List<DeviceFilter<?>> allFilters = request.getDeviceFilters(); final List<BluetoothDeviceFilter> btFilters = diff --git a/packages/CtsShim/build/Android.bp b/packages/CtsShim/build/Android.bp index 7cf5385bd841..af3e2102e430 100644 --- a/packages/CtsShim/build/Android.bp +++ b/packages/CtsShim/build/Android.bp @@ -47,6 +47,7 @@ android_app { uses_libs: ["android.test.runner"], apex_available: [ + "//apex_available:platform", "com.android.apex.cts.shim.v2_apk_in_apex_upgrades", ], } diff --git a/packages/SettingsLib/BannerMessagePreference/res/values-gl/strings.xml b/packages/SettingsLib/BannerMessagePreference/res/values-gl/strings.xml index d7876261ebdd..816cbf67c6a6 100644 --- a/packages/SettingsLib/BannerMessagePreference/res/values-gl/strings.xml +++ b/packages/SettingsLib/BannerMessagePreference/res/values-gl/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"Ignorar"</string> + <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"Pechar"</string> </resources> diff --git a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java index ac306361386e..6766cdd0beb6 100644 --- a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java +++ b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java @@ -40,6 +40,8 @@ public class FooterPreference extends Preference { static final int ORDER_FOOTER = Integer.MAX_VALUE - 1; @VisibleForTesting View.OnClickListener mLearnMoreListener; + @VisibleForTesting + int mIconVisibility = View.VISIBLE; private CharSequence mContentDescription; private CharSequence mLearnMoreText; private CharSequence mLearnMoreContentDescription; @@ -84,6 +86,9 @@ public class FooterPreference extends Preference { } else { learnMore.setVisibility(View.GONE); } + + View icon = holder.itemView.findViewById(R.id.icon_frame); + icon.setVisibility(mIconVisibility); } @Override @@ -165,6 +170,17 @@ public class FooterPreference extends Preference { } } + /** + * Set visibility of footer icon. + */ + public void setIconVisibility(int iconVisibility) { + if (mIconVisibility == iconVisibility) { + return; + } + mIconVisibility = iconVisibility; + notifyChanged(); + } + private void init() { setLayoutResource(R.layout.preference_footer); if (getIcon() == null) { diff --git a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/WorkPolicyUtils.java b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/WorkPolicyUtils.java index 5693c2f22d1e..281f7ba6a5ea 100644 --- a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/WorkPolicyUtils.java +++ b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/WorkPolicyUtils.java @@ -27,17 +27,20 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import androidx.annotation.Nullable; + import java.util.List; + /** * Utility class for find out when to show WorkPolicyInfo */ public class WorkPolicyUtils { - Context mContext; - PackageManager mPackageManager; - UserManager mUserManager; - DevicePolicyManager mDevicePolicyManager; + private final Context mContext; + private final PackageManager mPackageManager; + private final UserManager mUserManager; + private final DevicePolicyManager mDevicePolicyManager; private static final int USER_NULL = -10000; @@ -81,7 +84,12 @@ public class WorkPolicyUtils { return false; } - private Intent getWorkPolicyInfoIntentDO() { + /** + * Returns the work policy info intent if the device owner component exists, + * and returns {@code null} otherwise + */ + @Nullable + public Intent getWorkPolicyInfoIntentDO() { final ComponentName ownerComponent = getDeviceOwnerComponent(); if (ownerComponent == null) { return null; @@ -99,43 +107,55 @@ public class WorkPolicyUtils { return null; } - private Intent getWorkPolicyInfoIntentPO() { + @Nullable + private ComponentName getManagedProfileOwnerComponent(int managedUserId) { + if (managedUserId == USER_NULL) { + return null; + } + Context managedProfileContext; try { - final int managedUserId = getManagedProfileUserId(); - if (managedUserId == USER_NULL) { - return null; - } - - Context managedProfileContext = + managedProfileContext = mContext.createPackageContextAsUser( mContext.getPackageName(), 0, UserHandle.of(managedUserId) ); + } catch (PackageManager.NameNotFoundException e) { + return null; + } - DevicePolicyManager managedProfileDevicePolicyManager = - (DevicePolicyManager) - managedProfileContext.getSystemService(Context.DEVICE_POLICY_SERVICE); - ComponentName ownerComponent = managedProfileDevicePolicyManager.getProfileOwner(); - if (ownerComponent == null) { - return null; - } - - // Only search for the required action in the Profile Owner's package - final Intent intent = - new Intent(Settings.ACTION_SHOW_WORK_POLICY_INFO) - .setPackage(ownerComponent.getPackageName()); - final List<ResolveInfo> activities = - mPackageManager.queryIntentActivitiesAsUser( - intent, 0, UserHandle.of(managedUserId)); - if (activities.size() != 0) { - return intent; - } + DevicePolicyManager managedProfileDevicePolicyManager = + (DevicePolicyManager) + managedProfileContext.getSystemService(Context.DEVICE_POLICY_SERVICE); + ComponentName ownerComponent = managedProfileDevicePolicyManager.getProfileOwner(); + return ownerComponent; + } - return null; - } catch (PackageManager.NameNotFoundException e) { + /** + * Returns the work policy info intent if the profile owner component exists, + * and returns {@code null} otherwise + */ + @Nullable + public Intent getWorkPolicyInfoIntentPO() { + final int managedUserId = getManagedProfileUserId(); + ComponentName ownerComponent = getManagedProfileOwnerComponent(managedUserId); + if (ownerComponent == null) { return null; } + + // Only search for the required action in the Profile Owner's package + final Intent intent = + new Intent(Settings.ACTION_SHOW_WORK_POLICY_INFO) + .setPackage(ownerComponent.getPackageName()); + final List<ResolveInfo> activities = + mPackageManager.queryIntentActivitiesAsUser( + intent, 0, UserHandle.of(managedUserId)); + if (activities.size() != 0) { + return intent; + } + + return null; } + @Nullable private ComponentName getDeviceOwnerComponent() { if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) { return null; @@ -143,7 +163,10 @@ public class WorkPolicyUtils { return mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser(); } - private int getManagedProfileUserId() { + /** + * Returns the user id of the managed profile, and returns {@code USER_NULL} otherwise + */ + public int getManagedProfileUserId() { List<UserHandle> allProfiles = mUserManager.getAllProfiles(); for (UserHandle uh : allProfiles) { int id = uh.getIdentifier(); diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 9f5cf35db62a..0533a2ab56a7 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Verlaat gasmodus"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Alle aktiwiteit sal uitgevee word wanneer jy uitgaan"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Jy kan jou aktiwiteit stoor of uitvee wanneer jy uitgaan"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Stel terug om sessie-aktiwiteit nou uit te vee, of jy kan aktiwiteit stoor of uitvee wanneer jy uitgaan"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Stel terug om aktiwiteit nou uit te vee, of stoor of vee aktiwiteit uit wanneer jy uitgaan"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Neem \'n foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Kies \'n prent"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Kies foto"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"As jy <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitsaai of die uitvoer verander, sal jou huidige uitsending stop"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Saai <xliff:g id="SWITCHAPP">%1$s</xliff:g> uit"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Verander uitvoer"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Voorspellingteruggebaaranimasies"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktiveer stelselanimasies vir voorspellingteruggebaar."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Hierdie instelling aktiveer stelselanimasies vir voorspellinggebaaranimasie. Dit vereis dat enableOnBackInvokedCallback per program op waar gestel word in die manifeslêer."</string> </resources> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 747a935fa740..b94cb7e4abd3 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ያሰራጩ"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"ውፅዓትን ይቀይሩ"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"የግምት ጀርባ እነማዎች"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"ለግምት ጀርባ የስርዓት እንማዎችን ያንቁ።"</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ይህ ቅንብር የስርዓት እነማዎችን ለመገመት የምልክት እነማን ያነቃል። በዝርዝር ሰነድ ፋይሉ ውስጥ በእያንዳንዱ መተግበሪያ enableOnBackInvokedCallbackን ወደ እውነት ማቀናበር ያስፈልገዋል።"</string> </resources> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index f9585ad106a7..ad3ea6b992b9 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"إذا أجريت بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g> أو غيَّرت جهاز الإخراج، سيتوقَف البث الحالي."</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"تغيير جهاز الإخراج"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index 7d4e6abb584c..8583057de9ca 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"যদি আপুনি <xliff:g id="SWITCHAPP">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰে অথবা আউটপুট সলনি কৰে, তেন্তে, আপোনাৰ বৰ্তমানৰ সম্প্ৰচাৰ বন্ধ হৈ যাব"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্ৰচাৰ কৰক"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"আউটপুট সলনি কৰক"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"প্ৰেডিক্টিভ বেক এনিমেশ্বন"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"প্ৰেডিক্টিভ বেকৰ বাবে ছিষ্টেম এনিমেশ্বন সক্ষম কৰক।"</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"এই ছেটিংটোৱে প্ৰেডিক্টিভ বেক এনিমেশ্বনৰ বাবে ছিষ্টেম এনিমেশ্বন সক্ষম কৰে। ইয়াৰ বাবে মেনিফেষ্ট ফাইলত প্ৰতি এপত enableOnBackInvokedCallback সত্য বুলি ছেট কৰাৰ প্ৰয়োজন।"</string> </resources> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index ed7c4b4cd847..e78e11b5f565 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlasanız və ya nəticəni dəyişsəniz, cari yayımınız dayandırılacaq"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlayın"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Nəticəni dəyişdirin"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Proqnozlaşdırılan geri animasiyalar"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Proqnozlaşdırıcı geri jest üçün sistem animasiyalarını aktiv edin."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Bu ayar proqnozlaşdırıcı jest animasiyası üçün sistem animasiyalarını aktiv edir. Bu, manifest faylında hər bir tətbiq üçün enableOnBackInvokedCallback-in doğru kimi ayarlanmasını tələb edir."</string> </resources> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index f85d31451f6f..1aaff825e7e9 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -594,7 +594,7 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesiju gosta"</string> <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Želite li da resetujete sesiju gosta?"</string> - <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Želite li da uklonite gosta?"</string> + <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Želite da uklonite gosta?"</string> <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string> <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ukloni"</string> <string name="guest_resetting" msgid="7822120170191509566">"Sesija gosta se resetuje…"</string> @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Izađi iz režima gosta"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sve aktivnosti će biti izbrisane pri izlazu"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete da sačuvate ili izbrišete aktivnosti pri izlazu"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetujete da biste izbrisali aktivnosti sesije odmah ili možete da sačuvate ili izbrišete aktivnosti pri izlazu"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetujete za brisanje aktivnosti sesije, ili sačuvajte ili izbrišite aktivnosti pri izlazu"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Izaberite sliku"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitujte aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Promenite izlaz"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije za pokret povratka sa predviđanjem"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogućite animacije sistema za pokret povratka sa predviđanjem."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ovo podešavanje omogućava animacije sistema za pokret povratka sa predviđanjem. Zahteva podešavanje dozvole enableOnBackInvokedCallback po aplikaciji na true u fajlu manifesta."</string> </resources> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 6188dc1cfa42..17d31ff302e4 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Выйсці з гасцявога рэжыму"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Падчас выхаду будуць выдалены ўсе звесткі пра дзеянні"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Падчас выхаду можна захаваць ці выдаліць звесткі пра дзеянні"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Скіньце налады, каб выдаліць звесткі пра дзеянні падчас сеанса. Таксама можна захаваць ці выдаліць гэтыя звесткі ў час выхаду"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Скіньце звесткі пра дзеянні падчас сеанса зараз. Вы таксама можаце захаваць ці выдаліць іх у час выхаду."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Зрабіць фота"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбраць відарыс"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Выбраць фота"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Пры пераключэнні на праграму \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" ці змяненні вываду бягучая трансляцыя спыняецца"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Трансляцыя праграмы \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Змяненне вываду"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 4375eb653884..5cbc02226183 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -603,7 +603,7 @@ <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Изход от режима на гост?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Така ще изтриете приложенията и данните от текущата сесия като гост"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Изход"</string> - <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Активност като гост – запазване?"</string> + <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Запазване на активността като гост?"</string> <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Можете да запазите активността от сесията или да изтриете всички прил. и данни"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Изтриване"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Запазване"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ако предавате <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените изхода, текущото ви предаване ще бъде прекратено"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Предаване на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Промяна на изхода"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index f3f5b3d23dc1..6585bc14b9d5 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -603,7 +603,7 @@ <string name="guest_exit_dialog_title" msgid="1846494656849381804">"\'অতিথি মোড\' ছেড়ে বেরিয়ে আসবেন?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"এটি বর্তমান অতিথি সেশন থেকে অ্যাপ ও ডেটা মুছে দেবে"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"বেরিয়ে আসুন"</string> - <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"অতিথি অ্যাক্টিভিটি সেভ করবেন?"</string> + <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"অতিথি মোডের অ্যাক্টিভিটি সেভ করবেন?"</string> <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"আপনি বর্তমান সেশন থেকে অ্যাক্টিভিটি সেভ করতে বা সব অ্যাপ ও ডেটা মুছতে পারবেন"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"মুছুন"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"সেভ করুন"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"আপনি <xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করলে বা আউটপুট পরিবর্তন করলে, আপনার বর্তমান সম্প্রচার বন্ধ হয়ে যাবে"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করুন"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"আউটপুট পরিবর্তন করুন"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"ফিরে যাওয়ার পূর্বাভাস সংক্রান্ত অ্যানিমেশন"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"ফিরে যাওয়া সংক্রান্ত পূর্বাভাসের জন্য সিস্টেম অ্যানিমেশন চালু করুন।"</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"জেসচারের পূর্বাভাস সংক্রান্ত অ্যানিমেশন দেখাতে এই সেটিং সিস্টেম অ্যানিমেশন চালু করে। এই সেটিংয়ে \'ম্যানিফেস্ট\' ফাইলে প্রত্যেক অ্যাপে enableOnBackInvokedCallback অ্যাট্রিবিউটকে \'ট্রু\' (true) হিসেবে সেট করতে হয়।"</string> </resources> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index dc74450d5ecb..b020a9b9c18e 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -604,15 +604,15 @@ <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ovim ćete izbrisati aplikacije i podatke iz trenutne sesije gosta"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Napusti"</string> <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Sačuvati aktivnost gosta?"</string> - <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Možete sačuvati aktivnost iz sesije ili izbrisati sve aplikacije i podatke"</string> + <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Možete sačuvati aktivnost iz ove sesije ili izbrisati sve aplikacije i podatke"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Izbriši"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Sačuvaj"</string> <string name="guest_exit_button" msgid="5774985819191803960">"Napusti način rada za gosta"</string> <string name="guest_reset_button" msgid="2515069346223503479">"Poništi sesiju gosta"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Izlazak iz sesije gosta"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sva aktivnost će biti izbrisana kada napustite sesiju"</string> - <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete sačuvati ili izbrisati svoju aktivnost pri napuštanju"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Poništite da sada izbrišete aktivnost iz sesije ili možete sačuvati ili izbrisati aktivnost pri napuštanju"</string> + <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete sačuvati ili izbrisati svoju aktivnost pri izlasku"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Poništite da odmah izbrišete aktivnost iz sesije ili je možete sačuvati ili izbrisati pri izlasku"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Snimite fotografiju"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberite sliku"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir fotografije"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, trenutno emitiranje će se zaustaviti"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitiraj aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Promijeni izlaz"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije za pokret povratka s predviđanjem"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogući animacije sustava za pokret povratka s predviđanjem."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ova postavka omogućuje animacije sustava za animaciju pokreta s predviđanjem. Zahtijeva postavljanje dopuštenja enableOnBackInvokedCallback po aplikaciji na True u datoteci manifesta."</string> </resources> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 8ec8f0fc8032..43aa18503dc9 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Surt del mode de convidat"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Se suprimirà tota l\'activitat en sortir"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Pots desar o suprimir l\'activitat en sortir"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restableix per suprimir l\'activitat de la sessió ara. També pots desar o suprimir l\'activitat en sortir."</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restableix la sessió per suprimir l\'activitat ara, o desa o suprimeix l\'activitat en sortir."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Fes una foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Tria una imatge"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Selecciona una foto"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si emets <xliff:g id="SWITCHAPP">%1$s</xliff:g> o canvies la sortida, l\'emissió actual s\'aturarà"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emet <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Canvia la sortida"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 7766777c6092..e49a8a604cae 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Pokud budete vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g> nebo změníte výstup, aktuální vysílání se zastaví"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Změna výstupu"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 0ef99e9151fb..2a99ac0e6ae1 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Afslut gæstesession"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Al aktivitet slettes ved afslutning"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Du kan gemme eller slette din aktivitet ved afslutning"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Nulstil for at slette sessionsaktiviteten nu, eller du kan gemme eller slette aktivitet ved afslutning"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Nulstil for at slette sessionsaktiviteten nu, eller gem eller slet aktivitet ved afslutning"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Tag et billede"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Vælg et billede"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Vælg billede"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Hvis du udsender <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller skifter output, stopper din aktuelle udsendelse"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Udsend <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Skift output"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Foreslåede animationer for Tilbage"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktivér systemanimationer for foreslåede animationer for Tilbage."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Denne indstilling aktiverer systemanimationer for de foreslåede animationer for bevægelsen Tilbage. Dette forudsætter konfiguration af enableOnBackInvokedCallback som sand for hver app i manifestfilen."</string> </resources> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index c94218fec760..c72fd59b5548 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Wenn du <xliff:g id="SWITCHAPP">%1$s</xliff:g> streamst oder die Ausgabe änderst, wird dein aktueller Stream beendet"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> streamen"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Ausgabe ändern"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index f94d43a89934..d13f533513cc 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -600,19 +600,19 @@ <string name="guest_resetting" msgid="7822120170191509566">"Επαναφορά επισκέπτη…"</string> <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Επαναφορά περιόδου σύνδεσης επισκέπτη;"</string> <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Με αυτόν τον τρόπο θα ξεκινήσει μια νέα περίοδος σύνδεσης επισκέπτη και θα διαγραφούν όλες οι εφαρμογές και τα δεδομένα από την τρέχουσα περίοδο σύνδεσης"</string> - <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Έξοδος από λειτουργία επισκέπτη;"</string> + <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Έξοδος από λειτ. επισκέπτη;"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Θα διαγραφούν εφαρμογές και δεδομένα από την τρέχουσα περίοδο σύνδεσης επισκέπτη"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Έξοδος"</string> <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Αποθήκευση δραστ. επισκέπτη;"</string> <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Αποθήκευση δραστ. τρέχουσας περιόδου σύνδεσης ή διαγραφή εφαρμογών και δεδομένων"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Διαγραφή"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Αποθήκευση"</string> - <string name="guest_exit_button" msgid="5774985819191803960">"Έξοδος από λειτουργία επισκέπτη"</string> + <string name="guest_exit_button" msgid="5774985819191803960">"Έξοδος από λειτ. επισκέπτη"</string> <string name="guest_reset_button" msgid="2515069346223503479">"Επαναφορά περ. σύνδεσης επισκέπτη"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Έξοδος επισκέπτη"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Όλη η δραστηριότητα θα διαγραφεί κατά την έξοδο"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Αποθηκεύστε ή διαγράψτε τη δραστηριότητά σας κατά την έξοδο"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Κάντε επαναφορά για να διαγράψετε τη δραστηριότητα της περιόδου σύνδεσης τώρα ή μπορείτε να αποθηκεύσετε ή να διαγράψετε τη δραστηριότητα κατά την έξοδο"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Επαναφορά για διαγραφή της δραστηριότητας της περιόδου σύνδεσης ή αποθήκευση ή διαγραφή κατά την έξοδο."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Λήψη φωτογραφίας"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Επιλογή εικόνας"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Επιλογή φωτογραφίας"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Εάν κάνετε μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g> ή αλλάξετε την έξοδο, η τρέχουσα μετάδοση θα σταματήσει"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Αλλαγή εξόδου"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 158d6fd76c88..9c4b3329a6b8 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string> </resources> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 1a3f5464b726..ceefae040e86 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string> </resources> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 158d6fd76c88..9c4b3329a6b8 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string> </resources> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 158d6fd76c88..9c4b3329a6b8 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string> </resources> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index df280cdbbf8a..18d0d0c1aedd 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string> </resources> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index afdfa9242627..846e6658349c 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Salir del modo de invitado"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Cuando salgas, se borrará toda la actividad"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puedes guardar o borrar la actividad cuando salgas"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para borrar la actividad ahora, o bien guarda y borra la actividad cuando salgas"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para eliminar la actividad ahora; o guarda o borra la actividad cuando salgas"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Tomar una foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Elegir una imagen"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si transmites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu transmisión actual se detendrá"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Cambia la salida"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index ba723ac68c18..9aa6f382b724 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -570,7 +570,7 @@ <string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restringido"</string> <string name="user_add_user_title" msgid="5457079143694924885">"¿Añadir nuevo usuario?"</string> <string name="user_add_user_message_long" msgid="1527434966294733380">"Puedes compartir este dispositivo si creas más usuarios. Cada uno tendrá su propio espacio y podrá personalizarlo con aplicaciones, un fondo de pantalla y mucho más. Los usuarios también pueden ajustar opciones del dispositivo, como la conexión Wi‑Fi, que afectan a todos los usuarios.\n\nCuando añadas un usuario, tendrá que configurar su espacio.\n\nCualquier usuario puede actualizar aplicaciones de todos los usuarios. Es posible que no se transfieran los servicios y opciones de accesibilidad al nuevo usuario."</string> - <string name="user_add_user_message_short" msgid="3295959985795716166">"Al añadir un usuario nuevo, debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string> + <string name="user_add_user_message_short" msgid="3295959985795716166">"Al añadir un nuevo usuario, dicha persona debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"¿Configurar usuario ahora?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"Asegúrate de que la persona está disponible en este momento para usar el dispositivo y configurar su espacio."</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"¿Quieres configurar un perfil ahora?"</string> @@ -600,19 +600,19 @@ <string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string> <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"¿Restablecer sesión de invitado?"</string> <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Se iniciará una nueva sesión de invitado y se borrarán todas las aplicaciones y datos de esta sesión"</string> - <string name="guest_exit_dialog_title" msgid="1846494656849381804">"¿Salir del modo Invitados?"</string> - <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Se eliminarán todas las aplicaciones y datos de la sesión de invitado"</string> + <string name="guest_exit_dialog_title" msgid="1846494656849381804">"¿Salir del modo Invitado?"</string> + <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Se eliminarán todas las aplicaciones y datos de la sesión de invitado actual"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Salir"</string> - <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"¿Guardar actividad de invitados?"</string> - <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puedes guardar la actividad de esta sesión o eliminar las aplicaciones y datos"</string> + <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"¿Guardar actividad de invitado?"</string> + <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puedes guardar la actividad de esta sesión o eliminar todas las aplicaciones y datos"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Eliminar"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Guardar"</string> - <string name="guest_exit_button" msgid="5774985819191803960">"Salir del modo Invitados"</string> + <string name="guest_exit_button" msgid="5774985819191803960">"Salir del modo Invitado"</string> <string name="guest_reset_button" msgid="2515069346223503479">"Restablecer sesión de invitado"</string> - <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Salir del modo Invitados"</string> + <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Salir del modo Invitado"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toda la actividad se eliminará cuando salgas"</string> - <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puedes guardar o eliminar tu actividad cuando salgas"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para eliminar la actividad ahora, o guarda o elimina la actividad cuando salgas"</string> + <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puedes guardar o eliminar tu actividad al salir"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para eliminar la actividad ahora, o guarda o borra la actividad al salir"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Hacer foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Seleccionar una imagen"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si emites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu emisión actual se detendrá"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Cambiar salida"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index a42fc4d5f6c8..582fdb37a99d 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -599,7 +599,7 @@ <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Eemalda"</string> <string name="guest_resetting" msgid="7822120170191509566">"Külastajaseansi lähtestamine …"</string> <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Kas lähtestada külastajaseanss?"</string> - <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"See alustab uut külastajaseanssi ning kustutab kõik praeguse seansi rakendused ja andmed"</string> + <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"See alustab uut külastajaseanssi ning kustutab kõik praeguse seansi rakendused ja andmed."</string> <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Kas väljuda külalisrežiimist?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"See kustutab praeguse külastajaseansi rakendused ja andmed"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Välju"</string> @@ -611,8 +611,8 @@ <string name="guest_reset_button" msgid="2515069346223503479">"Lähtesta külastajaseanss"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Välju külastajaseansist"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Kõik tegevused kustutatakse väljumisel"</string> - <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Võite tegevused salvestada või kustutada väljumisel"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Lähtestage, et seansi tegevused kohe kustutada; samuti võite tegevused salvestada või kustutada väljumisel"</string> + <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Võite tegevused salvestada või kustutada väljumisel."</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Seansi tegevuste kohe kustutamiseks lähtestage; või salvestage või kustutage need väljumisel."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Pildistage"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Valige pilt"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Valige foto"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Kui kannate rakendust <xliff:g id="SWITCHAPP">%1$s</xliff:g> üle või muudate väljundit, peatatakse teie praegune ülekanne"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Rakenduse <xliff:g id="SWITCHAPP">%1$s</xliff:g> ülekandmine"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Väljundi muutmine"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 759714767361..e0b7ad5690fd 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -446,7 +446,7 @@ <string name="daltonizer_mode_monochromacy" msgid="362060873835885014">"Ikusmen-monokromia"</string> <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Daltonismoa (gorri-berdeak)"</string> <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanopia (gorri-berdeak)"</string> - <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanopia (urdin-horia)"</string> + <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalia (urdin-horia)"</string> <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Koloreen zuzenketa"</string> <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Baliteke koloreen zuzenketa lagungarria izatea hauek egin nahi dituzunean:<br/> <ol> <li>&nbsp;Koloreak zehaztasun handiagoz ikusi.</li> <li>&nbsp;Koloreak kendu, arreta gal ez dezazun.</li> </ol>"</string> <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string> @@ -569,7 +569,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"Erabiltzailea"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"Profil murriztua"</string> <string name="user_add_user_title" msgid="5457079143694924885">"Beste erabiltzaile bat gehitu nahi duzu?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"Gailu hau beste pertsona batzuekin partekatzeko, sortu erabiltzaile gehiago. Erabiltzaile bakoitzak bere eremua izango du eta, bertan, aplikazioak, horma-papera eta antzekoak pertsonalizatu ahal izango ditu. Horrez gain, erabiltzaile guztiei eragin diezaieketen ezarpen batzuk ere doi daitezke; adibidez, wifi-konexioarena.\n\nErabiltzaile bat gehitzen duzunean, pertsona horrek berak konfiguratu beharko du bere eremua.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak. Baliteke erabilerraztasun-ezarpenak eta -zerbitzuak ez transferitzea erabiltzaile berriei."</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"Gailu hau beste pertsona batzuekin partekatzeko, sortu erabiltzaile gehiago. Erabiltzaile bakoitzak bere eremua izango du eta, bertan, aplikazioak, horma-papera eta antzekoak pertsonalizatu ahal izango ditu. Horrez gain, agian erabiltzaile guztiei eragingo dieten ezarpen batzuk ere doi daitezke; adibidez, wifi-konexioarena.\n\nErabiltzaile bat gehitzen duzunean, pertsona horrek berak konfiguratu beharko du bere eremua.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak. Baliteke erabilerraztasun-ezarpenak eta -zerbitzuak ez transferitzea erabiltzaile berriei."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"Erabiltzaile bat gehitzen duzunean, erabiltzaile horrek bere eremua konfiguratu beharko du.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"Erabiltzailea konfiguratu?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"Ziurtatu pertsona horrek gailua hartu eta bere eremua konfigura dezakeela"</string> @@ -610,9 +610,9 @@ <string name="guest_exit_button" msgid="5774985819191803960">"Irten gonbidatu modutik"</string> <string name="guest_reset_button" msgid="2515069346223503479">"Berrezarri gonbidatuentzako saioa"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Irten gonbidatu modutik"</string> - <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Saiotik irtetean, jarduera guztiak ezabatuko dira"</string> + <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Irtetean, jarduera guztiak ezabatuko dira"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Irtetean, jarduerak gorde edo ezabatu egin ditzakezu"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Berrezarri saioa jarduerak ezabatzeko (bestela, jarduerak gordetzea edo ezabatzea aukera dezakezu irtetean)"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Berrezarri saioa jarduerak ezabatzeko; bestela, aukeratu jarduerak irtetean gordetzea edo ezabatzea"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Atera argazki bat"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Aukeratu irudi bat"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Hautatu argazki bat"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa igortzen baduzu, edo audio-irteera aldatzen baduzu, une hartako igorpena eten egingo da"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Igorri <xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Aldatu audio-irteera"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 15a8f3e1800c..8e732779da0c 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"اگر <xliff:g id="SWITCHAPP">%1$s</xliff:g> را همهفرستی کنید یا خروجی را تغییر دهید، همهفرستی کنونی متوقف خواهد شد"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"همهفرستی <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"تغییر خروجی"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index e14cf873faa9..89c7ed38c6e0 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Jos lähetät <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta tai muutat ulostuloa, nykyinen lähetyksesi loppuu"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Lähetä <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Muuta ulostuloa"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index 565439a0f851..6a005dbf7675 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou changez la sortie, votre diffusion actuelle s\'arrêtera"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Changer la sortie"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 15df12c31913..47eafc32352f 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Quitter le mode Invité"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toute l\'activité sera supprimée une fois la session quittée"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Vous pouvez enregistrer ou supprimer l\'activité en quittant"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Réinitialisez la session pour supprimer immédiatement l\'activité, qui pourra aussi être enregistrée ou supprimée lorsque vous quitterez la session"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Réinitialisez la session pour supprimer immédiatement l\'activité. Vous pourrez aussi l\'enregistrer ou la supprimer en quittant la session."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Choisir une image"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionner une photo"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou que vous modifiez le résultat, votre annonce actuelle s\'arrêtera"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Modifier le résultat"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index cd002d5f8d7a..78c9b53fb8fa 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -619,7 +619,7 @@ <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Realizaches demasiados intentos incorrectos. Eliminaranse os datos deste dispositivo."</string> <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Realizaches demasiados intentos incorrectos. Eliminarase este usuario."</string> <string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Realizaches demasiados intentos incorrectos. Eliminaranse este perfil de traballo e os datos asociados."</string> - <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Ignorar"</string> + <string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Pechar"</string> <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Funcionamento predeterminado"</string> <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desactivado"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activado"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Se emites contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou cambias de saída, a emisión en curso deterase"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitir contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Cambiar de saída"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index be103548e37e..1cc4bfa255e9 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"જો તમે <xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો અથવા આઉટપુટ બદલો, તો તમારું હાલનું બ્રોડકાસ્ટ બંધ થઈ જશે"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"આઉટપુટ બદલો"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"પાછળના પૂર્વાનુમાનિત ઍનિમેશન્સ"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"પાછળના પૂર્વાનુમાનિત સંકેત માટે સિસ્ટમ ઍનિમેશન ચાલુ કરો."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"આ સેટિંગ પૂર્વાનુમાનિત સંકેત ઍનિમેશન માટે સિસ્ટમ ઍનિમેશન ચાલુ કરે છે. તેના માટે દરેક ઍપ માટે મેનિફેસ્ટ ફાઇલમાં enableOnBackInvokedCallbackને true પર સેટ કરવાની જરૂર પડે છે."</string> </resources> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 812ac7416ced..5de0d420177a 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट शुरू करने पर या आउटपुट बदलने पर, आपका मौजूदा ब्रॉडकास्ट बंद हो जाएगा"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट करें"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"आउटपुट बदलें"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"प्रिडिक्टिव बैक ऐनिमेशन"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"प्रिडिक्टिव बैक के लिए सिस्टम ऐनिमेशन चालू करें."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"यह सेटिंग, सिस्टम के ऐनिमेशन को प्रिडिक्टिव जेस्चर ऐनिमेशन के लिए चालू कर देती है. मेनिफ़ेस्ट फ़ाइल में enableOnBackInvokedCallback की सेटिंग को हर ऐप्लिकेशन के हिसाब से \'सही\' पर सेट होना चाहिए."</string> </resources> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index a1722d7878ee..fcf832864602 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -583,7 +583,7 @@ <string name="profile_info_settings_title" msgid="105699672534365099">"Profilni podaci"</string> <string name="user_need_lock_message" msgid="4311424336209509301">"Prije izrade ograničenog profila trebate postaviti zaključavanje zaslona radi zaštite svojih aplikacija i osobnih podataka."</string> <string name="user_set_lock_button" msgid="1427128184982594856">"Postavi zaključavanje"</string> - <string name="user_switch_to_user" msgid="6975428297154968543">"Prelazak na korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string> + <string name="user_switch_to_user" msgid="6975428297154968543">"Prijeđi na korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string> <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Izrada novog korisnika…"</string> <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Izrada novog gosta…"</string> <string name="add_user_failed" msgid="4809887794313944872">"Izrada novog korisnika nije uspjela"</string> @@ -591,7 +591,7 @@ <string name="user_nickname" msgid="262624187455825083">"Nadimak"</string> <string name="user_add_user" msgid="7876449291500212468">"Dodavanje korisnika"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Dodavanje gosta"</string> - <string name="guest_exit_guest" msgid="5908239569510734136">"Uklanjanje gosta"</string> + <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Poništi gostujuću sesiju"</string> <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Poništiti gostujuću sesiju?"</string> <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Želite li ukloniti gosta?"</string> @@ -611,8 +611,8 @@ <string name="guest_reset_button" msgid="2515069346223503479">"Poništi gostujuću sesiju"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Izlaz iz gostujuće sesije"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sve će se aktivnosti izbrisati na izlasku"</string> - <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete spremiti ili izbrisati svoje aktivnosti na izlasku"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Poništite da biste odmah izbrisali aktivnost sesije, a možete i spremiti ili izbrisati aktivnost na izlasku."</string> + <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Svoje aktivnosti možete spremiti ili izbrisati na izlasku."</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Poništite da odmah izbrišete aktivnost sesije. Inače je možete spremiti ili izbrisati na izlasku."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiraj"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir slike"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, vaše će se trenutačno emitiranje zaustaviti"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitiranje aplikacije <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Promjena izlaza"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije za pokret povratka s predviđanjem"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogući animacije sustava za pokret povratka s predviđanjem."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ova postavka omogućuje animacije sustava za animaciju pokreta s predviđanjem. Zahtijeva postavljanje dopuštenja enableOnBackInvokedCallback po aplikaciji na True u datoteci manifesta."</string> </resources> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index fe6bc88cded3..63d075335ab7 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Vendég kiléptetése"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"A kilépéssel minden tevékenység törlődik"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"A kilépéskor mentheti vagy törölheti a tevékenységeket"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Visszaállítással azonnal törölheti a munkamenethez tartozó tevékenységeket, illetve kilépéskor mentheti vagy törölheti a tevékenységeket"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Visszaállítással azonnal törölheti, illetve kilépéskor mentheti vagy törölheti a tevékenységeket"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Fotó készítése"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Kép kiválasztása"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Fotó kiválasztása"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"A(z) <xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése vagy a kimenet módosítása esetén a jelenlegi közvetítés leáll"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Kimenet módosítása"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 9b4b21719068..a364cf182e05 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -593,12 +593,12 @@ <string name="guest_new_guest" msgid="3482026122932643557">"Ավելացնել հյուր"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Հեռացնել հյուրին"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Վերակայել հյուրի աշխատաշրջանը"</string> - <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Վերակայե՞լ հյուրի աշխատաշրջանը"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Զրոյացնե՞լ հյուրի աշխատաշրջանը"</string> <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Հեռացնե՞լ հյուրին"</string> <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Զրոյացնել"</string> <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Հեռացնել"</string> <string name="guest_resetting" msgid="7822120170191509566">"Հյուրի աշխատաշրջանը վերակայվում է…"</string> - <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Վերակայե՞լ հյուրի աշխատաշրջանը"</string> + <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Զրոյացնե՞լ հյուրի աշխատաշրջանը"</string> <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Կսկսվի հյուրի նոր աշխատաշրջան, իսկ նախորդ աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն"</string> <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Դուրս գա՞լ հյուրի ռեժիմից"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Հյուրի ընթացիկ աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Եթե հեռարձակեք <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը կամ փոխեք աուդիո ելքը, ձեր ընթացիկ հեռարձակումը կկանգնեցվի։"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Հեռարձակել <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Փոխել աուդիո ելքը"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 96e129a862fb..01bd7fe29b85 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Keluar dari mode tamu"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Semua aktivitas akan dihapus saat Anda keluar"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Anda dapat menyimpan atau menghapus aktivitas saat keluar"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset untuk menghapus aktivitas sesi sekarang, atau Anda dapat menyimpan atau menghapus aktivitas saat keluar"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset untuk hapus aktivitas sesi sekarang, atau simpan atau hapus aktivitas saat keluar"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih gambar"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Jika Anda menyiarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau mengubah output, siaran saat ini akan dihentikan"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Ubah output"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 3a1ab7fef74a..5dc4d04dfc01 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Loka gestastillingu"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Öllum aðgerðum verður eytt þegar lotu er lokað"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Þú getur vistað eða eytt aðgerðum þegar þú lokar"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Endurstilltu til að eyða aðgerðum lotu núna, eða þú getur vistað eða eytt aðgerðum þegar þú lokar"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Endurstilltu til að eyða aðgerðum lotu núna, eða vistaðu eða eyddu aðgerðum þegar þú lokar"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Taka mynd"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Velja mynd"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Velja mynd"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ef þú sendir út <xliff:g id="SWITCHAPP">%1$s</xliff:g> eða skiptir um úttak lýkur yfirstandandi útsendingu"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Senda út <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Skipta um úttak"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index e312fa7bae78..57c75d9788ea 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -604,7 +604,7 @@ <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Verranno eliminati i dati e le app della sessione Ospite corrente"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Esci"</string> <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vuoi salvare l\'attività Ospite?"</string> - <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puoi salvare l\'attività della sessione corrente o eliminare tutti i dati e app"</string> + <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puoi salvare l\'attività della sessione corrente o eliminare tutti i dati e le app"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Elimina"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Salva"</string> <string name="guest_exit_button" msgid="5774985819191803960">"Esci dalla modalità Ospite"</string> @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Esci dalla modalità Ospite"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Quando esci verrà eliminata tutta l\'attività"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Quando esci puoi salvare o eliminare la tua attività"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reimposta per eliminare subito l\'attività della sessione oppure puoi salvare o eliminare l\'attività quando esci"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reimposta la sessione per eliminare subito l\'attività, oppure salvala o eliminala quando esci"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Scatta una foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Scegli un\'immagine"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Seleziona la foto"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Se trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambi l\'uscita, la trasmissione attuale viene interrotta"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Cambia uscita"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index fc70209f7d94..72ba41b0df72 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"אם משדרים את התוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g> או משנים את הפלט, השידור הנוכחי יפסיק לפעול"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"שידור תוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"שינוי הפלט"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 6f0759d5ab1a..6622d2b6c87a 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -569,8 +569,8 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"ユーザー"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"制限付きプロファイル"</string> <string name="user_add_user_title" msgid="5457079143694924885">"新しいユーザーを追加しますか?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"追加ユーザーを作成して、このデバイスを他のユーザーと共有できます。各ユーザーは各自のスペースを所有して、アプリや壁紙などのカスタマイズを行うことができます。Wi-Fi など、すべてのユーザーに影響するデバイス設定を変更することもできます。\n\n新しく追加したユーザーは各自でスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。ユーザー補助機能の設定とサービスは新しいユーザーに適用されないことがあります。"</string> - <string name="user_add_user_message_short" msgid="3295959985795716166">"新しく追加したユーザーは各自でスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。"</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"追加ユーザーを作成して、このデバイスを他のユーザーと共有できます。各ユーザーは各自のスペースを所有して、アプリや壁紙などのカスタマイズを行うことができます。Wi-Fi など、すべてのユーザーに影響するデバイス設定を変更することもできます。\n\n新しく追加したユーザーは各自でスペースをセットアップする必要があります。\n\nすべてのユーザーがアプリを更新でき、その影響は他のユーザーにも及びます。ユーザー補助機能の設定とサービスは新しいユーザーに適用されないことがあります。"</string> + <string name="user_add_user_message_short" msgid="3295959985795716166">"新しく追加したユーザーは各自でスペースをセットアップする必要があります。\n\nすべてのユーザーがアプリを更新でき、その影響は他のユーザーにも及びます。"</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"ユーザーを今すぐセットアップ"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"ユーザーがデバイスを使って各自のスペースをセットアップできるようにします"</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"プロファイルを今すぐセットアップしますか?"</string> @@ -603,7 +603,7 @@ <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ゲストモードを終了しますか?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"現在のゲスト セッションからすべてのアプリとデータが削除されます"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"終了"</string> - <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ゲストのアクティビティを保存しますか?"</string> + <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ゲストアクティビティの保存"</string> <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"現在のセッションのアクティビティの保存や、すべてのアプリとデータの削除を行えます"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"削除"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"保存"</string> @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ゲストを終了"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"終了時にすべてのアクティビティが削除されます"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"終了時にアクティビティを保存、削除できます"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"リセットして今すぐセッションのアクティビティを削除します(終了時にアクティビティを保存、削除することもできます)"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"アクティビティは、リセットして今すぐ削除するか、終了時に保存または削除できます"</string> <string name="user_image_take_photo" msgid="467512954561638530">"写真を撮る"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"画像を選択"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"写真を選択"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャストしたり、出力を変更したりすると、現在のブロードキャストが停止します。"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャスト"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"出力を変更"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index 525a0d235fd2..736a05935798 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"სტუმრის გასვლა"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"გასვლისას ყველა აქტივობა წაიშლება"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"გასვლისას შეგიძლიათ შეინახოთ ან წაშალოთ თქვენი აქტივობა"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"გადააყენეთ სესიის აქტივობის ახლავე წასაშლელად, ასევე, შეინახეთ ან წაშალეთ აქტივობა გასვლისას"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"გადააყენეთ სესიის აქტივობის ახლა წასაშლელად. შენახვა/წაშლა გასვლისასაც შეიძლება."</string> <string name="user_image_take_photo" msgid="467512954561638530">"ფოტოს გადაღება"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"აირჩიეთ სურათი"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ფოტოს არჩევა"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაციის შემთხვევაში ან აუდიოს გამოსასვლელის შეცვლისას, მიმდინარე ტრანსლაცია შეჩერდება"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაცია"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"აუდიოს გამოსასვლელის შეცვლა"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"უკან დაბრუნების ანიმაციის პროგნოზირება"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"უკან დაბრუნების პროგნოზირებადი ანიმაციისთვის სისტემის ანიმაციების ჩართვა."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ეს პარამეტრი ჩართავს სისტემის ანიმაციებს ჟესტების პროგნოზირებადი ანიმაციებისთვის. საჭიროა, რომ აღწერის ფაილში აპის enableOnBackInvokedCallback პარამეტრი იყოს ჭეშმარიტი."</string> </resources> diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml index a831df14bc7d..33fd25bbdaf6 100644 --- a/packages/SettingsLib/res/values-kk/arrays.xml +++ b/packages/SettingsLib/res/values-kk/arrays.xml @@ -54,9 +54,9 @@ <item msgid="9048424957228926377">"Әрқашан тексеру"</item> </string-array> <string-array name="hdcp_checking_summaries"> - <item msgid="4045840870658484038">"Ешқашан HDCP (жоғары кең жолақты сандық мазмұн қорғаушы) тексерулерін қолданбаңыз"</item> + <item msgid="4045840870658484038">"Ешқашан HDCP (жоғары кең жолақты цифрлық мазмұн қорғаушы) тексерулерін қолданбаңыз"</item> <item msgid="8254225038262324761">"HDCP тексерісін DRM мазмұны үшін ғана қолдану"</item> - <item msgid="6421717003037072581">"Әрқашан HDCP (жоғары кең жолақты сандық мазмұн қорғаушы) тексерулерін қолданыңыз"</item> + <item msgid="6421717003037072581">"Әрқашан HDCP (жоғары кең жолақты цифрлық мазмұн қорғаушы) тексерулерін қолданыңыз"</item> </string-array> <string-array name="bt_hci_snoop_log_entries"> <item msgid="695678520785580527">"Өшірулі"</item> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 2f5389416787..93497f4049ef 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -344,7 +344,7 @@ <string name="enable_terminal_title" msgid="3834790541986303654">"Жергілікті терминал"</string> <string name="enable_terminal_summary" msgid="2481074834856064500">"Жергілікті шелл-код қол жетімділігін ұсынатын терминалды қолданбаны қосу"</string> <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP тексерісі"</string> - <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP (кең жолақты сандық мазмұн қорғау) тексеру мүмкіндігін орнату"</string> + <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP (кең жолақты цифрлық мазмұн қорғау) тексеру мүмкіндігін орнату"</string> <string name="debug_debugging_category" msgid="535341063709248842">"Түзету"</string> <string name="debug_app" msgid="8903350241392391766">"Түзету қолданбасын таңдау"</string> <string name="debug_app_not_set" msgid="1934083001283807188">"Түзету қолданбалары орнатылмаған."</string> @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Қонақ режимінен шығу"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Шыққанда барлық әрекет жойылады."</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Шыққанда барлық әрекетті сақтай немесе жоя аласыз."</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сеанс әрекетін қазір жою үшін оны бастапқы күйге қайтарыңыз. Әрекетті сақтау немесе жою шешімін шыққан кезде қабылдай аласыз."</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сеанс дерегін жою үшін оны бастапқы күйге қайтарыңыз. Деректі шығар кезде де сақтауға не жоюға болады."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Фотосуретке түсіру"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Сурет таңдау"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Фотосурет таңдау"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын таратсаңыз немесе аудио шығысын өзгертсеңіз, қазіргі тарату сеансы тоқтайды."</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын тарату"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Аудио шығысын өзгерту"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 4f36f697dbca..2995c21b76b7 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"ប្រសិនបើអ្នកផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ឬប្ដូរឧបករណ៍បញ្ចេញសំឡេង ការផ្សាយបច្ចុប្បន្នរបស់អ្នកនឹងបញ្ឈប់"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"ការផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"ប្ដូរឧបករណ៍បញ្ចេញសំឡេង"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 9e7a9a30e2b9..2be4960b1847 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"ನೀವು <xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿದರೆ ಅಥವಾ ಔಟ್ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿದರೆ, ನಿಮ್ಮ ಪ್ರಸ್ತುತ ಪ್ರಸಾರವು ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತದೆ"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿ"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"ಔಟ್ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿ"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"ಮುನ್ನೋಟದ ಬ್ಯಾಕ್ ಆ್ಯನಿಮೇಶನ್ಗಳು"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"ಮುನ್ನೋಟದ ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್ಗಾಗಿ ಸಿಸ್ಟಂ ಆ್ಯನಿಮೇಶನ್ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ಮುನ್ನೋಟದ ಗೆಸ್ಚರ್ ಆ್ಯನಿಮೇಶನ್ಗಾಗಿ ಸಿಸ್ಟಂ ಆ್ಯನಿಮೇಶನ್ಗಳನ್ನು ಈ ಸೆಟ್ಟಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸುತ್ತವೆ. ಇದನ್ನು ಮಾಡಲು, ಪ್ರತಿ ಆ್ಯಪ್ನ ಮ್ಯಾನಿಫೆಸ್ಟ್ ಫೈಲ್ನಲ್ಲಿರುವ enableOnBackInvokedCallback ಪ್ಯಾರಾಮೀಟರ್ ಅನ್ನು ಸರಿ ಎಂದು ಹೊಂದಿಸಬೇಕು."</string> </resources> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 69cb714d1ebc..7f0ee76b48c9 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -599,9 +599,9 @@ <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"삭제"</string> <string name="guest_resetting" msgid="7822120170191509566">"게스트 재설정 중…"</string> <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"게스트 세션을 재설정하시겠습니까?"</string> - <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"이렇게 하면 새로운 게스트 세션이 시작되고 기존 세션의 모든 앱과 데이터가 삭제됩니다."</string> + <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"새로운 게스트 세션이 시작되고 기존 세션의 모든 앱과 데이터가 삭제됩니다."</string> <string name="guest_exit_dialog_title" msgid="1846494656849381804">"게스트 모드를 종료하시겠습니까?"</string> - <string name="guest_exit_dialog_message" msgid="1743218864242719783">"기존 게스트 세션의 앱과 데이터가 삭제됩니다."</string> + <string name="guest_exit_dialog_message" msgid="1743218864242719783">"현재 게스트 세션의 앱과 데이터가 삭제됩니다."</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"종료"</string> <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"게스트 활동을 저장하시겠습니까?"</string> <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"기존 세션의 활동을 저장하거나 모든 앱과 데이터를 삭제할 수 있습니다."</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 앱을 방송하거나 출력을 변경하면 기존 방송이 중단됩니다"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 방송"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"출력 변경"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 341cdeb5a6fe..fbf4b6d086c8 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -569,7 +569,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"Колдонуучу"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"Чектелген профайл"</string> <string name="user_add_user_title" msgid="5457079143694924885">"Жаңы колдонуучу кошосузбу?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"Эгер түзмөгүңүздү дагы бир адам колдонуп жаткан болсо, кошумча профилдерди түзүп коюңуз. Профилдин ээси аны өзү каалагандай жөндөп, тушкагаздарды коюп, керектүү колдонмолорду орнотуп алат. Мындан тышкары, колдонуучулар түзмөктүн Wi‑Fi´ды өчүрүү/күйгүзүү сыяктуу жалпы жөндөөлөрүн өзгөртө алат.\n\nПрофиль түзүлгөндөн кийин, аны жөндөп алуу керек.\n\nЖалпы колдонмолорду баары жаңырта алат, бирок атайын мүмкүнчүлүктөр өз-өзүнчө жөндөлөт."</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"Эгер түзмөгүңүздү дагы бир адам колдонуп жаткан болсо, кошумча профилдерди түзүп коюңуз. Профилдин ээси аны өзү каалагандай тууралап, тушкагаздарды коюп, керектүү колдонмолорду орнотуп алат. Мындан тышкары, колдонуучулар түзмөктүн Wi‑Fi´ды өчүрүү/күйгүзүү сыяктуу жалпы параметрлерин өзгөртө алышат.\n\nПрофиль түзүлгөндөн кийин, аны тууралап алуу керек.\n\nЖалпы колдонмолорду баары жаңырта алат, бирок атайын мүмкүнчүлүктөр өз-өзүнчө жөндөлөт."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"Жаңы колдонуучу кошулганда, ал өз мейкиндигин түзүп алышы керек.\n\nКолдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"Профилди жөндөйсүзбү?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"Өз мейкиндигин жөндөп алышы үчүн, түзмөктү колдонуучуга беришиңиз керек."</string> @@ -598,12 +598,12 @@ <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Баштапкы абалга келтирүү"</string> <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Өчүрүү"</string> <string name="guest_resetting" msgid="7822120170191509566">"Конок сеансы баштапкы абалга келтирилүүдө…"</string> - <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Конок сеансы баштапкы абалга келтирилсинби?"</string> + <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Конок сеансын баштапкы абалга келтиресизби?"</string> <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Бул аракет жаңы конок сеансын баштап, учурдагы сеанстагы бардык колдонмолорду жана алардагы нерселерди жок кылат"</string> <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Конок режиминен чыгасызбы?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Бул учурдагы конок сеансындагы колдонмолорду жана алардагы нерселерди жок кылат"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Чыгуу"</string> - <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Коноктун аракеттери сакталсынбы?"</string> + <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Коноктун аракеттерин сактайсызбы?"</string> <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Учурдагы сеанстагы аракеттерди сактап же бардык колдонмолорду жана алардагы нерселерди жок кылсаңыз болот"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Өчүрүү"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Сактоо"</string> @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Конок режиминен чыгуу"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Чыксаңыз, бардык аракеттер өчүрүлөт"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Чыгуудан мурун аракеттериңизди сактап же жок кылсаңыз болот"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сеанстагы аракеттерди азыр жок кылуу үчүн баштапкы абалга келтириңиз, же болбосо чыгуу учурунда аракеттерди сактап же жок кылсаңыз болот"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сеанстагы аракеттерди азыр өчүрсөңүз болот же чыгып баратып өчүрүп же сактап коюңуз"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Сүрөткө тартуу"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Сүрөт тандаңыз"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Сүрөт тандаңыз"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Эгер <xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарласаңыз же аудионун чыгуусун өзгөртсөңүз, учурдагы кабарлоо токтотулат"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарлоо"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Аудионун чыгуусун өзгөртүү"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 5f42f5c0a3f1..fd6ba22ef372 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -598,7 +598,7 @@ <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ຣີເຊັດ"</string> <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ລຶບອອກ"</string> <string name="guest_resetting" msgid="7822120170191509566">"ກຳລັງຣີເຊັດແຂກ…"</string> - <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ຣີເຊັດໄລຍະເວລາຂອງແຂກບໍ?"</string> + <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ຣີເຊັດເຊດຊັນຂອງແຂກບໍ?"</string> <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ນີ້ຈະເລີ່ມໄລຍະເວລາຂອງແຂກໃໝ່ ແລະ ລຶບແອັບ ແລະ ຂໍ້ມູນທັງໝົດອອກຈາກເຊດຊັນປັດຈຸບັນ"</string> <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ອອກຈາກໂໝດແຂກບໍ?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ນີ້ຈະລຶບແອັບ ແລະ ຂໍ້ມູນອອກຈາກໄລຍະເວລາຂອງແຂກປັດຈຸບັນ"</string> @@ -608,7 +608,7 @@ <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ລຶບ"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"ບັນທຶກ"</string> <string name="guest_exit_button" msgid="5774985819191803960">"ອອກຈາກໂໝດແຂກ"</string> - <string name="guest_reset_button" msgid="2515069346223503479">"ຣີເຊັດໄລຍະເວລາຂອງແຂກ"</string> + <string name="guest_reset_button" msgid="2515069346223503479">"ຣີເຊັດເຊດຊັນຂອງແຂກ"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ອອກຈາກແຂກ"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ການເຄື່ອນໄຫວທັງໝົດຈະຖືກລຶບໃນຕອນອອກ"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ທ່ານສາມາດບັນທຶກ ຫຼື ລຶບການເຄື່ອນໄຫວຂອງທ່ານໃນຕອນອອກໄດ້"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"ຫາກທ່ານອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ຫຼື ປ່ຽນເອົ້າພຸດ, ການອອກອາກາດປັດຈຸບັນຂອງທ່ານຈະຢຸດ"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"ອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"ປ່ຽນເອົ້າພຸດ"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"ອະນິເມຊັນກັບຫຼັງແບບຄາດເດົາ"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"ເປີດການນຳໃຊ້ອະນິເມຊັນລະບົບສຳລັບການກັບຫຼັງແບບຄາດເດົາ."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ການຕັ້ງຄ່ານີ້ຈະເປີດການນຳໃຊ້ອະນິເມຊັນລະບົບສຳລັບອະນິເມຊັນທ່າທາງແບບຄາດເດົາ. ມັນຕ້ອງໃຊ້ການຕັ້ງຄ່າຕໍ່ແອັບ enableOnBackInvokedCallback ເປັນ true ໃນໄຟລ໌ manifest."</string> </resources> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index a161750e2098..f8475e1dfc07 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Jei transliuosite „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“ arba pakeisite išvestį, dabartinė transliacija bus sustabdyta"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Transliuoti „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Keisti išvestį"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index 929b857950ff..e024d30ded99 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ja sāksiet lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraidīšanu vai mainīsiet izvadi, pašreizējā apraide tiks apturēta"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraide"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Izvades maiņa"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 50ea0563fcde..d91792a56de8 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ако емитувате на <xliff:g id="SWITCHAPP">%1$s</xliff:g> или го промените излезот, тековното емитување ќе запре"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Емитување на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Променете излез"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Предвидливи анимации отпозади"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Овозможете предвидливи системски анимации отпозади."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Поставкава ги овозможува системските анимации за предвидливи движења. Поставката треба да се постави на „точно“ преку апликација enableOnBackInvokedCallback во датотеката за манифест."</string> </resources> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index a38daced13d2..f07b0669fd91 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -569,7 +569,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"ഉപയോക്താവ്"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"നിയന്ത്രിത പ്രൊഫൈൽ"</string> <string name="user_add_user_title" msgid="5457079143694924885">"പുതിയ ഉപയോക്താവിനെ ചേർക്കണോ?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"കൂടുതൽ ഉപയോക്താക്കളെ സൃഷ്ടിച്ചുകൊണ്ട് ഈ ഉപകരണം മറ്റുള്ളവരുമായി നിങ്ങൾക്ക് പങ്കിടാം. ആപ്പുകളും വാൾപേപ്പറുകളും മറ്റും ഉപയോഗിച്ച് ഇഷ്ടാനുസൃതമാക്കാൻ ഓരോ ഉപയോക്താവിനും സാധിക്കും. വൈഫൈ പോലെ എല്ലാവരെയും ബാധിക്കുന്ന ഉപകരണ ക്രമീകരണവും ഉപയോക്താക്കൾക്ക് ക്രമീകരിക്കാം.\n\nനിങ്ങളൊരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിക്ക് സ്വന്തമായ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\n എല്ലാ ഉപയോക്താക്കൾക്കുമായി ആപ്പുകൾ അപ്ഡേറ്റ് ചെയ്യാൻ ഏതൊരു ഉപയോക്താവിനുമാവും. ഉപയോഗസഹായി ക്രമീകരണവും സേവനങ്ങളും പുതിയ ഉപയോക്താവിന് കൈമാറുകയില്ല."</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"കൂടുതൽ ഉപയോക്താക്കളെ സൃഷ്ടിച്ചുകൊണ്ട് ഈ ഉപകരണം മറ്റുള്ളവരുമായി നിങ്ങൾക്ക് പങ്കിടാം. ആപ്പുകളും വാൾപേപ്പറുകളും മറ്റും ഉപയോഗിച്ച് ഇഷ്ടാനുസൃതമാക്കാൻ ഓരോ ഉപയോക്താവിനും സാധിക്കും. വൈഫൈ പോലെ എല്ലാവരെയും ബാധിക്കുന്ന ഉപകരണ ക്രമീകരണവും ഉപയോക്താക്കൾക്ക് അഡ്ജസ്റ്റ് ചെയ്യാം.\n\nനിങ്ങളൊരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തി സ്വന്തമായ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\n ഏതെങ്കിലും ഉപയോക്താവിന് എല്ലാ ഉപയോക്താക്കൾക്കുമായി ആപ്പുകൾ അപ്ഡേറ്റ് ചെയ്യാനാകും. ഉപയോഗസഹായി ക്രമീകരണവും സേവനങ്ങളും പുതിയ ഉപയോക്താവിന് കൈമാറുകയില്ല."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"നിങ്ങൾ ഒരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിയ്ക്ക് അവരുടെ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\nമറ്റ് എല്ലാ ഉപയോക്താക്കൾക്കുമായി ഏതൊരു ഉപയോക്താവിനും ആപ്പുകൾ അപ്ഡേറ്റ് ചെയ്യാനാവും."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"ഉപയോക്താവിനെ ഇപ്പോൾ സജ്ജീകരിക്കണോ?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"ഉപകരണം എടുത്ത് ഇടം സജ്ജീകരിക്കുന്നതിന് വ്യക്തി ലഭ്യമാണെന്ന് ഉറപ്പാക്കുക"</string> @@ -607,7 +607,7 @@ <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"നിലവിലെ സെഷനിൽ നിന്നുള്ള ആക്റ്റിവിറ്റി സംരക്ഷിക്കാം അല്ലെങ്കിൽ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കാം"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ഇല്ലാതാക്കുക"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"സംരക്ഷിക്കുക"</string> - <string name="guest_exit_button" msgid="5774985819191803960">"അതിഥി മോഡിൽ നിന്ന് പുറത്തുകടക്കുക"</string> + <string name="guest_exit_button" msgid="5774985819191803960">"പുറത്തുകടക്കുക"</string> <string name="guest_reset_button" msgid="2515069346223503479">"അതിഥി സെഷൻ റീസെറ്റ് ചെയ്യുക"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"അതിഥി മോഡിൽ നിന്ന് പുറത്തുകടക്കുക"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"പുറത്തുകടക്കുമ്പോൾ എല്ലാ ആക്റ്റിവിറ്റിയും ഇല്ലാതാക്കും"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"നിങ്ങൾ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്കാസ്റ്റ് ചെയ്യുകയോ ഔട്ട്പുട്ട് മാറ്റുകയോ ചെയ്താൽ നിങ്ങളുടെ നിലവിലുള്ള ബ്രോഡ്കാസ്റ്റ് അവസാനിക്കും"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്കാസ്റ്റ് ചെയ്യുക"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"ഔട്ട്പുട്ട് മാറ്റുക"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 5eef7d386cc1..35a29a4556b3 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -569,7 +569,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"Хэрэглэгч"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"Хязгаарлагдсан профайл"</string> <string name="user_add_user_title" msgid="5457079143694924885">"Шинэ хэрэглэгч нэмэх үү?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"Та нэмэлт хэрэглэгч үүсгэх замаар бусад хүмүүстэй энэ төхөөрөмжийг хуваалцаж болно. Хэрэглэгч тус бүр апп, дэлгэцийн зураг болон бусад зүйлээ өөрчлөх боломжтой хувийн орон зайтай байдаг. Түүнчлэн хэрэглэгч нь бүх хэрэглэгчид нөлөөлөх боломжтой Wi-Fi зэрэг төхөөрөмжийн тохиргоог өөрчлөх боломжтой.\n\nХэрэв та шинэ хэрэглэгч нэмэх бол тухайн хүн хувийн орон зайгаа бүрдүүлэх ёстой.\n\nХэрэглэгч бүр бусад бүх хэрэглэгчийн өмнөөс апп шинэчилж болно. Хүртээмжийн тохиргоо болон үйлчилгээг шинэ хэрэглэгчид шилжүүлэх боломжгүй байж болзошгүй."</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"Та нэмэлт хэрэглэгч үүсгэх замаар бусад хүмүүстэй энэ төхөөрөмжийг хуваалцаж болно. Хэрэглэгч тус бүр апп, дэлгэцийн зураг болон бусад зүйлээ өөрчлөх боломжтой хувийн орон зайтай байна. Түүнчлэн хэрэглэгч нь бүх хэрэглэгчид нөлөөлөх боломжтой Wi-Fi зэрэг төхөөрөмжийн тохиргоог өөрчлөх боломжтой.\n\nХэрэв та шинэ хэрэглэгч нэмэх бол тухайн хүн хувийн орон зайгаа бүрдүүлэх ёстой.\n\nХэрэглэгч бүр бусад бүх хэрэглэгчийн өмнөөс апп шинэчилж болно. Хандалтын тохиргоо болон үйлчилгээг шинэ хэрэглэгчид шилжүүлэх боломжгүй байж болзошгүй."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн апп-уудыг шинэчлэх боломжтой."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"Хэрэглэгчийг одоо тохируулах уу?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"Хэрэглэгч төхөөрөмжийг авч өөрийн профайлыг тохируулах боломжтой эсэхийг шалгана уу"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Хэрэв та <xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлсэн эсвэл гаралтыг өөрчилсөн бол таны одоогийн нэвтрүүлэлтийг зогсооно"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлэх"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Гаралтыг өөрчлөх"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Таамаглах боломжтой буцаах анимаци"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Таамаглах боломжтой буцаах зангаанд системийн анимацийг идэвхжүүлнэ үү."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Энэ тохиргоо нь таамаглах боломжтой зангааны анимацид системийн анимацийг идэвхжүүлнэ. Үүнд апп бүрд тодорхойлогч файлл enableOnBackInvokedCallback-г үнэн болгож тохируулахыг шаардана."</string> </resources> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 1611961f18c9..44b90d544543 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"तुम्ही <xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण केल्यास किंवा आउटपुट बदलल्यास, तुमचे सध्याचे प्रसारण बंद होईल"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण करा"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"आउटपूट बदला"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"पूर्वानुमानित मागे जाण्याचे अॅनिमेशन"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"पूर्वानुमानित मागे जाण्यासाठीचे सिस्टीम अॅनिमेशन सुरू करा."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"हे सेटिंग पूर्वानुमानित जेश्चर ॲनिमेशनसाठी सिस्टीम ॲनिमेशन सुरू करते. यासाठी मॅनिफेस्ट फाइलमध्ये प्रति ॲप enableOnBackInvokedCallback सत्य वर सेट करणे आवश्यक आहे."</string> </resources> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 79bb7a712e2b..126c5ef5fa35 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Jika anda siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau tukarkan output, siaran semasa anda akan berhenti"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Tukar output"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Animasi kembali ramalan"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Dayakan animasi sistem untuk kembali ramalan."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Tetapan ini mendayakan animasi sistem untuk animasi gerak isyarat ramalan. Animasi sistem memerlukan tetapan enableOnBackInvokedCallback untuk setiap apl kepada benar dalam fail manifes."</string> </resources> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index a4325315291a..b0f9f340e928 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -613,7 +613,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ဧည့်သည့်မှ ထွက်ရန်"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ထွက်သည့်အခါ လုပ်ဆောင်ချက်အားလုံးကို ဖျက်လိုက်မည်"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ထွက်သည့်အခါ လုပ်ဆောင်ချက်ကို သိမ်းနိုင် (သို့) ဖျက်နိုင်သည်"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"စက်ရှင်လုပ်ဆောင်ချက်ကို ယခုဖျက်ရန် ပြင်ဆင်သတ်မှတ်နိုင်သည် (သို့) ထွက်သည့်အခါ လုပ်ဆောင်ချက်ကို သိမ်းနိုင် (သို့) ဖျက်နိုင်သည်"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"စက်ရှင်လုပ်ဆောင်ချက်ကို ယခုဖျက်ရန် ပြင်ဆင်သတ်မှတ်နိုင်သည် (သို့) ထွက်သည့်အခါ သိမ်းနိုင်၊ ဖျက်နိုင်သည်"</string> <string name="user_image_take_photo" msgid="467512954561638530">"ဓာတ်ပုံရိုက်ရန်"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ပုံရွေးရန်"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ဓာတ်ပုံရွေးရန်"</string> @@ -675,4 +675,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ကို ထုတ်လွှင့်သောအခါ (သို့) အထွက်ကို ပြောင်းသောအခါ သင့်လက်ရှိထုတ်လွှင့်ခြင်း ရပ်သွားမည်"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ထုတ်လွှင့်ခြင်း"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"အထွက်ကို ပြောင်းခြင်း"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index e016a340f5c7..229730e3b057 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Hvis du kringkaster <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller endrer utgangen, stopper den nåværende kringkastingen din"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Kringkast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Endre utgang"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 9e5c0fee283b..3473b816cc3c 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"तपाईंले <xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुभयो वा आउटपुट परिवर्तन गर्नुभयो भने तपाईंको हालको ब्रोडकास्ट रोकिने छ"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुहोस्"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"आउटपुट परिवर्तन गर्नुहोस्"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"पूर्वानुमानयुक्त ब्याक एनिमेसनहरू"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"पूर्वानुमानयुक्त ब्याक एनिमेसनका हकमा सिस्टम एनिमेसनहरू लागू गर्नुहोस्।"</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"यो सेटिङले पूर्वानुमानयुक्त जेस्चर एनिमेसनका हकमा सिस्टम एनिमेनसहरू लागू गर्छ। म्यानिफेस्ट फाइलमा हरेक एपका हकमा enableOnBackInvokedCallback सेट गरी TRUE बनाएपछि मात्र यो सेटिङ अन गर्न मिल्छ।"</string> </resources> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 4050a8ab6901..0b52e9ea6070 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Als je <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzendt of de uitvoer wijzigt, wordt je huidige uitzending gestopt"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzenden"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Uitvoer wijzigen"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Voorspellende animaties voor gebaren voor terug"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Systeemanimaties aanzetten voor voorspellende animaties voor gebaren voor terug."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Met deze instelling zet je systeemanimaties aan voor voorspellende gebaaranimaties. Je moet enableOnBackInvokedCallback per app instellen op True in het manifestbestand."</string> </resources> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 5e275a5aa43d..1649550cc4ca 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"ଯଦି ଆପଣ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତି କିମ୍ବା ଆଉଟପୁଟ ବଦଳାନ୍ତି, ତେବେ ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ବ୍ରଡକାଷ୍ଟ ବନ୍ଦ ହୋଇଯିବ"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତୁ"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"ଆଉଟପୁଟ ବଦଳାନ୍ତୁ"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index a626274578d2..8cda50050b63 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -569,7 +569,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"ਵਰਤੋਂਕਾਰ"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"ਪ੍ਰਤਿਬੰਧਿਤ ਪ੍ਰੋਫਾਈਲ"</string> <string name="user_add_user_title" msgid="5457079143694924885">"ਕੀ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨਾ ਹੈ?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"ਤੁਸੀਂ ਵਾਧੂ ਵਰਤੋਂਕਾਰ ਬਣਾ ਕੇ ਹੋਰਾਂ ਲੋਕਾਂ ਨਾਲ ਇਹ ਡੀਵਾਈਸ ਸਾਂਝਾ ਕਰ ਸਕਦੇ ਹੋ। ਹਰੇਕ ਵਰਤੋਂਕਾਰ ਦੀ ਆਪਣੀ ਖੁਦ ਦੀ ਜਗ੍ਹਾ ਹੁੰਦੀ ਹੈ, ਜਿਸਨੂੰ ਉਹ ਐਪਾਂ ਅਤੇ ਵਾਲਪੇਪਰ ਆਦਿ ਨਾਲ ਵਿਉਂਤਬੱਧ ਕਰ ਸਕਦੇ ਹਨ। ਵਰਤੋਂਕਾਰ ਡੀਵਾਈਸ ਸੈਟਿੰਗਾਂ ਵੀ ਵਿਵਸਥਿਤ ਕਰ ਸਕਦੇ ਹਨ ਜਿਵੇਂ ਵਾਈ‑ਫਾਈ ਜੋ ਹਰੇਕ \'ਤੇ ਅਸਰ ਪਾਉਂਦੀ ਹੈ।\n\nਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸੈੱਟ ਅੱਪ ਕਰਨੀ ਪੈਂਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਬਾਕੀ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ। ਸ਼ਾਇਦ ਪਹੁੰਚਯੋਗਤਾ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਨੂੰ ਕਿਸੇ ਨਵੇਂ ਵਰਤੋਂਕਾਰ ਨੂੰ ਟ੍ਰਾਂਸਫਰ ਨਾ ਕੀਤਾ ਜਾ ਸਕੇ।"</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"ਤੁਸੀਂ ਵਾਧੂ ਵਰਤੋਂਕਾਰ ਬਣਾ ਕੇ ਹੋਰਾਂ ਲੋਕਾਂ ਨਾਲ ਇਹ ਡੀਵਾਈਸ ਸਾਂਝਾ ਕਰ ਸਕਦੇ ਹੋ। ਹਰੇਕ ਵਰਤੋਂਕਾਰ ਦੀ ਆਪਣੀ ਖੁਦ ਦੀ ਜਗ੍ਹਾ ਹੁੰਦੀ ਹੈ, ਜਿਸਨੂੰ ਉਹ ਐਪਾਂ ਅਤੇ ਵਾਲਪੇਪਰ ਆਦਿ ਨਾਲ ਵਿਉਂਤਬੱਧ ਕਰ ਸਕਦੇ ਹਨ। ਵਰਤੋਂਕਾਰ ਵਾਈ-ਫਾਈ ਵਰਗੀਆਂ ਡੀਵਾਈਸ ਸੈਟਿੰਗਾਂ ਨੂੰ ਵੀ ਵਿਵਸਥਿਤ ਕਰ ਸਕਦੇ ਹਨ, ਜਿਸ ਨਾਲ ਹਰੇਕ ਵਰਤੋਂਕਾਰ \'ਤੇ ਅਸਰ ਪੈਂਦਾ ਹੈ।\n\nਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸੈੱਟ ਅੱਪ ਕਰਨੀ ਪੈਂਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਬਾਕੀ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ। ਸ਼ਾਇਦ ਪਹੁੰਚਯੋਗਤਾ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਨੂੰ ਕਿਸੇ ਨਵੇਂ ਵਰਤੋਂਕਾਰ ਨੂੰ ਟ੍ਰਾਂਸਫਰ ਨਾ ਕੀਤਾ ਜਾ ਸਕੇ।"</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"ਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸੈੱਟਅੱਪ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਹੋਰ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"ਕੀ ਹੁਣ ਵਰਤੋਂਕਾਰ ਸੈੱਟ ਅੱਪ ਕਰਨਾ ਹੈ?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਵਿਅਕਤੀ ਡੀਵਾਈਸ ਵਰਤਣ ਅਤੇ ਆਪਣੀ ਜਗ੍ਹਾ ਦੇ ਸੈੱਟ ਅੱਪ ਲਈ ਉਪਲਬਧ ਹੈ"</string> @@ -611,8 +611,8 @@ <string name="guest_reset_button" msgid="2515069346223503479">"ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਨੂੰ ਰੀਸੈੱਟ ਕਰੋ"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ਮਹਿਮਾਨ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ਬਾਹਰ ਜਾਣ \'ਤੇ ਸਾਰੀ ਸਰਗਰਮੀ ਮਿਟਾਈ ਜਾਵੇਗੀ"</string> - <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ਤੁਸੀਂ ਬਾਹਰ ਜਾਣ \'ਤੇ ਆਪਣੀ ਸਭ ਸਰਗਰਮੀ ਰੱਖਿਅਤ ਕਰ ਜਾਂ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ਸੈਸ਼ਨ ਦੀ ਸਰਗਰਮੀ ਮਿਟਾਉਣ ਹੁਣੇ ਲਈ ਰੀਸੈੱਟ ਕਰੋ ਜਾਂ ਤੁਸੀਂ ਬਾਹਰ ਜਾਣ \'ਤੇ ਸਰਗਰਮੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰ ਜਾਂ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string> + <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ਤੁਸੀਂ ਬਾਹਰ ਜਾਣ \'ਤੇ ਆਪਣੀ ਸਰਗਰਮੀ ਰੱਖਿਅਤ ਕਰ ਜਾਂ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ਸੈਸ਼ਨ ਦੀ ਸਰਗਰਮੀ ਹੁਣੇ ਮਿਟਾਉਣ ਲਈ ਰੀਸੈੱਟ ਕਰੋ ਜਾਂ ਤੁਸੀਂ ਬਾਹਰ ਜਾਣ \'ਤੇ ਸਰਗਰਮੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰ ਜਾਂ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string> <string name="user_image_take_photo" msgid="467512954561638530">"ਇੱਕ ਫ਼ੋਟੋ ਖਿੱਚੋ"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ਕੋਈ ਚਿੱਤਰ ਚੁਣੋ"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ਫ਼ੋਟੋ ਚੁਣੋ"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"ਜੇ ਤੁਸੀਂ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰਦੇ ਹੋ ਜਾਂ ਆਊਟਪੁੱਟ ਬਦਲਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਪ੍ਰਸਾਰਨ ਰੁਕ ਜਾਵੇਗਾ"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰੋ"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"ਆਊਟਪੁੱਟ ਬਦਲੋ"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 658a63ba989e..3488532f3506 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -611,8 +611,8 @@ <string name="guest_reset_button" msgid="2515069346223503479">"Zresetuj sesję gościa"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Zakończ tryb gościa"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Cała aktywność zostanie usunięta po zamknięciu"</string> - <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Możesz zapisać lub usunąć swoją aktywność podczas zamykania"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Zresetuj, aby usunąć aktywność w sesji w tym momencie. Możesz też ją zapisać lub usunąć podczas zamykania"</string> + <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Możesz zapisać lub usunąć swoją aktywność podczas zamykania."</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Zresetuj, aby teraz usunąć aktywność z tej sesji. Możesz też ją zapisać lub usunąć podczas zamykania sesji."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Zrób zdjęcie"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Wybierz obraz"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Wybierz zdjęcie"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Jeśli transmitujesz aplikację <xliff:g id="SWITCHAPP">%1$s</xliff:g> lub zmieniasz dane wyjściowe, Twoja obecna transmisja zostanie zakończona"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Transmisja aplikacji <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Zmień dane wyjściowe"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 06faf68461ca..c8f57d5b6feb 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Sair do modo visitante"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Todas as atividades serão excluídas ao sair"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Você pode salvar ou excluir sua atividade ao sair"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Faça uma redefinição para excluir a atividade da sessão agora. Você também pode salvar ou excluir a atividade ao sair"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Redefina para excluir a atividade da sessão agora. Salve ou exclua a atividade ao sair"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Mudar saída"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 4fc5728b4177..dbda70ddd73f 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -569,7 +569,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"Utilizador"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"Perfil restrito"</string> <string name="user_add_user_title" msgid="5457079143694924885">"Adicionar novo utilizador?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"Pode partilhar este dispositivo com outras pessoas ao criar utilizadores adicionais. Cada utilizador possui o seu próprio espaço, que pode ser personalizado com aplicações, imagens de fundo, etc. Os utilizadores também podem ajustar as definições do dispositivo, como o Wi‑Fi, que afetam os restantes utilizadores.\n\nAo adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar aplicações para todos os outros utilizadores. Os serviços e as definições de acessibilidade podem não ser transferidos para o novo utilizador."</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"Pode partilhar este dispositivo com outras pessoas ao criar utilizadores adicionais. Cada utilizador possui o seu próprio espaço, que pode ser personalizado com apps, imagens de fundo, etc. Os utilizadores também podem ajustar as definições do dispositivo, como o Wi‑Fi, que afetam os restantes utilizadores.\n\nAo adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar apps para todos os outros utilizadores. Os serviços e as definições de acessibilidade podem não ser transferidos para o novo utilizador."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar aplicações para todos os outros utilizadores."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"Configurar o utilizador agora?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"Certifique-se de que a pessoa está disponível para levar o dispositivo e configurar o seu espaço"</string> @@ -607,12 +607,12 @@ <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Pode guardar a atividade da sessão atual ou eliminar todas as apps e dados"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Eliminar"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Guardar"</string> - <string name="guest_exit_button" msgid="5774985819191803960">"Sair do modo de convidado"</string> + <string name="guest_exit_button" msgid="5774985819191803960">"Sair do modo convidado"</string> <string name="guest_reset_button" msgid="2515069346223503479">"Repor sessão de convidado"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Sair do modo de convidado"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toda a atividade é eliminada ao sair"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Pode guardar ou eliminar a sua atividade ao sair"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reponha para eliminar agora a atividade da sessão. Em alternativa, pode guardar ou eliminar a atividade ao sair"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reponha para eliminar agora a atividade da sessão. Pode ainda guardar ou eliminar a atividade ao sair"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Se transmitir a app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou alterar a saída, a sua transmissão atual é interrompida"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Transmita a app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Altere a saída"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Animações de gestos para voltar preditivos"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Ative as animações do sistema para gestos para voltar preditivos."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta definição ativa animações do sistema para a animação de gestos preditivos. Requer a definição do atributo enableOnBackInvokedCallback por app como verdadeiro no ficheiro de manifesto."</string> </resources> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 06faf68461ca..c8f57d5b6feb 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Sair do modo visitante"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Todas as atividades serão excluídas ao sair"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Você pode salvar ou excluir sua atividade ao sair"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Faça uma redefinição para excluir a atividade da sessão agora. Você também pode salvar ou excluir a atividade ao sair"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Redefina para excluir a atividade da sessão agora. Salve ou exclua a atividade ao sair"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Mudar saída"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 019fb7f60fe1..085226eea1ce 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Dacă difuzați <xliff:g id="SWITCHAPP">%1$s</xliff:g> sau schimbați rezultatul, difuzarea actuală se va opri"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Difuzați <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Schimbați rezultatul"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 2910ebc02652..dfd052b37682 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Выйти из гостевого режима"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"История будет удалена сразу после выхода."</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"При выходе вы можете сохранить или удалить историю."</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сбросьте историю сеанса прямо сейчас и удалите или сохраните ее при выходе."</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Можно сбросить историю сеанса прямо сейчас, либо удалить или сохранить ее при выходе."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Сделать снимок"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбрать фото"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Выбрать фотографию"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Если вы начнете транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" или смените целевое устройство, текущая трансляция прервется."</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Транслировать на другое устройство"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Анимации подсказки для жеста \"Назад\""</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Включить системную анимацию подсказки для жеста \"Назад\"."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"С помощью этого параметра можно включить системные анимации подсказок для жестов. Для этого нужно установить значение true для enableOnBackInvokedCallback в файле манифеста приложения."</string> </resources> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index c8c411dbf177..3da503455451 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"ඔබ <xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය කළහොත් හෝ ප්රතිදානය වෙනස් කළහොත්, ඔබගේ වත්මන් විකාශනය නවතිනු ඇත."</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"ප්රතිදානය වෙනස් කරන්න"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 5ad807118909..c398f661e43a 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -280,7 +280,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certifikácia bezdrôtového zobrazenia"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Podrobné denníky Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Pribrzdiť vyhľadávanie sietí Wi‑Fi"</string> - <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Randomizácia dočasnej adresy MAC siete Wi‑Fi"</string> + <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Randomizovať dočasnú adresu MAC siete Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilné dáta ponechať vždy aktívne"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardvérová akcelerácia tetheringu"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Zobrazovať zariadenia Bluetooth bez názvov"</string> @@ -381,7 +381,7 @@ <string name="debug_layout_summary" msgid="8825829038287321978">"Zobraziť vo výstrižku ohraničenie, okraje a pod."</string> <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Rozloženie sprava doľava"</string> <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Vynútiť pre všetky jazyky rozloženie obrazovky sprava doľava"</string> - <string name="window_blurs" msgid="6831008984828425106">"Povolenie rozmazania na úrovni okna"</string> + <string name="window_blurs" msgid="6831008984828425106">"Povoliť rozmazanie na úrovni okna"</string> <string name="force_msaa" msgid="4081288296137775550">"Vynútiť 4x MSAA"</string> <string name="force_msaa_summary" msgid="9070437493586769500">"Povoliť 4x MSAA v aplikáciách OpenGL ES 2.0"</string> <string name="show_non_rect_clip" msgid="7499758654867881817">"Ladiť operácie s neobdĺžnikovými výstrižkami"</string> @@ -600,11 +600,11 @@ <string name="guest_resetting" msgid="7822120170191509566">"Relácia hosťa sa resetuje…"</string> <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Chcete resetovať reláciu hosťa?"</string> <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Týmto sa spustí nová relácia hosťa a odstránia sa všetky aplikácie a údaje z aktuálnej relácie"</string> - <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Chcete skončiť režim pre hostí?"</string> + <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Chcete ukončiť režim pre hostí?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ukončí sa režim pre hostí a odstránia sa aplikácie a údaje z relácie hosťa"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Ukončiť"</string> <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Chcete uložiť aktivitu hosťa?"</string> - <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Aktivitu v aktuálnej relácii uložte alebo odstráňte všetky aplikácie a údaje"</string> + <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Môžte uložiť aktivitu aktuálnej relácie alebo odstrániť všetky aplikácie a údaje"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Odstrániť"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Uložiť"</string> <string name="guest_exit_button" msgid="5774985819191803960">"Ukončiť režim pre hostí"</string> @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Ukončiť režim pre hostí"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Pri ukončení sa všetka aktivita odstráni"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Aktivitu môžete pri ukončení uložiť alebo odstrániť"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetovaním ihneď odstráňte aktivitu relácie alebo ju uložte či odstráňte pri ukončení relácie"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetovaním ihneď odstránite aktivitu relácie alebo ju uložte či odstráňte pri ukončení relácie"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Odfotiť"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrať obrázok"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Vybrať fotku"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ak vysielate aplikáciu <xliff:g id="SWITCHAPP">%1$s</xliff:g> alebo zmeníte výstup, aktuálne vysielanie bude zastavené"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Vysielanie aplikácie <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Zmena výstupu"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Prediktívne animácie gesta Späť"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Povoľte animácie v systéme pre prediktívne gesto Späť"</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Toto nastavenie povoľuje animácie v systéme na účely prediktívnej animácie gest. Vyžaduje nastavenie povolenia enableOnBackInvokedCallback na pravdu v súbore manifestu konkrétnej aplikácie."</string> </resources> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 34bfa8e5d3a5..0d0a0de97cce 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -568,7 +568,7 @@ <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Dostop do aplikacij in vsebine iz vašega računa lahko omejite"</string> <string name="user_add_user_item_title" msgid="2394272381086965029">"Uporabnik"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"Omejen profil"</string> - <string name="user_add_user_title" msgid="5457079143694924885">"Dodajanje novega uporabnika?"</string> + <string name="user_add_user_title" msgid="5457079143694924885">"Želite dodati uporabnika?"</string> <string name="user_add_user_message_long" msgid="1527434966294733380">"To napravo lahko delite z drugimi tako, da ustvarite dodatne uporabnike. Vsak ima svoj prostor, ki ga lahko prilagodi z aplikacijami, ozadji in drugim. Uporabniki lahko tudi prilagodijo nastavitve naprave, ki vplivajo na vse, na primer nastavitve omrežja Wi-Fi.\n\nKo dodate novega uporabnika, mora ta nastaviti svoj prostor.\n\nVsak uporabnik lahko posodobi aplikacije za vse druge uporabnike. Nastavitve in storitve funkcij za ljudi s posebnimi potrebami morda ne bodo prenesene v prostor novega uporabnika."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"Ko dodate novega uporabnika, mora ta nastaviti svoj prostor.\n\nVsak uporabnik lahko posodobi aplikacije za vse druge uporabnike."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"Želite uporabnika nastaviti zdaj?"</string> @@ -600,7 +600,7 @@ <string name="guest_resetting" msgid="7822120170191509566">"Ponastavljanje gosta …"</string> <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Želite ponastaviti sejo gosta?"</string> <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"S tem boste začeli novo sejo gosta ter izbrisali vse aplikacije in podatke v trenutni seji."</string> - <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Zapri način za goste"</string> + <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Želite zapreti način za goste?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"S tem boste izbrisali aplikacije in podatke v trenutni seji gosta."</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Zapri"</string> <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Želite shraniti dejavnost gosta?"</string> @@ -610,9 +610,9 @@ <string name="guest_exit_button" msgid="5774985819191803960">"Zapri način za goste"</string> <string name="guest_reset_button" msgid="2515069346223503479">"Ponastavi sejo gosta"</string> <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Zapri sejo gosta"</string> - <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Ko zaprete sejo, bo vsa dejavnost izbrisana."</string> - <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Ko zaprete sejo, lahko shranite ali izbrišete dejavnost."</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ponastavite, če želite dejavnost v seji izbrisati zdaj, lahko pa jo shranite ali izbrišete, ko zaprete sejo."</string> + <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Ko zaprete način za goste, bo vsa dejavnost izbrisana."</string> + <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Ob zaprtju načina lahko shranite ali izbrišete dejavnost."</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ponastavite za izbris dejavnosti v seji zdaj, lahko pa jo shranite ali izbrišete, ko zaprete način za goste."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiranje"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Izberi sliko"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Izbira fotografije"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Če oddajate aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g> ali spremenite izhod, bo trenutno oddajanje ustavljeno."</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Oddajaj aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Sprememba izhoda"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije poteze za nazaj s predvidevanjem"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogoči sistemske animacije za potezo za nazaj s predvidevanjem."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ta nastavitev omogoča sistemske animacije za animacijo poteze s predvidevanjem. V datoteki manifesta mora biti parameter »enableOnBackInvokedCallback« za posamezno aplikacijo nastavljen na »true«."</string> </resources> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index aa8aee827087..ec64a925c0f0 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Nëse transmeton <xliff:g id="SWITCHAPP">%1$s</xliff:g> ose ndryshon daljen, transmetimi yt aktual do të ndalojë"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Transmeto <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Ndrysho daljen"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 381cd971727e..ff73639f0460 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -594,7 +594,7 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Ресетуј сесију госта"</string> <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Желите ли да ресетујете сесију госта?"</string> - <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Желите ли да уклоните госта?"</string> + <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Желите да уклоните госта?"</string> <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетуј"</string> <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Уклони"</string> <string name="guest_resetting" msgid="7822120170191509566">"Сесија госта се ресетује…"</string> @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Изађи из режима госта"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Све активности ће бити избрисане при излазу"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Можете да сачувате или избришете активности при излазу"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ресетујете да бисте избрисали активности сесије одмах или можете да сачувате или избришете активности при излазу"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ресетујете за брисање активности сесије, или сачувајте или избришите активности при излазу"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Изаберите слику"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Промените излаз"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Анимације за покрет повратка са предвиђањем"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Омогућите анимације система за покрет повратка са предвиђањем."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ово подешавање омогућава анимације система за покрет повратка са предвиђањем. Захтева подешавање дозволе enableOnBackInvokedCallback по апликацији на true у фајлу манифеста."</string> </resources> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index 683619a6a305..e3960b2e4a78 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -569,7 +569,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"Användare"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"Begränsad profil"</string> <string name="user_add_user_title" msgid="5457079143694924885">"Lägga till ny användare?"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dela enheten med andra om du skapar flera användare. Alla användare får sitt eget utrymme som de kan anpassa som de vill med appar, bakgrund och så vidare. Användarna kan även ändra enhetsinställningar som påverkar alla, till exempel Wi‑Fi.\n\nNär du lägger till en ny användare måste han eller hon konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning. Tillgänglighetsinställningar och tjänster kanske inte överförs till den nya användaren."</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"Du kan dela enheten med andra om du skapar flera användare. Alla användare får sitt eget utrymme som de kan anpassa som de vill med appar, bakgrund och så vidare. Användarna kan även ändra enhetsinställningar som påverkar alla, till exempel wifi.\n\nNär du lägger till en ny användare måste han eller hon konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning. Tillgänglighetsinställningar och tjänster kanske inte överförs till den nya användaren."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"Konfigurera användare nu?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"Kontrollera att personen finns tillgänglig för att konfigurera sitt utrymme på enheten"</string> @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Avsluta gästsession"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All aktivitet raderas när du avslutar"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Du kan spara eller radera aktivitet när du avslutar"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Återställ om du vill radera sessionsaktiviteten nu. Du kan också spara eller radera aktivitet när du avslutar"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Återställ om du vill radera sessionsaktiviteten nu, eller spara eller radera aktivitet när du avslutar"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Ta ett foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Välj en bild"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Välj foto"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Om en utsändning från <xliff:g id="SWITCHAPP">%1$s</xliff:g> pågår eller om du byter ljudutgång avbryts den nuvarande utsändningen"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Sänd från <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Byt ljudutgång"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index dbef1b74e8d0..c2b75cd3f175 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ikiwa unatangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g> au unabadilisha maudhui, tangazo lako la sasa litasimamishwa"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Tangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Badilisha maudhui"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 6544a2335b18..70e2c6283611 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"நீங்கள் <xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பினாலோ அவுட்புட்டை மாற்றினாலோ உங்களின் தற்போதைய ஒலிபரப்பு நிறுத்தப்படும்"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பு"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"அவுட்புட்டை மாற்று"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"கணிக்கக்கூடிய பின்செல் சைகைக்கான அனிமேஷன்கள்"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"கணிக்கக்கூடிய பின்செல் சைகைக்காகச் சிஸ்டம் அனிமேஷன்களை இயக்கும்."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"கணிக்கக்கூடிய சைகைக்கான அனிமேஷனுக்காக இந்த அமைப்பு சிஸ்டம் அனிமேஷன்களை இயக்கும். மெனிஃபெஸ்ட் ஃபைலில் ஒவ்வொரு ஆப்ஸுக்கும் enableOnBackInvokedCallbackகை \'சரி\' என அமைக்க வேண்டும்."</string> </resources> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index f6612b8243dd..c711dc433df9 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -583,7 +583,7 @@ <string name="profile_info_settings_title" msgid="105699672534365099">"ప్రొఫైల్ సమాచారం"</string> <string name="user_need_lock_message" msgid="4311424336209509301">"మీరు పరిమితం చేయబడిన ప్రొఫైల్ను క్రియేట్ చేయడానికి ముందు, మీ యాప్లు మరియు వ్యక్తిగత డేటాను రక్షించడానికి స్క్రీన్ లాక్ను సెటప్ చేయాల్సి ఉంటుంది."</string> <string name="user_set_lock_button" msgid="1427128184982594856">"లాక్ను సెట్ చేయి"</string> - <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>కు స్విచ్ చేయి"</string> + <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>కు స్విచ్ చేయి"</string> <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"కొత్త యూజర్ను క్రియేట్ చేస్తోంది…"</string> <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"కొత్త అతిథిని క్రియేట్ చేస్తోంది…"</string> <string name="add_user_failed" msgid="4809887794313944872">"కొత్త యూజర్ను క్రియేట్ చేయడం విఫలమైంది"</string> @@ -599,7 +599,7 @@ <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"తీసివేయండి"</string> <string name="guest_resetting" msgid="7822120170191509566">"గెస్ట్ సెషన్ను రీసెట్ చేస్తోంది…"</string> <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"గెస్ట్ సెషన్ను రీసెట్ చేయాలా?"</string> - <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ఇది కొత్త గెస్ట్ సెషన్ను ప్రారంభిస్తుంది, ప్రస్తుత సెషన్ నుండి అన్ని యాప్లు, డేటాను తొలగించండి"</string> + <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ఇది కొత్త గెస్ట్ సెషన్ను ప్రారంభిస్తుంది, ప్రస్తుత సెషన్ నుండి అన్ని యాప్లు, డేటాను తొలగిస్తుంది."</string> <string name="guest_exit_dialog_title" msgid="1846494656849381804">"గెస్ట్ మోడ్ నిష్క్రమించాలా?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ఇది ప్రస్తుత గెస్ట్ సెషన్ నుండి యాప్లు, డేటాను తొలగిస్తుంది"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"నిష్క్రమించండి"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"మీరు <xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేస్తే లేదా అవుట్పుట్ను మార్చినట్లయితే, మీ ప్రస్తుత ప్రసారం ఆగిపోతుంది"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేయండి"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"అవుట్పుట్ను మార్చండి"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"ఊహించదగిన బ్యాక్ యానిమేషన్లు"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"ఊహించదగిన బ్యాక్ యానిమేషన్ల కోసం సిస్టమ్ యానిమేషన్లను ఎనేబుల్ చేయండి."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ఊహించదగిన సంజ్ఞ యానిమేషన్ కోసం ఈ సెట్టింగ్ సిస్టమ్ యానిమేషన్లను ఎనేబుల్ చేస్తుంది. దీనికి మ్యానిఫెస్ట్ ఫైల్లో ఒక్కో యాప్లో enableOnBackInvokedCallback సెట్టింగ్ను ఒప్పునకు సెట్ చేయవలసి ఉంటుంది."</string> </resources> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 7299ab555bb6..649d8de0f816 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -569,7 +569,7 @@ <string name="user_add_user_item_title" msgid="2394272381086965029">"ผู้ใช้"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"โปรไฟล์ที่ถูกจำกัด"</string> <string name="user_add_user_title" msgid="5457079143694924885">"ต้องการเพิ่มผู้ใช้ใหม่ใช่ไหม"</string> - <string name="user_add_user_message_long" msgid="1527434966294733380">"คุณมีสิทธิ์แชร์อุปกรณ์นี้กับผู้อื่นได้โดยการเพิ่มผู้ใช้ ซึ่งแต่ละคนจะมีพื้นที่ของตนเองและปรับใช้กับแอป วอลเปเปอร์ และรายการอื่นๆ ได้ อีกทั้งยังปรับการตั้งค่าอุปกรณ์ได้ด้วย เช่น Wi‑Fi ซึ่งจะมีผลกับทุกคน\n\nเมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตน\n\nผู้ใช้ทุกคนมีสิทธิ์อัปเดตแอปให้กับผู้ใช้รายอื่น การตั้งค่าและบริการสำหรับการช่วยเหลือพิเศษอาจโอนไปยังผู้ใช้ใหม่ไม่ได้"</string> + <string name="user_add_user_message_long" msgid="1527434966294733380">"คุณมีสิทธิ์แชร์อุปกรณ์นี้กับผู้อื่นได้โดยการเพิ่มผู้ใช้ แต่ละคนจะมีพื้นที่ของตนเองซึ่งปรับใช้กับแอป วอลเปเปอร์ และรายการอื่นๆ ได้ อีกทั้งยังปรับการตั้งค่าอุปกรณ์ได้ด้วย เช่น Wi‑Fi ซึ่งจะมีผลกับทุกคน\n\nเมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตน\n\nผู้ใช้ทุกคนมีสิทธิ์อัปเดตแอปให้ผู้ใช้รายอื่น การตั้งค่าและบริการสำหรับการช่วยเหลือพิเศษอาจโอนไปยังผู้ใช้ใหม่ไม่ได้"</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"เมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตนเอง\n\nผู้ใช้ทุกคนสามารถอัปเดตแอปสำหรับผู้ใช้รายอื่นได้"</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"ตั้งค่าผู้ใช้เลยไหม"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"ตรวจสอบว่าบุคคลดังกล่าวสามารถนำอุปกรณ์ไปตั้งค่าพื้นที่ของตนได้"</string> @@ -598,21 +598,21 @@ <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"รีเซ็ต"</string> <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"นำออก"</string> <string name="guest_resetting" msgid="7822120170191509566">"กำลังรีเซ็ตผู้เข้าร่วม…"</string> - <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"รีเซ็ตเซสชันผู้มาเยือนไหม"</string> - <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"การดำเนินการนี้จะเริ่มเซสชันผู้มาเยือนใหม่ และจะลบแอปและข้อมูลทั้งหมดจากเซสชันปัจจุบัน"</string> - <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ออกจากโหมดผู้มาเยือนไหม"</string> + <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"รีเซ็ตเซสชันผู้ใช้ชั่วคราวไหม"</string> + <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"การดำเนินการนี้จะเริ่มเซสชันผู้ใช้ชั่วคราวใหม่ และจะลบแอปและข้อมูลทั้งหมดจากเซสชันปัจจุบัน"</string> + <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ออกจากโหมดผู้ใช้ชั่วคราวไหม"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"การดำเนินการนี้จะลบแอปและข้อมูลออกจากเซสชันผู้มาเยือนในปัจจุบัน"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ออก"</string> - <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"บันทึกกิจกรรมของผู้มาเยือนไหม"</string> + <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"บันทึกกิจกรรมของผู้ใช้ชั่วคราวไหม"</string> <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"คุณสามารถบันทึกกิจกรรมจากเซสชันปัจจุบันหรือจะลบแอปและข้อมูลทั้งหมดก็ได้"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ลบ"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"บันทึก"</string> - <string name="guest_exit_button" msgid="5774985819191803960">"ออกจากโหมดผู้มาเยือน"</string> - <string name="guest_reset_button" msgid="2515069346223503479">"รีเซ็ตเซสชันผู้มาเยือน"</string> - <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ออกจากโหมดผู้มาเยือน"</string> + <string name="guest_exit_button" msgid="5774985819191803960">"ออกจากโหมดผู้ใช้ชั่วคราว"</string> + <string name="guest_reset_button" msgid="2515069346223503479">"รีเซ็ตเซสชันผู้ใช้ชั่วคราว"</string> + <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ออกจากโหมดผู้ใช้ชั่วคราว"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ระบบจะลบกิจกรรมทั้งหมดเมื่อออก"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"คุณสามารถบันทึกหรือลบกิจกรรมเมื่อออก"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"รีเซ็ตเพื่อลบกิจกรรมของเซสชันตอนนี้เลย หรือจะบันทึกหรือลบกิจกรรมเมื่อออกก็ได้"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"รีเซ็ตเพื่อลบกิจกรรมของเซสชันตอนนี้เลย หรือจะบันทึกหรือลบกิจกรรมเมื่อออกก็ได้"</string> <string name="user_image_take_photo" msgid="467512954561638530">"ถ่ายรูป"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"เลือกรูปภาพ"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"เลือกรูปภาพ"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"หากคุณออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g> หรือเปลี่ยนแปลงเอาต์พุต การออกอากาศในปัจจุบันจะหยุดลง"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"ออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"เปลี่ยนเอาต์พุต"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"การเคลื่อนไหวย้อนกลับแบบคาดเดา"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"เปิดใช้การเคลื่อนไหวของระบบสำหรับท่าทางสัมผัสย้อนกลับแบบคาดเดา"</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"การตั้งค่านี้จะเปิดใช้การเคลื่อนไหวของระบบสำหรับการเคลื่อนไหวจากท่าทางสัมผัสแบบคาดเดา โดยต้องตั้งค่า enableOnBackInvokedCallback สำหรับแต่ละแอปให้เป็น \"จริง\" ในไฟล์ Manifest"</string> </resources> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index a1c4fffc0217..bb8ba5222f39 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Kung magbo-broadcast ka ng <xliff:g id="SWITCHAPP">%1$s</xliff:g> o babaguhin mo ang output, hihinto ang iyong kasalukuyang broadcast"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"I-broadcast ang <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Baguhin ang output"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Mga animation ng predictive na pagbalik"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"I-enable ang mga animation ng system para sa predictive na pagbalik."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ine-enable ng setting na ito ang mga animation ng system para sa animation ng predictive na galaw. Kinakailangan nitong itakda sa true ang enableOnBackInvokedCallback sa bawat app sa manifest file."</string> </resources> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 24c6d690c325..3cde80416779 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Misafir modundan çık"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Çıkış yapıldığında tüm etkinlikler silinir"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Etkinliklerinizi çıkarken kaydedebilir veya silebilirsiniz"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Oturum etkinliklerini hemen silmek için sıfırlayın. Etkinlikleri çıkarken kaydetmeyi veya silmeyi de tercih edebilirsiniz"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Oturum etkinliklerini silmek için sıfırlayabilir ya da çıkarken kaydedebilir veya silebilirsiniz"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Fotoğraf çek"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Resim seç"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Fotoğraf seç"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapar veya çıkışı değiştirirseniz mevcut anonsunuz duraklatılır"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapın"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Çıkışı değiştirme"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index cab4add99c10..1377667c79bd 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Вийти з режиму гостя"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Під час виходу буде видалено всі дії"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Під час виходу можна зберегти або видалити ваші дії"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Скиньте, щоб зараз видалити дії під час сеансу. Ви також можете зберегти чи видалити дії під час виходу."</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Можна скинути історію сеансу просто зараз або видалити чи зберегти її під час виходу."</string> <string name="user_image_take_photo" msgid="467512954561638530">"Зробити фотографію"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Вибрати зображення"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Вибрати фотографію"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Якщо ви зміните додаток (<xliff:g id="SWITCHAPP">%1$s</xliff:g>) або аудіовихід, поточну трансляцію буде припинено"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Змінити додаток для трансляції на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Змінити аудіовихід"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 77530b6c2a10..7a0dcbbc73cc 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -599,7 +599,7 @@ <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ہٹائیں"</string> <string name="guest_resetting" msgid="7822120170191509566">"مہمان کو ری سیٹ کرنا…"</string> <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"مہمان سیشن کو ری سیٹ کریں؟"</string> - <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"یہ ایک نیا مہمان سیشن شروع کرے گا اور موجودہ سیشن سے تمام ایپس اور ڈیٹا کو حذف کر دے گا"</string> + <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"اس سے ایک نیا مہمان سیشن شروع ہو گا اور موجودہ سیشن سے تمام ایپس اور ڈیٹا حذف ہو جائے گا"</string> <string name="guest_exit_dialog_title" msgid="1846494656849381804">"مہمان وضع سے باہر نکلیں؟"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"یہ موجودہ مہمان سیشن سے ایپس اور ڈیٹا کو حذف کر دے گا"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"باہر نکلیں"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"اگر آپ <xliff:g id="SWITCHAPP">%1$s</xliff:g> براڈکاسٹ کرتے ہیں یا آؤٹ پٹ کو تبدیل کرتے ہیں تو آپ کا موجودہ براڈکاسٹ رک جائے گا"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> پر براڈکاسٹ کریں"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"آؤٹ پٹ تبدیل کریں"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"پیچھے جانے کے اشارے کی پیش گوئی والی اینیمیشنز"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"پیچھے جانے کے پیش گوئی والے اشارے کے لیے سسٹم اینیمیشنز فعال کریں۔"</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"یہ ترتیب پیش گوئی والی اشارے کی اینیمیشن کے لیے سسٹم کی اینیمیشنز کو فعال کرتی ہے۔ اس کے لیے manifest فائل میں فی ایپ enableOnBackInvokedCallback کو درست پر سیٹ کرنے کی ضرورت ہے۔"</string> </resources> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index c003838b7e20..92f21df6942b 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -604,7 +604,7 @@ <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bunda joriy mehmon seansidagi ilova va ularning maʼlumotlari tozalanadi"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Chiqish"</string> <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Mehmon faoliyati saqlansinmi?"</string> - <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Joriy seansdagi faoliyatni saqlash yoki barcha ilova va maʼlumotlarni tozalash mumkin"</string> + <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Joriy seansdagi faoliyatni saqlash yoki barcha ilova va maʼlumotlarni oʻchirib tashlashingiz mumkin"</string> <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Oʻchirish"</string> <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Saqlash"</string> <string name="guest_exit_button" msgid="5774985819191803960">"Mehmon rejimidan chiqish"</string> @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Agar <xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya qilsangiz yoki ovoz chiqishini oʻzgartirsangiz, joriy translatsiya toʻxtab qoladi"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Ovoz chiqishini oʻzgartirish"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Taxminiy qaytish animatsiyalari"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Taxminiy qaytish uchun tizim animatsiyalarini yoqish."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Bu sozlamalar taxminiy qaytish animatsiyalari uchun tizim animatsiyalarini faollashtiradi. Buning uchun har bir ilovaning manifest faylida enableOnBackInvokedCallback parametri “true” qiymatida boʻlishi lozim."</string> </resources> diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml index ea5230c8be10..4cf8ff49b636 100644 --- a/packages/SettingsLib/res/values-vi/arrays.xml +++ b/packages/SettingsLib/res/values-vi/arrays.xml @@ -178,13 +178,13 @@ <item msgid="2983219471251787208">"8 MB/vùng đệm nhật ký"</item> </string-array> <string-array name="select_logpersist_titles"> - <item msgid="704720725704372366">"Tắt"</item> + <item msgid="704720725704372366">"Đang tắt"</item> <item msgid="6014837961827347618">"Tất cả"</item> <item msgid="7387060437894578132">"Tất cả trừ đài"</item> <item msgid="7300881231043255746">"chỉ kernel"</item> </string-array> <string-array name="select_logpersist_summaries"> - <item msgid="97587758561106269">"Tắt"</item> + <item msgid="97587758561106269">"Đang tắt"</item> <item msgid="7126170197336963369">"Tất cả lần tải nhật ký"</item> <item msgid="7167543126036181392">"Tất cả trừ lần tải nhật ký qua đài"</item> <item msgid="5135340178556563979">"chỉ vùng đệm nhật ký kernel"</item> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 3dcf61c4d205..2fa22b4fbc42 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Nếu bạn phát <xliff:g id="SWITCHAPP">%1$s</xliff:g> hoặc thay đổi đầu ra, phiên truyền phát hiện tại sẽ dừng"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Phát <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Thay đổi đầu ra"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Ảnh động vuốt ngược dự đoán"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Cho phép sử dụng ảnh động hệ thống cho chức năng vuốt ngược dự đoán."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Cài đặt này cho phép sử dụng ảnh động hệ thống cho ảnh động cử chỉ dự đoán. Nó yêu cầu cài đặt cho mỗi ứng dụng chuyển enableOnBackInvokedCallback thành lệnh true trong tệp kê khai."</string> </resources> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index a6f738f0ac1d..e9227fd2a8e0 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -668,10 +668,13 @@ <string name="allow_turn_screen_on" msgid="6194845766392742639">"允许开启屏幕"</string> <string name="allow_turn_screen_on_description" msgid="43834403291575164">"允许应用开启屏幕。如获授权,该应用便可在您未明确表达意愿的情况下随时开启屏幕。"</string> <string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"扫描二维码"</string> - <string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"将扫描器对准下方二维码,即可开始收听"</string> + <string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"将取景框对准二维码,即可开始收听"</string> <string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"二维码的格式无效"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"要停止广播“<xliff:g id="APP_NAME">%1$s</xliff:g>”的内容吗?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"如果广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容或更改输出来源,当前的广播就会停止"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"更改输出来源"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"预测性返回手势动画"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"启用系统动画作为预测性返回手势动画。"</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"此设置将启用系统动画作为预测性手势动画。这要求在清单文件中将单个应用的 enableOnBackInvokedCallback 设为 true。"</string> </resources> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index f334cc84e484..fae79cb61a51 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -599,7 +599,7 @@ <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"移除"</string> <string name="guest_resetting" msgid="7822120170191509566">"正在重設訪客…"</string> <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"要重設訪客工作階段嗎?"</string> - <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"此操作會開始新的訪客工作階段,並刪除目前工作階段中的所有應用程式和活動"</string> + <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"此操作會開始新的訪客工作階段,並刪除目前工作階段的所有應用程式和資料"</string> <string name="guest_exit_dialog_title" msgid="1846494656849381804">"要結束訪客模式嗎?"</string> <string name="guest_exit_dialog_message" msgid="1743218864242719783">"此操作會刪除目前訪客工作階段中的所有應用程式和資料"</string> <string name="guest_exit_dialog_button" msgid="1736401897067442044">"結束"</string> @@ -612,7 +612,7 @@ <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"結束訪客模式"</string> <string name="guest_notification_ephemeral" msgid="7263252466950923871">"結束時將會刪除所有活動"</string> <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"您可以在結束時儲存或刪除活動"</string> - <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"重設即可立即刪除工作階段活動,或在結束時儲存或刪除工作階段"</string> + <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"重設可立即刪除工作階段活動,或者您可以在結束時儲存或刪除活動"</string> <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"揀相"</string> @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"如要廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止廣播目前的內容"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"變更輸出來源"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 9a4cc5b66a06..19ab135b5c68 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -674,4 +674,10 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"如果播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止播送目前的內容"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"變更輸出來源"</string> + <!-- no translation found for back_navigation_animation (8105467568421689484) --> + <skip /> + <!-- no translation found for back_navigation_animation_summary (741292224121599456) --> + <skip /> + <!-- no translation found for back_navigation_animation_dialog (8696966520944625596) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 45c4d6748d02..1f29525bda71 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -674,4 +674,7 @@ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Uma usakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g> noma ushintsha okuphumayo, ukusakaza kwakho kwamanje kuzoma"</string> <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Sakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string> <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Shintsha okuphumayo"</string> + <string name="back_navigation_animation" msgid="8105467568421689484">"Ukubikezelwa kwasemuva kopopayi"</string> + <string name="back_navigation_animation_summary" msgid="741292224121599456">"Nika amandla ukubikezela emuva kopopayi besistimu."</string> + <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Leli sethingi livumela opopayi besistimu mayelana nokuthinta okubikezelwayo kopopayi. Idinga ukusetha i-app ngayinye ku-enableOnBackInvokedCallback ukuze iqinisekise ifayela le-manifest."</string> </resources> diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java index cc4fef8399c3..7f65837d5716 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java @@ -268,9 +268,9 @@ public class AppUtils { /** * Preload the top N icons of app entry list. * - * @param context caller's context + * @param context caller's context * @param appEntries AppEntry list of ApplicationsState - * @param number the number of Top N icons of the appEntries + * @param number the number of Top N icons of the appEntries */ public static void preloadTopIcons(Context context, ArrayList<ApplicationsState.AppEntry> appEntries, int number) { @@ -286,6 +286,19 @@ public class AppUtils { } } + /** + * Returns a boolean indicating whether this app is installed or not. + * + * @param appEntry AppEntry of ApplicationsState. + * @return true if the app is in installed state. + */ + public static boolean isAppInstalled(ApplicationsState.AppEntry appEntry) { + if (appEntry == null || appEntry.info == null) { + return false; + } + return (appEntry.info.flags & ApplicationInfo.FLAG_INSTALLED) != 0; + } + private static void setAppEntryMounted(ApplicationsState.AppEntry appEntry, boolean mounted) { if (appEntry.mounted != mounted) { synchronized (appEntry) { diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java index fdb06072bbd1..6b9daa35f9ca 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java @@ -863,6 +863,30 @@ public class ApplicationsState { } } + /** + * Activate session to enable a class that implements Callbacks to receive the callback. + */ + public void activateSession() { + synchronized (mEntriesMap) { + if (!mResumed) { + mResumed = true; + mSessionsChanged = true; + } + } + } + + /** + * Deactivate session to disable a class that implements Callbacks to get the callback. + */ + public void deactivateSession() { + synchronized (mEntriesMap) { + if (mResumed) { + mResumed = false; + mSessionsChanged = true; + } + } + } + public ArrayList<AppEntry> getAllApps() { synchronized (mEntriesMap) { return new ArrayList<>(mAppEntries); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 4ee21229e364..6919cf237853 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -1376,7 +1376,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> /** * Store the member devices that are in the same coordinated set. */ - public void setMemberDevice(CachedBluetoothDevice memberDevice) { + public void addMemberDevice(CachedBluetoothDevice memberDevice) { mMemberDevices.add(memberDevice); } @@ -1393,24 +1393,24 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> * device and member devices. * * @param prevMainDevice the previous Main device, it will be added into the member device set. - * @param newMainDevie the new Main device, it will be removed from the member device set. + * @param newMainDevice the new Main device, it will be removed from the member device set. */ public void switchMemberDeviceContent(CachedBluetoothDevice prevMainDevice, - CachedBluetoothDevice newMainDevie) { + CachedBluetoothDevice newMainDevice) { // Backup from main device final BluetoothDevice tmpDevice = mDevice; final short tmpRssi = mRssi; final boolean tmpJustDiscovered = mJustDiscovered; // Set main device from sub device - mDevice = newMainDevie.mDevice; - mRssi = newMainDevie.mRssi; - mJustDiscovered = newMainDevie.mJustDiscovered; - setMemberDevice(prevMainDevice); - mMemberDevices.remove(newMainDevie); + mDevice = newMainDevice.mDevice; + mRssi = newMainDevice.mRssi; + mJustDiscovered = newMainDevice.mJustDiscovered; + addMemberDevice(prevMainDevice); + mMemberDevices.remove(newMainDevice); // Set sub device from backup - newMainDevie.mDevice = tmpDevice; - newMainDevie.mRssi = tmpRssi; - newMainDevie.mJustDiscovered = tmpJustDiscovered; + newMainDevice.mDevice = tmpDevice; + newMainDevice.mRssi = tmpRssi; + newMainDevice.mJustDiscovered = tmpJustDiscovered; fetchActiveDevices(); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java index cc56a212aea1..89e10c4b5e11 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java @@ -85,7 +85,7 @@ public class CsipDeviceManager { // Once there is other devices with the same groupId, to add new device as member // devices. if (CsipDevice != null) { - CsipDevice.setMemberDevice(newDevice); + CsipDevice.addMemberDevice(newDevice); newDevice.setName(CsipDevice.getName()); return true; } @@ -148,7 +148,7 @@ public class CsipDeviceManager { log("onGroupIdChanged: removed from UI device =" + cachedDevice + ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex); - mainDevice.setMemberDevice(cachedDevice); + mainDevice.addMemberDevice(cachedDevice); mCachedDevices.remove(i); mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice); break; diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java b/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java index 8a1e91b4dcd8..3e7481a61f89 100644 --- a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java +++ b/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java @@ -147,6 +147,7 @@ public class AvatarPickerActivity extends Activity { mWaitingForActivityResult = savedInstanceState.getBoolean(KEY_AWAITING_RESULT, false); mAdapter.mSelectedPosition = savedInstanceState.getInt(KEY_SELECTED_POSITION, AvatarAdapter.NONE); + mDoneButton.setEnabled(mAdapter.mSelectedPosition != AvatarAdapter.NONE); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/users/EditUserInfoController.java b/packages/SettingsLib/src/com/android/settingslib/users/EditUserInfoController.java index 80ee86f5e489..3b542ccea635 100644 --- a/packages/SettingsLib/src/com/android/settingslib/users/EditUserInfoController.java +++ b/packages/SettingsLib/src/com/android/settingslib/users/EditUserInfoController.java @@ -54,6 +54,7 @@ public class EditUserInfoController { private Dialog mEditUserInfoDialog; private Bitmap mSavedPhoto; + private Drawable mSavedDrawable; private EditUserPhotoController mEditUserPhotoController; private boolean mWaitingForActivityResult = false; private final String mFileAuthority; @@ -68,6 +69,7 @@ public class EditUserInfoController { } mEditUserInfoDialog = null; mSavedPhoto = null; + mSavedDrawable = null; } /** @@ -170,7 +172,8 @@ public class EditUserInfoController { private Drawable getUserIcon(Activity activity, Drawable defaultUserIcon) { if (mSavedPhoto != null) { - return CircleFramedDrawable.getInstance(activity, mSavedPhoto); + mSavedDrawable = CircleFramedDrawable.getInstance(activity, mSavedPhoto); + return mSavedDrawable; } return defaultUserIcon; } @@ -229,6 +232,6 @@ public class EditUserInfoController { EditUserPhotoController createEditUserPhotoController(Activity activity, ActivityStarter activityStarter, ImageView userPhotoView) { return new EditUserPhotoController(activity, activityStarter, userPhotoView, - mSavedPhoto, mFileAuthority); + mSavedPhoto, mSavedDrawable, mFileAuthority); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java index 5862f6095018..38cf383645aa 100644 --- a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java +++ b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java @@ -62,7 +62,7 @@ public class EditUserPhotoController { private Drawable mNewUserPhotoDrawable; public EditUserPhotoController(Activity activity, ActivityStarter activityStarter, - ImageView view, Bitmap bitmap, String fileAuthority) { + ImageView view, Bitmap savedBitmap, Drawable savedDrawable, String fileAuthority) { mActivity = activity; mActivityStarter = activityStarter; mFileAuthority = fileAuthority; @@ -71,7 +71,9 @@ public class EditUserPhotoController { mImagesDir.mkdir(); mImageView = view; mImageView.setOnClickListener(v -> showAvatarPicker()); - mNewUserPhotoBitmap = bitmap; + + mNewUserPhotoBitmap = savedBitmap; + mNewUserPhotoDrawable = savedDrawable; } /** diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppUtilsTest.java index 8e448aa0eace..994c1ee5013f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppUtilsTest.java @@ -129,6 +129,28 @@ public class AppUtilsTest { assertThat(mAppIconCacheManager.get(APP_PACKAGE_NAME, APP_UID)).isNotNull(); } + @Test + public void isAppInstalled_noAppEntry_shouldReturnFalse() { + assertThat(AppUtils.isAppInstalled(null)).isFalse(); + } + + @Test + public void isAppInstalled_hasAppEntryWithInstalledFlag_shouldReturnTrue() { + final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); + appEntry.info = new ApplicationInfo(); + appEntry.info.flags = ApplicationInfo.FLAG_INSTALLED; + + assertThat(AppUtils.isAppInstalled(appEntry)).isTrue(); + } + + @Test + public void isAppInstalled_hasAppEntryWithoutInstalledFlag_shouldReturnFalse() { + final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class); + appEntry.info = new ApplicationInfo(); + + assertThat(AppUtils.isAppInstalled(appEntry)).isFalse(); + } + private ApplicationsState.AppEntry createAppEntry(ApplicationInfo appInfo, int id) { ApplicationsState.AppEntry appEntry = new ApplicationsState.AppEntry(mContext, appInfo, id); appEntry.label = "label"; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java index 298ee90d311d..bef1d9cbcde1 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java @@ -40,7 +40,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import java.util.Collection; -import java.util.HashMap; import java.util.Map; @RunWith(RobolectricTestRunner.class) @@ -503,8 +502,8 @@ public class CachedBluetoothDeviceManagerTest { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1); CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2); CachedBluetoothDevice cachedDevice3 = mCachedDeviceManager.addDevice(mDevice3); - cachedDevice1.setMemberDevice(cachedDevice2); - cachedDevice1.setMemberDevice(cachedDevice3); + cachedDevice1.addMemberDevice(cachedDevice2); + cachedDevice1.addMemberDevice(cachedDevice3); assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice2); assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice3); @@ -524,7 +523,7 @@ public class CachedBluetoothDeviceManagerTest { CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2); cachedDevice1.setGroupId(1); cachedDevice2.setGroupId(1); - cachedDevice1.setMemberDevice(cachedDevice2); + cachedDevice1.addMemberDevice(cachedDevice2); // Call onDeviceUnpaired for the one in mCachedDevices. mCachedDeviceManager.onDeviceUnpaired(cachedDevice1); @@ -541,7 +540,7 @@ public class CachedBluetoothDeviceManagerTest { CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2); cachedDevice1.setGroupId(1); cachedDevice2.setGroupId(1); - cachedDevice1.setMemberDevice(cachedDevice2); + cachedDevice1.addMemberDevice(cachedDevice2); // Call onDeviceUnpaired for the one in mCachedDevices. mCachedDeviceManager.onDeviceUnpaired(cachedDevice2); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java index 61a28aab061f..9abb27e68398 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.view.LayoutInflater; +import android.view.View; import android.widget.TextView; import androidx.preference.PreferenceViewHolder; @@ -61,7 +62,7 @@ public class FooterPreferenceTest { mFooterPreference.onBindViewHolder(holder); assertThat(((TextView) holder.findViewById( - R.id.settingslib_learn_more)).getText().toString()) + R.id.settingslib_learn_more)).getText().toString()) .isEqualTo("Custom learn more"); } @@ -86,4 +87,11 @@ public class FooterPreferenceTest { assertThat(mFooterPreference.mLearnMoreListener).isNotNull(); } + + @Test + public void setIconVisibility_shouldReturnSameVisibilityType() { + mFooterPreference.setIconVisibility(View.GONE); + + assertThat(mFooterPreference.mIconVisibility).isEqualTo(View.GONE); + } } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 0c6d40aa9910..5088533ccdd8 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -1074,13 +1074,63 @@ public class SettingsBackupAgent extends BackupAgentHelper { if (DEBUG) Log.d(TAG, "Successfully unMarshaled SoftApConfiguration "); // Depending on device hardware, we may need to notify the user of a setting change SoftApConfiguration storedConfig = mWifiManager.getSoftApConfiguration(); - if (!storedConfig.equals(configInCloud)) { + + if (isNeedToNotifyUserConfigurationHasChanged(configInCloud, storedConfig)) { Log.d(TAG, "restored ap configuration requires a conversion, notify the user"); WifiSoftApConfigChangedNotifier.notifyUserOfConfigConversion(this); } } } + private boolean isNeedToNotifyUserConfigurationHasChanged(SoftApConfiguration configInCloud, + SoftApConfiguration storedConfig) { + // Check if the cloud configuration was modified when restored to the device. + // All elements of the configuration are compared except: + // 1. Persistent randomized MAC address (which is per device) + // 2. The flag indicating whether the configuration is "user modified" + return !(Objects.equals(configInCloud.getWifiSsid(), storedConfig.getWifiSsid()) + && Objects.equals(configInCloud.getBssid(), storedConfig.getBssid()) + && Objects.equals(configInCloud.getPassphrase(), storedConfig.getPassphrase()) + && configInCloud.isHiddenSsid() == storedConfig.isHiddenSsid() + && configInCloud.getChannels().toString().equals( + storedConfig.getChannels().toString()) + && configInCloud.getSecurityType() == storedConfig.getSecurityType() + && configInCloud.getMaxNumberOfClients() == storedConfig.getMaxNumberOfClients() + && configInCloud.isAutoShutdownEnabled() == storedConfig.isAutoShutdownEnabled() + && configInCloud.getShutdownTimeoutMillis() + == storedConfig.getShutdownTimeoutMillis() + && configInCloud.isClientControlByUserEnabled() + == storedConfig.isClientControlByUserEnabled() + && Objects.equals(configInCloud.getBlockedClientList(), + storedConfig.getBlockedClientList()) + && Objects.equals(configInCloud.getAllowedClientList(), + storedConfig.getAllowedClientList()) + && configInCloud.getMacRandomizationSetting() + == storedConfig.getMacRandomizationSetting() + && configInCloud.isBridgedModeOpportunisticShutdownEnabled() + == storedConfig.isBridgedModeOpportunisticShutdownEnabled() + && configInCloud.isIeee80211axEnabled() == storedConfig.isIeee80211axEnabled() + && configInCloud.isIeee80211beEnabled() == storedConfig.isIeee80211beEnabled() + && configInCloud.getBridgedModeOpportunisticShutdownTimeoutMillis() + == storedConfig.getBridgedModeOpportunisticShutdownTimeoutMillis() + && Objects.equals(configInCloud.getVendorElements(), + storedConfig.getVendorElements()) + && (configInCloud.getPersistentRandomizedMacAddress() != null + ? Objects.equals(configInCloud.getPersistentRandomizedMacAddress(), + storedConfig.getPersistentRandomizedMacAddress()) : true) + && Arrays.equals(configInCloud.getAllowedAcsChannels( + SoftApConfiguration.BAND_2GHZ), + storedConfig.getAllowedAcsChannels(SoftApConfiguration.BAND_2GHZ)) + && Arrays.equals(configInCloud.getAllowedAcsChannels( + SoftApConfiguration.BAND_5GHZ), + storedConfig.getAllowedAcsChannels(SoftApConfiguration.BAND_5GHZ)) + && Arrays.equals(configInCloud.getAllowedAcsChannels( + SoftApConfiguration.BAND_6GHZ), + storedConfig.getAllowedAcsChannels(SoftApConfiguration.BAND_6GHZ)) + && configInCloud.getMaxChannelBandwidth() == storedConfig.getMaxChannelBandwidth() + ); + } + private byte[] getNetworkPolicies() { NetworkPolicyManager networkPolicyManager = (NetworkPolicyManager) getSystemService(NETWORK_POLICY_SERVICE); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index aadfcea150f7..a6edb0f0e2e3 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -5509,16 +5509,7 @@ public class SettingsProvider extends ContentProvider { currentVersion = 209; } if (currentVersion == 209) { - // Version 209: Enable enforcement of - // android.Manifest.permission#POST_NOTIFICATIONS in order for applications - // to post notifications. - final SettingsState secureSettings = getSecureSettingsLocked(userId); - secureSettings.insertSettingLocked( - Secure.NOTIFICATION_PERMISSION_ENABLED, - /* enabled= */ "1", - /* tag= */ null, - /* makeDefault= */ false, - SettingsState.SYSTEM_PACKAGE_NAME); + // removed now that feature is enabled for everyone currentVersion = 210; } diff --git a/packages/Shell/res/values-hy/strings.xml b/packages/Shell/res/values-hy/strings.xml index 33f76f0da8f3..ebe4cd9c61ed 100644 --- a/packages/Shell/res/values-hy/strings.xml +++ b/packages/Shell/res/values-hy/strings.xml @@ -23,11 +23,11 @@ <string name="bugreport_updating_title" msgid="4423539949559634214">"Տվյալների ավելացում վրիպակի զեկույցում"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Խնդրում ենք սպասել…"</string> <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Վրիպակների մասին հաշվետվությունը շուտով կստանաք հեռախոսին"</string> - <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Ընտրեք՝ վրիպակի զեկույցն ուղարկելու համար"</string> - <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Հպեք՝ վրիպակի զեկույցը տրամադրելու համար"</string> - <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Ընտրեք՝ վրիպակի զեկույցն առանց սքրինշոթի ուղարկելու համար կամ սպասեք սքրինշոթի ստեղծմանը"</string> - <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Հպեք՝ վրիպակի զեկույցն առանց սքրինշոթի ուղարկելու համար կամ սպասեք սքրինշոթի ստեղծմանը"</string> - <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Հպեք՝ վրիպակի զեկույցն առանց սքրինշոթի ուղարկելու համար կամ սպասեք սքրինշոթի ստեղծմանը"</string> + <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Ընտրեք՝ վրիպակի մասին հաղորդումն ուղարկելու համար"</string> + <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Հպեք՝ վրիպակի մասին հաղորդմամբ կիսվելու համար"</string> + <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Ընտրեք՝ վրիպակի մասին հաղորդումն առանց սքրինշոթի ուղարկելու համար կամ սպասեք սքրինշոթի ստեղծմանը"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Հպեք՝ վրիպակի մասին հաղորդումն առանց սքրինշոթի ուղարկելու համար կամ սպասեք սքրինշոթի ստեղծմանը"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Հպեք՝ վրիպակի մասին հաղորդումն առանց սքրինշոթի ուղարկելու համար կամ սպասեք սքրինշոթի ստեղծմանը"</string> <string name="bugreport_confirm" msgid="5917407234515812495">"Վրիպակի զեկույցները պարունակում են տվյալներ համակարգի տարբեր մատյաններից և կարող են ներառել տեղեկություններ, որոնք դուք գաղտնի եք համարում (օրինակ՝ հավելվածի օգտագործման կամ տեղադրության մասին): Վրիպակի զեկույցները տրամադրեք միայն վստահելի մարդկանց և հավելվածներին:"</string> <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Այլևս ցույց չտալ"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Վրիպակների հաշվետվություններ"</string> @@ -43,5 +43,5 @@ <string name="bugreport_info_title" msgid="2306030793918239804">"Վրիպակի զեկույցի վերնագիրը"</string> <string name="bugreport_info_description" msgid="5072835127481627722">"Վրիպակի զեկույցի ամփոփագիրը"</string> <string name="save" msgid="4781509040564835759">"Պահել"</string> - <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Տրամադրե՞լ վրիպակի զեկույցը"</string> + <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"Կիսվե՞լ վրիպակի մասին հաղորդմամբ"</string> </resources> diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 290ce345694e..4d0888ab8d2d 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -323,6 +323,8 @@ <!-- To read safety center status --> <uses-permission android:name="android.permission.READ_SAFETY_CENTER_STATUS" /> + <uses-permission android:name="android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS" /> + <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" /> <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" /> <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" /> diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml index ca1e6b2f27db..145bd2b9f6d4 100644 --- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml @@ -21,7 +21,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"請輸入 PIN"</string> - <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"請畫出圖形"</string> + <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"請畫出圖案"</string> <string name="keyguard_enter_your_password" msgid="7225626204122735501">"請輸入密碼"</string> <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"SIM 卡無效。"</string> <string name="keyguard_charged" msgid="5478247181205188995">"已完成充電"</string> @@ -50,7 +50,7 @@ <string name="error_disable_esim_title" msgid="3802652622784813119">"無法停用 eSIM 卡"</string> <string name="error_disable_esim_msg" msgid="2441188596467999327">"發生錯誤,因此無法停用此 eSIM 卡。"</string> <string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Enter 鍵 (輸入)"</string> - <string name="kg_wrong_pattern" msgid="5907301342430102842">"圖形錯誤"</string> + <string name="kg_wrong_pattern" msgid="5907301342430102842">"圖案錯誤"</string> <string name="kg_wrong_password" msgid="4143127991071670512">"密碼錯誤"</string> <string name="kg_wrong_pin" msgid="4160978845968732624">"PIN 碼錯誤"</string> <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{請在 # 秒後再試一次。}other{請在 # 秒後再試一次。}}"</string> @@ -66,7 +66,7 @@ <string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK 碼應由 8 個或以上數字組成。"</string> <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> - <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> + <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string> <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM 卡 PIN 碼不正確,您現在必須聯絡流動網絡供應商為您的裝置解鎖。"</string> <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026"> <item quantity="other">SIM 卡的 PIN 碼不正確,您還有 <xliff:g id="NUMBER_1">%d</xliff:g> 次輸入機會。</item> @@ -81,10 +81,10 @@ <string name="kg_password_puk_failed" msgid="6778867411556937118">"無法使用 SIM 卡 PUK 碼解鎖!"</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"轉換輸入方法"</string> <string name="airplane_mode" msgid="2528005343938497866">"飛行模式"</string> - <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"裝置重新啟動後,必須畫出上鎖圖形才能使用"</string> + <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"裝置重新啟動後,必須畫出上鎖圖案才能使用"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"裝置重新啟動後,必須輸入 PIN 碼才能使用"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"裝置重新啟動後,必須輸入密碼才能使用"</string> - <string name="kg_prompt_reason_timeout_pattern" msgid="9170360502528959889">"請務必畫出上鎖圖形,以進一步確保安全"</string> + <string name="kg_prompt_reason_timeout_pattern" msgid="9170360502528959889">"請務必畫出上鎖圖案,以進一步確保安全"</string> <string name="kg_prompt_reason_timeout_pin" msgid="5945186097160029201">"請務必輸入 PIN 碼,以進一步確保安全"</string> <string name="kg_prompt_reason_timeout_password" msgid="2258263949430384278">"請務必輸入密碼,以進一步確保安全"</string> <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"裝置已由管理員鎖定"</string> diff --git a/packages/SystemUI/res-product/values-af/strings.xml b/packages/SystemUI/res-product/values-af/strings.xml index 1d335c3dff9b..d86cc1deda98 100644 --- a/packages/SystemUI/res-product/values-af/strings.xml +++ b/packages/SystemUI/res-product/values-af/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ontsluit jou foon vir meer opsies"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ontsluit jou tablet vir meer opsies"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ontsluit jou toestel vir meer opsies"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-am/strings.xml b/packages/SystemUI/res-product/values-am/strings.xml index c11e85689f69..6b777e26e3c1 100644 --- a/packages/SystemUI/res-product/values-am/strings.xml +++ b/packages/SystemUI/res-product/values-am/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ለተጨማሪ አማራጮች የእርስዎን ስልክ ይክፈቱ"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ለተጨማሪ አማራጮች የእርስዎን ጡባዊ ይክፈቱ"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ለተጨማሪ አማራጮች የእርስዎን መሣሪያ ይክፈቱ"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ar/strings.xml b/packages/SystemUI/res-product/values-ar/strings.xml index a13136fbd1e2..1687349b619b 100644 --- a/packages/SystemUI/res-product/values-ar/strings.xml +++ b/packages/SystemUI/res-product/values-ar/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"يمكنك فتح قفل هاتفك للوصول إلى مزيد من الخيارات."</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"يمكنك فتح قفل جهازك اللوحي للوصول إلى مزيد من الخيارات."</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"يمكنك فتح قفل جهازك للوصول إلى مزيد من الخيارات."</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-as/strings.xml b/packages/SystemUI/res-product/values-as/strings.xml index aa9cb2dee679..0745341db2a7 100644 --- a/packages/SystemUI/res-product/values-as/strings.xml +++ b/packages/SystemUI/res-product/values-as/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"অধিক বিকল্পৰ বাবে আপোনাৰ ফ’নটো আনলক কৰক"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"অধিক বিকল্পৰ বাবে আপোনাৰ টেবলেটটো আনলক কৰক"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"অধিক বিকল্পৰ বাবে আপোনাৰ ডিভাইচটো আনলক কৰক"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-az/strings.xml b/packages/SystemUI/res-product/values-az/strings.xml index c0668dbcea07..76a8f26f1a02 100644 --- a/packages/SystemUI/res-product/values-az/strings.xml +++ b/packages/SystemUI/res-product/values-az/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Daha çox seçim üçün telefonu kiliddən çıxarın"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Daha çox seçim üçün planşeti kiliddən çıxarın"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Daha çox seçim üçün cihazı kiliddən çıxarın"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml index 7a27dd0fd9b6..29889d173989 100644 --- a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Otključajte telefon za još opcija"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Otključajte tablet za još opcija"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Otključajte uređaj za još opcija"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-be/strings.xml b/packages/SystemUI/res-product/values-be/strings.xml index 4fd7cc047246..1d5a84a3bd7d 100644 --- a/packages/SystemUI/res-product/values-be/strings.xml +++ b/packages/SystemUI/res-product/values-be/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Каб адкрыць іншыя параметры, разблакіруйце тэлефон"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Каб адкрыць іншыя параметры, разблакіруйце планшэт"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Каб адкрыць іншыя параметры, разблакіруйце прыладу"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-bg/strings.xml b/packages/SystemUI/res-product/values-bg/strings.xml index cfdab241f45f..0638c12f54d7 100644 --- a/packages/SystemUI/res-product/values-bg/strings.xml +++ b/packages/SystemUI/res-product/values-bg/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Отключете телефона си за още опции"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Отключете таблета си за още опции"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Отключете устройството си за още опции"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-bn/strings.xml b/packages/SystemUI/res-product/values-bn/strings.xml index 214dd45040fc..2f0651ca0edc 100644 --- a/packages/SystemUI/res-product/values-bn/strings.xml +++ b/packages/SystemUI/res-product/values-bn/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"আরও বিকল্প দেখতে আপনার ফোন আনলক করুন"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"আরও বিকল্প দেখতে আপনার ট্যাবলেট আনলক করুন"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"আরও বিকল্প দেখতে আপনার ডিভাইস আনলক করুন"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-bs/strings.xml b/packages/SystemUI/res-product/values-bs/strings.xml index ed5caae511fa..e0a2a3b800db 100644 --- a/packages/SystemUI/res-product/values-bs/strings.xml +++ b/packages/SystemUI/res-product/values-bs/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Otključajte telefon za više opcija"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Otključajte tablet za više opcija"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Otključajte uređaj za više opcija"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ca/strings.xml b/packages/SystemUI/res-product/values-ca/strings.xml index 44417927a1dd..777cb794d469 100644 --- a/packages/SystemUI/res-product/values-ca/strings.xml +++ b/packages/SystemUI/res-product/values-ca/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueja el teu telèfon per veure més opcions"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueja la teva tauleta per veure més opcions"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueja el teu dispositiu per veure més opcions"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-cs/strings.xml b/packages/SystemUI/res-product/values-cs/strings.xml index aa6ba7212e9c..8e0b656b8744 100644 --- a/packages/SystemUI/res-product/values-cs/strings.xml +++ b/packages/SystemUI/res-product/values-cs/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Chcete-li zobrazit další možnosti, odemkněte telefon"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Chcete-li zobrazit další možnosti, odemkněte tablet"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Chcete-li zobrazit další možnosti, odemkněte zařízení"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-da/strings.xml b/packages/SystemUI/res-product/values-da/strings.xml index 5b2112ec7d70..7c6586e9eb55 100644 --- a/packages/SystemUI/res-product/values-da/strings.xml +++ b/packages/SystemUI/res-product/values-da/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Lås din telefon op for at se flere valgmuligheder"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Lås din tablet op for at se flere valgmuligheder"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Lås din enhed op for at se flere valgmuligheder"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-de/strings.xml b/packages/SystemUI/res-product/values-de/strings.xml index a84413d825c2..b28704cb1189 100644 --- a/packages/SystemUI/res-product/values-de/strings.xml +++ b/packages/SystemUI/res-product/values-de/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Entsperre dein Smartphone für weitere Optionen"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Entsperre dein Tablet für weitere Optionen"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Entsperre dein Gerät für weitere Optionen"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-el/strings.xml b/packages/SystemUI/res-product/values-el/strings.xml index 8dd9ec25ccb1..6438653066a4 100644 --- a/packages/SystemUI/res-product/values-el/strings.xml +++ b/packages/SystemUI/res-product/values-el/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ξεκλειδώστε το τηλέφωνό σας για περισσότερες επιλογές"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ξεκλειδώστε το tablet για περισσότερες επιλογές"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ξεκλειδώστε τη συσκευή σας για περισσότερες επιλογές"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-en-rAU/strings.xml b/packages/SystemUI/res-product/values-en-rAU/strings.xml index 3de7b654ead0..04e63f5eb428 100644 --- a/packages/SystemUI/res-product/values-en-rAU/strings.xml +++ b/packages/SystemUI/res-product/values-en-rAU/strings.xml @@ -43,4 +43,6 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string> + <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Playing on this phone"</string> + <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Playing on this tablet"</string> </resources> diff --git a/packages/SystemUI/res-product/values-en-rCA/strings.xml b/packages/SystemUI/res-product/values-en-rCA/strings.xml index 3de7b654ead0..04e63f5eb428 100644 --- a/packages/SystemUI/res-product/values-en-rCA/strings.xml +++ b/packages/SystemUI/res-product/values-en-rCA/strings.xml @@ -43,4 +43,6 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string> + <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Playing on this phone"</string> + <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Playing on this tablet"</string> </resources> diff --git a/packages/SystemUI/res-product/values-en-rGB/strings.xml b/packages/SystemUI/res-product/values-en-rGB/strings.xml index 3de7b654ead0..04e63f5eb428 100644 --- a/packages/SystemUI/res-product/values-en-rGB/strings.xml +++ b/packages/SystemUI/res-product/values-en-rGB/strings.xml @@ -43,4 +43,6 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string> + <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Playing on this phone"</string> + <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Playing on this tablet"</string> </resources> diff --git a/packages/SystemUI/res-product/values-en-rIN/strings.xml b/packages/SystemUI/res-product/values-en-rIN/strings.xml index 3de7b654ead0..04e63f5eb428 100644 --- a/packages/SystemUI/res-product/values-en-rIN/strings.xml +++ b/packages/SystemUI/res-product/values-en-rIN/strings.xml @@ -43,4 +43,6 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string> + <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Playing on this phone"</string> + <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Playing on this tablet"</string> </resources> diff --git a/packages/SystemUI/res-product/values-en-rXC/strings.xml b/packages/SystemUI/res-product/values-en-rXC/strings.xml index 022c5b390e7b..aa895e1364e2 100644 --- a/packages/SystemUI/res-product/values-en-rXC/strings.xml +++ b/packages/SystemUI/res-product/values-en-rXC/strings.xml @@ -43,4 +43,6 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string> + <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Playing on this phone"</string> + <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Playing on this tablet"</string> </resources> diff --git a/packages/SystemUI/res-product/values-es-rUS/strings.xml b/packages/SystemUI/res-product/values-es-rUS/strings.xml index b333479ad264..b0083521dae7 100644 --- a/packages/SystemUI/res-product/values-es-rUS/strings.xml +++ b/packages/SystemUI/res-product/values-es-rUS/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloquea el teléfono para ver más opciones"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloquea la tablet para ver más opciones"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloquea el dispositivo para ver más opciones"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-es/strings.xml b/packages/SystemUI/res-product/values-es/strings.xml index 03ff2ff8a2d9..5161f603c1a7 100644 --- a/packages/SystemUI/res-product/values-es/strings.xml +++ b/packages/SystemUI/res-product/values-es/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloquea el teléfono para ver más opciones"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloquea el tablet para ver más opciones"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloquea el dispositivo para ver más opciones"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-et/strings.xml b/packages/SystemUI/res-product/values-et/strings.xml index 01060cb6dc9b..b178be30f548 100644 --- a/packages/SystemUI/res-product/values-et/strings.xml +++ b/packages/SystemUI/res-product/values-et/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Lisavalikute nägemiseks avage oma telefon"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Lisavalikute nägemiseks avage oma tahvelarvuti"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Lisavalikute nägemiseks avage oma seade"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-eu/strings.xml b/packages/SystemUI/res-product/values-eu/strings.xml index e6cf28d2fac0..5283d4a5b2ef 100644 --- a/packages/SystemUI/res-product/values-eu/strings.xml +++ b/packages/SystemUI/res-product/values-eu/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desblokeatu telefonoa aukera gehiago ikusteko"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desblokeatu tableta aukera gehiago ikusteko"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desblokeatu gailua aukera gehiago ikusteko"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-fa/strings.xml b/packages/SystemUI/res-product/values-fa/strings.xml index cd98ef60994d..f880779acdad 100644 --- a/packages/SystemUI/res-product/values-fa/strings.xml +++ b/packages/SystemUI/res-product/values-fa/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"برای گزینههای بیشتر، قفل تلفن را باز کنید"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"برای گزینههای بیشتر، قفل رایانه لوحی را باز کنید"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"برای گزینههای بیشتر، قفل دستگاه را باز کنید"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-fi/strings.xml b/packages/SystemUI/res-product/values-fi/strings.xml index 4001b30eb4d9..dc3180b1b356 100644 --- a/packages/SystemUI/res-product/values-fi/strings.xml +++ b/packages/SystemUI/res-product/values-fi/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Avaa puhelimen lukitus, niin näet enemmän vaihtoehtoja"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Avaa tabletin lukitus, niin näet enemmän vaihtoehtoja"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Avaa laitteen lukitus, niin näet enemmän vaihtoehtoja"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-fr-rCA/strings.xml b/packages/SystemUI/res-product/values-fr-rCA/strings.xml index 0849256bb53a..903eb6ba4a5b 100644 --- a/packages/SystemUI/res-product/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res-product/values-fr-rCA/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Déverrouillez votre téléphone pour afficher davantage d\'options"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Déverrouillez votre tablette pour afficher davantage d\'options"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Déverrouillez votre appareil pour afficher davantage d\'options"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-fr/strings.xml b/packages/SystemUI/res-product/values-fr/strings.xml index 1bbb759046e1..193f03902cbf 100644 --- a/packages/SystemUI/res-product/values-fr/strings.xml +++ b/packages/SystemUI/res-product/values-fr/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Déverrouillez votre téléphone pour obtenir plus d\'options"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Déverrouillez votre tablette pour obtenir plus d\'options"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Déverrouillez votre appareil pour obtenir plus d\'options"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-gl/strings.xml b/packages/SystemUI/res-product/values-gl/strings.xml index 6f034fb369d9..4a1fc4a4affa 100644 --- a/packages/SystemUI/res-product/values-gl/strings.xml +++ b/packages/SystemUI/res-product/values-gl/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloquea o teléfono para ver máis opcións"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloquea a tableta para ver máis opcións"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloquea o dispositivo para ver máis opcións"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-gu/strings.xml b/packages/SystemUI/res-product/values-gu/strings.xml index 9839b42919e4..c8e2f808c30e 100644 --- a/packages/SystemUI/res-product/values-gu/strings.xml +++ b/packages/SystemUI/res-product/values-gu/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"વધુ વિકલ્પો માટે તમારા ફોનને અનલૉક કરો"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"વધુ વિકલ્પો માટે તમારા ટૅબ્લેટને અનલૉક કરો"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"વધુ વિકલ્પો માટે તમારા ડિવાઇસને અનલૉક કરો"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-hi/strings.xml b/packages/SystemUI/res-product/values-hi/strings.xml index 83c67e2fc724..f83e965db433 100644 --- a/packages/SystemUI/res-product/values-hi/strings.xml +++ b/packages/SystemUI/res-product/values-hi/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ज़्यादा विकल्प देखने के लिए, अपना फ़ोन अनलॉक करें"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ज़्यादा विकल्प देखने के लिए, अपना टैबलेट अनलॉक करें"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ज़्यादा विकल्प देखने के लिए, अपना डिवाइस अनलॉक करें"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-hr/strings.xml b/packages/SystemUI/res-product/values-hr/strings.xml index 13f0023deac4..6deccaa9dcdf 100644 --- a/packages/SystemUI/res-product/values-hr/strings.xml +++ b/packages/SystemUI/res-product/values-hr/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Za više opcija otključajte telefon"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Za više opcija otključajte tablet"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Za više opcija otključajte uređaj"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-hu/strings.xml b/packages/SystemUI/res-product/values-hu/strings.xml index 743e2082dd81..ad53a37a83c6 100644 --- a/packages/SystemUI/res-product/values-hu/strings.xml +++ b/packages/SystemUI/res-product/values-hu/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"További lehetőségekért oldja fel a telefont"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"További lehetőségekért oldja fel a táblagépet"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"További lehetőségekért oldja fel az eszközt"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-hy/strings.xml b/packages/SystemUI/res-product/values-hy/strings.xml index f245562d541a..9997933a50c5 100644 --- a/packages/SystemUI/res-product/values-hy/strings.xml +++ b/packages/SystemUI/res-product/values-hy/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ապակողպեք ձեր հեռախոսը՝ լրացուցիչ կարգավորումները տեսնելու համար"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ապակողպեք ձեր պլանշետը՝ լրացուցիչ կարգավորումները տեսնելու համար"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ապակողպեք ձեր սարքը՝ լրացուցիչ կարգավորումները տեսնելու համար"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-in/strings.xml b/packages/SystemUI/res-product/values-in/strings.xml index 1451e2c063c9..5cf18bf2eb80 100644 --- a/packages/SystemUI/res-product/values-in/strings.xml +++ b/packages/SystemUI/res-product/values-in/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Buka kunci ponsel untuk melihat opsi lainnya"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Buka kunci tablet untuk melihat opsi lainnya"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Buka kunci perangkat untuk melihat opsi lainnya"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-is/strings.xml b/packages/SystemUI/res-product/values-is/strings.xml index 32f6e21e124f..c33522808a92 100644 --- a/packages/SystemUI/res-product/values-is/strings.xml +++ b/packages/SystemUI/res-product/values-is/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Taktu símann úr lás til að fá fleiri valkosti"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Taktu spjaldtölvuna úr lás til að fá fleiri valkosti"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Taktu tækið úr lás til að fá fleiri valkosti"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-it/strings.xml b/packages/SystemUI/res-product/values-it/strings.xml index 3403f3106678..208b2c54ca1b 100644 --- a/packages/SystemUI/res-product/values-it/strings.xml +++ b/packages/SystemUI/res-product/values-it/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Sblocca il telefono per visualizzare altre opzioni"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Sblocca il tablet per visualizzare altre opzioni"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Sblocca il dispositivo per visualizzare altre opzioni"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-iw/strings.xml b/packages/SystemUI/res-product/values-iw/strings.xml index a5c7aaa9064f..06c26e626113 100644 --- a/packages/SystemUI/res-product/values-iw/strings.xml +++ b/packages/SystemUI/res-product/values-iw/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"לאפשרויות נוספות, יש לבטל את נעילת הטלפון"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"לאפשרויות נוספות, יש לבטל את נעילת הטאבלט"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"לאפשרויות נוספות, יש לבטל את נעילת המכשיר"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ja/strings.xml b/packages/SystemUI/res-product/values-ja/strings.xml index 0e7497aaa354..31ee7f34acee 100644 --- a/packages/SystemUI/res-product/values-ja/strings.xml +++ b/packages/SystemUI/res-product/values-ja/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"スマートフォンのロックを解除してその他のオプションを表示する"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"タブレットのロックを解除してその他のオプションを表示する"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"デバイスのロックを解除してその他のオプションを表示する"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ka/strings.xml b/packages/SystemUI/res-product/values-ka/strings.xml index 3d04a3c73a01..1b496ccddfb2 100644 --- a/packages/SystemUI/res-product/values-ka/strings.xml +++ b/packages/SystemUI/res-product/values-ka/strings.xml @@ -43,4 +43,6 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"მეტი ვარიანტის სანახავად განბლოკეთ თქვენი ტელეფონი"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"მეტი ვარიანტის სანახავად განბლოკეთ თქვენი ტაბლეტი"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"მეტი ვარიანტის სანახავად განბლოკეთ თქვენი მოწყობილობა"</string> + <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"უკრავს ტელეფონზე"</string> + <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"უკრავს ამ ტაბლეტზე"</string> </resources> diff --git a/packages/SystemUI/res-product/values-kk/strings.xml b/packages/SystemUI/res-product/values-kk/strings.xml index 2629667d00ee..4ba81a0976e2 100644 --- a/packages/SystemUI/res-product/values-kk/strings.xml +++ b/packages/SystemUI/res-product/values-kk/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Басқа опцияларды көру үшін телефон құлпын ашыңыз."</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Басқа опцияларды көру үшін планшет құлпын ашыңыз."</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Басқа опцияларды көру үшін құрылғы құлпын ашыңыз."</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-km/strings.xml b/packages/SystemUI/res-product/values-km/strings.xml index 0a840edc9503..9659cedf18a8 100644 --- a/packages/SystemUI/res-product/values-km/strings.xml +++ b/packages/SystemUI/res-product/values-km/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ដោះសោទូរសព្ទរបស់អ្នកសម្រាប់ជម្រើសច្រើនទៀត"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ដោះសោថេប្លេតរបស់អ្នកសម្រាប់ជម្រើសច្រើនទៀត"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ដោះសោឧបករណ៍របស់អ្នកសម្រាប់ជម្រើសច្រើនទៀត"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-kn/strings.xml b/packages/SystemUI/res-product/values-kn/strings.xml index 1b0f8bd127aa..47a1e7a93e85 100644 --- a/packages/SystemUI/res-product/values-kn/strings.xml +++ b/packages/SystemUI/res-product/values-kn/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ko/strings.xml b/packages/SystemUI/res-product/values-ko/strings.xml index 3629f2f3761b..eae3d6bcabd8 100644 --- a/packages/SystemUI/res-product/values-ko/strings.xml +++ b/packages/SystemUI/res-product/values-ko/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"더 많은 옵션을 확인하려면 휴대전화를 잠금 해제하세요."</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"더 많은 옵션을 확인하려면 태블릿을 잠금 해제하세요."</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"더 많은 옵션을 확인하려면 기기를 잠금 해제하세요."</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ky/strings.xml b/packages/SystemUI/res-product/values-ky/strings.xml index 00265a187ddf..0663847b2768 100644 --- a/packages/SystemUI/res-product/values-ky/strings.xml +++ b/packages/SystemUI/res-product/values-ky/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Дагы башка параметрлерди көрүү үчүн телефонуңуздун кулпусун ачыңыз"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Дагы башка параметрлерди көрүү үчүн планшетиңиздин кулпусун ачыңыз"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Дагы башка параметрлерди көрүү үчүн түзмөгүңүздүн кулпусун ачыңыз"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-lo/strings.xml b/packages/SystemUI/res-product/values-lo/strings.xml index 2b262e7008f5..e56bb2b69e5c 100644 --- a/packages/SystemUI/res-product/values-lo/strings.xml +++ b/packages/SystemUI/res-product/values-lo/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ປົດລັອກໂທລະສັບຂອງທ່ານເພື່ອໃຊ້ຕົວເລືອກເພີ່ມເຕີມ"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ປົດລັອກແທັບເລັດຂອງທ່ານເພື່ອໃຊ້ຕົວເລືອກເພີ່ມເຕີມ"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ປົດລັອກອຸປະກອນຂອງທ່ານເພື່ອໃຊ້ຕົວເລືອກເພີ່ມເຕີມ"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-lt/strings.xml b/packages/SystemUI/res-product/values-lt/strings.xml index 8ac5895ce065..10263f67ecf9 100644 --- a/packages/SystemUI/res-product/values-lt/strings.xml +++ b/packages/SystemUI/res-product/values-lt/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Atrakinkite telefoną, kad galėtumėte naudoti daugiau parinkčių"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Atrakinkite planšetinį kompiuterį, kad galėtumėte naudoti daugiau parinkčių"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Atrakinkite įrenginį, kad galėtumėte naudoti daugiau parinkčių"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-lv/strings.xml b/packages/SystemUI/res-product/values-lv/strings.xml index 174f5d215634..7dbac1955162 100644 --- a/packages/SystemUI/res-product/values-lv/strings.xml +++ b/packages/SystemUI/res-product/values-lv/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Atbloķējiet tālruni, lai skatītu citas opcijas."</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Atbloķējiet planšetdatoru, lai skatītu citas opcijas."</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Atbloķējiet ierīci, lai skatītu citas opcijas."</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-mk/strings.xml b/packages/SystemUI/res-product/values-mk/strings.xml index 86ff8d1c9c7a..2fbc0154a757 100644 --- a/packages/SystemUI/res-product/values-mk/strings.xml +++ b/packages/SystemUI/res-product/values-mk/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Отклучето го вашиот телефон за повеќе опции"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Отклучето го вашиот таблет за повеќе опции"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Отклучето го вашиот уред за повеќе опции"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ml/strings.xml b/packages/SystemUI/res-product/values-ml/strings.xml index fc322d6110e5..99ab7734c1b1 100644 --- a/packages/SystemUI/res-product/values-ml/strings.xml +++ b/packages/SystemUI/res-product/values-ml/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് നിങ്ങളുടെ ഫോൺ അൺലോക്ക് ചെയ്യുക"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് നിങ്ങളുടെ ടാബ്ലെറ്റ് അൺലോക്ക് ചെയ്യുക"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് നിങ്ങളുടെ ഉപകരണം അൺലോക്ക് ചെയ്യുക"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-mn/strings.xml b/packages/SystemUI/res-product/values-mn/strings.xml index 0b47eb06da30..730bbc815196 100644 --- a/packages/SystemUI/res-product/values-mn/strings.xml +++ b/packages/SystemUI/res-product/values-mn/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Бусад сонголтыг харахын тулд утасныхаа түгжээг тайлна уу"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Бусад сонголтыг харахын тулд таблетынхаа түгжээг тайлна уу"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Бусад сонголтыг харахын тулд төхөөрөмжийнхөө түгжээг тайлна уу"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-mr/strings.xml b/packages/SystemUI/res-product/values-mr/strings.xml index c9cd4ba8442b..22731472bcdb 100644 --- a/packages/SystemUI/res-product/values-mr/strings.xml +++ b/packages/SystemUI/res-product/values-mr/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"आणखी पर्यायांसाठी तुमचा फोन अनलॉक करा"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"आणखी पर्यायांसाठी तुमचा टॅबलेट अनलॉक करा"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"आणखी पर्यायांसाठी तुमचे डिव्हाइस अनलॉक करा"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ms/strings.xml b/packages/SystemUI/res-product/values-ms/strings.xml index ded2b3d1f89d..1600097ebfba 100644 --- a/packages/SystemUI/res-product/values-ms/strings.xml +++ b/packages/SystemUI/res-product/values-ms/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Buka kunci telefon anda untuk mendapatkan lagi pilihan"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Buka kunci tablet anda untuk mendapatkan lagi pilihan"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Buka kunci peranti anda untuk mendapatkan lagi pilihan"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-my/strings.xml b/packages/SystemUI/res-product/values-my/strings.xml index 43c2aca274ee..d15df82aa6d6 100644 --- a/packages/SystemUI/res-product/values-my/strings.xml +++ b/packages/SystemUI/res-product/values-my/strings.xml @@ -43,4 +43,6 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"နောက်ထပ် ထိန်းချုပ်မှုများအတွက် သင့်ဖုန်းကို လော့ခ်ဖွင့်ပါ"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"နောက်ထပ် ထိန်းချုပ်မှုများအတွက် သင့်တက်ဘလက်ကို လော့ခ်ဖွင့်ပါ"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"နောက်ထပ် ထိန်းချုပ်မှုများအတွက် သင့်စက်ကို လော့ခ်ဖွင့်ပါ"</string> + <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"ဤဖုန်းတွင် ဖွင့်နေသည်"</string> + <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"ဤတက်ဘလက်တွင် ဖွင့်နေသည်"</string> </resources> diff --git a/packages/SystemUI/res-product/values-nb/strings.xml b/packages/SystemUI/res-product/values-nb/strings.xml index c7d5bb1263db..a6cf61cfd377 100644 --- a/packages/SystemUI/res-product/values-nb/strings.xml +++ b/packages/SystemUI/res-product/values-nb/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Lås opp telefonen din for å få flere alternativer"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Lås opp nettbrettet ditt for å få flere alternativer"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Lås opp enheten din for å få flere alternativer"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ne/strings.xml b/packages/SystemUI/res-product/values-ne/strings.xml index 315024438e0e..1a9319ff6382 100644 --- a/packages/SystemUI/res-product/values-ne/strings.xml +++ b/packages/SystemUI/res-product/values-ne/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"थप विकल्पहरू हेर्न आफ्नो फोन अनलक गर्नुहोस्"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"थप विकल्पहरू हेर्न आफ्नो ट्याब्लेट अनलक गर्नुहोस्"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"थप विकल्पहरू हेर्न आफ्नो डिभाइस अनलक गर्नुहोस्"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-nl/strings.xml b/packages/SystemUI/res-product/values-nl/strings.xml index 015ff3eaed95..baf97d2bda77 100644 --- a/packages/SystemUI/res-product/values-nl/strings.xml +++ b/packages/SystemUI/res-product/values-nl/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ontgrendel je telefoon voor meer opties"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ontgrendel je tablet voor meer opties"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ontgrendel je apparaat voor meer opties"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml index f0525c98e311..03655ccdac5c 100644 --- a/packages/SystemUI/res-product/values-or/strings.xml +++ b/packages/SystemUI/res-product/values-or/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଆପଣଙ୍କ ଫୋନ୍ ଅନଲକ୍ କରନ୍ତୁ"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଆପଣଙ୍କ ଟାବଲେଟ୍ ଅନଲକ୍ କରନ୍ତୁ"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସ୍ ଅନଲକ୍ କରନ୍ତୁ"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-pa/strings.xml b/packages/SystemUI/res-product/values-pa/strings.xml index fa6cc3ba1aa4..4e5b4cfa0542 100644 --- a/packages/SystemUI/res-product/values-pa/strings.xml +++ b/packages/SystemUI/res-product/values-pa/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਕਰੋ"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਆਪਣਾ ਟੈਬਲੈੱਟ ਅਣਲਾਕ ਕਰੋ"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਆਪਣਾ ਡੀਵਾਈਸ ਅਣਲਾਕ ਕਰੋ"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-pl/strings.xml b/packages/SystemUI/res-product/values-pl/strings.xml index 5ac3d8420783..b5e2b1359826 100644 --- a/packages/SystemUI/res-product/values-pl/strings.xml +++ b/packages/SystemUI/res-product/values-pl/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Odblokuj telefon, by wyświetlić więcej opcji"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Odblokuj tablet, by wyświetlić więcej opcji"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Odblokuj urządzenie, by wyświetlić więcej opcji"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-pt-rBR/strings.xml b/packages/SystemUI/res-product/values-pt-rBR/strings.xml index 499850a6995f..ba1b8458a500 100644 --- a/packages/SystemUI/res-product/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res-product/values-pt-rBR/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueie seu smartphone para ver mais opções"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueie seu tablet para ver mais opções"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie seu dispositivo para ver mais opções"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-pt-rPT/strings.xml b/packages/SystemUI/res-product/values-pt-rPT/strings.xml index 22166bd19a21..07f756f69af3 100644 --- a/packages/SystemUI/res-product/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res-product/values-pt-rPT/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueie o telemóvel para obter mais opções."</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueie o tablet para obter mais opções."</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie o dispositivo para obter mais opções."</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-pt/strings.xml b/packages/SystemUI/res-product/values-pt/strings.xml index 499850a6995f..ba1b8458a500 100644 --- a/packages/SystemUI/res-product/values-pt/strings.xml +++ b/packages/SystemUI/res-product/values-pt/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueie seu smartphone para ver mais opções"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueie seu tablet para ver mais opções"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie seu dispositivo para ver mais opções"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ro/strings.xml b/packages/SystemUI/res-product/values-ro/strings.xml index 4740501f47bd..1faf7ede4b8b 100644 --- a/packages/SystemUI/res-product/values-ro/strings.xml +++ b/packages/SystemUI/res-product/values-ro/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Deblocați telefonul pentru mai multe opțiuni"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Deblocați tableta pentru mai multe opțiuni"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Deblocați dispozitivul pentru mai multe opțiuni"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ru/strings.xml b/packages/SystemUI/res-product/values-ru/strings.xml index e622dbce1745..dce645833b9c 100644 --- a/packages/SystemUI/res-product/values-ru/strings.xml +++ b/packages/SystemUI/res-product/values-ru/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Чтобы посмотреть дополнительные параметры, разблокируйте телефон."</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Чтобы посмотреть дополнительные параметры, разблокируйте планшет."</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Чтобы посмотреть дополнительные параметры, разблокируйте устройство."</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-si/strings.xml b/packages/SystemUI/res-product/values-si/strings.xml index efb2cdef258e..b96655d05ddb 100644 --- a/packages/SystemUI/res-product/values-si/strings.xml +++ b/packages/SystemUI/res-product/values-si/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"තව විකල්ප සඳහා ඔබේ දුරකථනය අගුලු හරින්න"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"තව විකල්ප සඳහා ඔබේ ටැබ්ලට් පරිගණකය අගුලු හරින්න"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"තව විකල්ප සඳහා ඔබේ උපාංගය අගුලු හරින්න"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-sk/strings.xml b/packages/SystemUI/res-product/values-sk/strings.xml index a7b6f0a56274..65a22e58807b 100644 --- a/packages/SystemUI/res-product/values-sk/strings.xml +++ b/packages/SystemUI/res-product/values-sk/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ak chcete zobraziť ďalšie možnosti, odomknite telefón"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ak chcete zobraziť ďalšie možnosti, odomknite tablet"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ak chcete zobraziť ďalšie možnosti, odomknite zariadenie"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-sl/strings.xml b/packages/SystemUI/res-product/values-sl/strings.xml index db55db823982..ca55a4a98b93 100644 --- a/packages/SystemUI/res-product/values-sl/strings.xml +++ b/packages/SystemUI/res-product/values-sl/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Za več možnosti odklenite telefon"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Za več možnosti odklenite tablični računalnik"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Za več možnosti odklenite napravo"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-sq/strings.xml b/packages/SystemUI/res-product/values-sq/strings.xml index cc444c2f91c6..1eabcc10c053 100644 --- a/packages/SystemUI/res-product/values-sq/strings.xml +++ b/packages/SystemUI/res-product/values-sq/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Shkyçe telefonin për më shumë opsione"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Shkyçe tabletin për më shumë opsione"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Shkyçe pajisjen për më shumë opsione"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-sr/strings.xml b/packages/SystemUI/res-product/values-sr/strings.xml index f22d6407a075..2b54158f4e29 100644 --- a/packages/SystemUI/res-product/values-sr/strings.xml +++ b/packages/SystemUI/res-product/values-sr/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Откључајте телефон за још опција"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Откључајте таблет за још опција"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Откључајте уређај за још опција"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-sv/strings.xml b/packages/SystemUI/res-product/values-sv/strings.xml index f6059e0294f1..e7d44ea0639d 100644 --- a/packages/SystemUI/res-product/values-sv/strings.xml +++ b/packages/SystemUI/res-product/values-sv/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Lås upp telefonen för fler alternativ"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Lås upp surfplattan för fler alternativ"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Lås upp enheten för fler alternativ"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-sw/strings.xml b/packages/SystemUI/res-product/values-sw/strings.xml index 171fd9763edb..5237bc336ac7 100644 --- a/packages/SystemUI/res-product/values-sw/strings.xml +++ b/packages/SystemUI/res-product/values-sw/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Fungua simu yako ili upate chaguo zaidi"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Fungua kompyuta yako kibao ili upate chaguo zaidi"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Fungua kifaa chako ili upate chaguo zaidi"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ta/strings.xml b/packages/SystemUI/res-product/values-ta/strings.xml index b53754927706..f2ee9cf07a18 100644 --- a/packages/SystemUI/res-product/values-ta/strings.xml +++ b/packages/SystemUI/res-product/values-ta/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"மேலும் விருப்பங்களுக்கு மொபைலை அன்லாக் செய்யவும்"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"மேலும் விருப்பங்களுக்கு டேப்லெட்டை அன்லாக் செய்யவும்"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"மேலும் விருப்பங்களுக்குச் சாதனத்தை அன்லாக் செய்யவும்"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-te/strings.xml b/packages/SystemUI/res-product/values-te/strings.xml index 511e09532c14..8ecb00f9d7a0 100644 --- a/packages/SystemUI/res-product/values-te/strings.xml +++ b/packages/SystemUI/res-product/values-te/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"మరిన్ని ఆప్షన్ల కోసం మీ ఫోన్ను అన్లాక్ చేయండి"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"మరిన్ని ఆప్షన్ల కోసం మీ టాబ్లెట్ను అన్లాక్ చేయండి"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"మరిన్ని ఆప్షన్ల కోసం మీ పరికరాన్ని అన్లాక్ చేయండి"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-th/strings.xml b/packages/SystemUI/res-product/values-th/strings.xml index bf2261d79abd..7cb9afdf9866 100644 --- a/packages/SystemUI/res-product/values-th/strings.xml +++ b/packages/SystemUI/res-product/values-th/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ปลดล็อกโทรศัพท์เพื่อดูตัวเลือกเพิ่มเติม"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ปลดล็อกแท็บเล็ตเพื่อดูตัวเลือกเพิ่มเติม"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ปลดล็อกอุปกรณ์เพื่อดูตัวเลือกเพิ่มเติม"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-tl/strings.xml b/packages/SystemUI/res-product/values-tl/strings.xml index a70a3a5c50ab..926d057263bf 100644 --- a/packages/SystemUI/res-product/values-tl/strings.xml +++ b/packages/SystemUI/res-product/values-tl/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"I-unlock ang iyong telepono para sa higit pang opsyon"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"I-unlock ang iyong tablet para sa higit pang opsyon"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"I-unlock ang iyong device para sa higit pang opsyon"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-tr/strings.xml b/packages/SystemUI/res-product/values-tr/strings.xml index 5eb7e91e6943..5114e4d0265f 100644 --- a/packages/SystemUI/res-product/values-tr/strings.xml +++ b/packages/SystemUI/res-product/values-tr/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Diğer seçenekler için telefonunuzun kilidini açın"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Diğer seçenekler için tabletinizin kilidini açın"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Diğer seçenekler için cihazınızın kilidini açın"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-uk/strings.xml b/packages/SystemUI/res-product/values-uk/strings.xml index 098f8e792bf4..9dad40d4de7c 100644 --- a/packages/SystemUI/res-product/values-uk/strings.xml +++ b/packages/SystemUI/res-product/values-uk/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Розблокуйте телефон, щоб переглянути інші параметри"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Розблокуйте планшет, щоб переглянути інші параметри"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Розблокуйте пристрій, щоб переглянути інші параметри"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-ur/strings.xml b/packages/SystemUI/res-product/values-ur/strings.xml index 298a72902d25..4f261f4ebd77 100644 --- a/packages/SystemUI/res-product/values-ur/strings.xml +++ b/packages/SystemUI/res-product/values-ur/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"مزید اختیارات کے لیے اپنا فون غیر مقفل کریں"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"مزید اختیارات کے لیے اپنا ٹیبلیٹ غیر مقفل کریں"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"مزید اختیارات کے لیے اپنا آلہ غیر مقفل کریں"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-uz/strings.xml b/packages/SystemUI/res-product/values-uz/strings.xml index d9c0acdc22f6..8da5ff4b0ec3 100644 --- a/packages/SystemUI/res-product/values-uz/strings.xml +++ b/packages/SystemUI/res-product/values-uz/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Boshqa parametrlar uchun telefoningiz qulfini oching"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Boshqa parametrlar uchun planshetingiz qulfini oching"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Boshqa parametrlar uchun qurilmangiz qulfini oching"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-vi/strings.xml b/packages/SystemUI/res-product/values-vi/strings.xml index d6fdf9f6bdd2..d024a1066307 100644 --- a/packages/SystemUI/res-product/values-vi/strings.xml +++ b/packages/SystemUI/res-product/values-vi/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Mở khóa điện thoại của bạn để xem thêm tùy chọn"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Mở khóa máy tính bảng của bạn để xem thêm tùy chọn"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Mở khóa thiết bị của bạn để xem thêm tùy chọn"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-zh-rCN/strings.xml b/packages/SystemUI/res-product/values-zh-rCN/strings.xml index 19196eb6d4aa..dbc792ff55ab 100644 --- a/packages/SystemUI/res-product/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res-product/values-zh-rCN/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"解锁手机即可查看更多选项"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"解锁平板电脑即可查看更多选项"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"解锁设备即可查看更多选项"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-zh-rHK/strings.xml b/packages/SystemUI/res-product/values-zh-rHK/strings.xml index 53f92c3cbb7f..415f078d45d0 100644 --- a/packages/SystemUI/res-product/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res-product/values-zh-rHK/strings.xml @@ -38,9 +38,13 @@ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string> <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string> <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string> - <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> - <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> + <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string> <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"解鎖手機以存取更多選項"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"解鎖平板電腦以存取更多選項"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"解鎖裝置以存取更多選項"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-zh-rTW/strings.xml b/packages/SystemUI/res-product/values-zh-rTW/strings.xml index e484b663bb54..518e3dfdb717 100644 --- a/packages/SystemUI/res-product/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res-product/values-zh-rTW/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"解鎖手機可查看更多選項"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"解鎖平板電腦可查看更多選項"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"解鎖裝置可查看更多選項"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res-product/values-zu/strings.xml b/packages/SystemUI/res-product/values-zu/strings.xml index 8b79a22a72a9..d0a6d9c4ac9c 100644 --- a/packages/SystemUI/res-product/values-zu/strings.xml +++ b/packages/SystemUI/res-product/values-zu/strings.xml @@ -43,4 +43,8 @@ <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Vula ifoni yakho ukuthola okunye okungakhethwa"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Vula ithebulethi yakho ukuthola okunye okungakhethwa"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Vula idivayisi yakho ukuthola okunye okungakhethwa"</string> + <!-- no translation found for media_transfer_playing_this_device (5795784619523545556) --> + <skip /> + <!-- no translation found for media_transfer_playing_this_device (222514408550408633) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/drawable/broadcast_dialog_btn_bg.xml b/packages/SystemUI/res/drawable/broadcast_dialog_btn_bg.xml new file mode 100644 index 000000000000..5fd7ee29d838 --- /dev/null +++ b/packages/SystemUI/res/drawable/broadcast_dialog_btn_bg.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle"> + <solid android:color="?androidprv:attr/colorAccentPrimary" /> + <corners android:radius="@dimen/broadcast_dialog_btn_radius" /> +</shape> diff --git a/packages/SystemUI/res/drawable/ic_qs_screen_saver.xml b/packages/SystemUI/res/drawable/ic_qs_screen_saver.xml new file mode 100644 index 000000000000..263a3d1c894c --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_qs_screen_saver.xml @@ -0,0 +1,24 @@ +<!-- + Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?android:attr/colorControlNormal"> + <path android:fillColor="@android:color/white" + android:pathData="M5,15H19L14.5,9L11,13.5L8.5,10.5ZM6,21Q5.575,21 5.287,20.712Q5,20.425 5,20V19H3Q2.175,19 1.588,18.413Q1,17.825 1,17V6Q1,5.175 1.588,4.588Q2.175,4 3,4H21Q21.825,4 22.413,4.588Q23,5.175 23,6V17Q23,17.825 22.413,18.413Q21.825,19 21,19H19V20Q19,20.425 18.712,20.712Q18.425,21 18,21ZM3,17H21Q21,17 21,17Q21,17 21,17V6Q21,6 21,6Q21,6 21,6H3Q3,6 3,6Q3,6 3,6V17Q3,17 3,17Q3,17 3,17ZM3,17Q3,17 3,17Q3,17 3,17V6Q3,6 3,6Q3,6 3,6Q3,6 3,6Q3,6 3,6V17Q3,17 3,17Q3,17 3,17Z"/> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/media_output_icon_volume.xml b/packages/SystemUI/res/drawable/media_output_icon_volume.xml new file mode 100644 index 000000000000..fce4e0022c7a --- /dev/null +++ b/packages/SystemUI/res/drawable/media_output_icon_volume.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="@color/media_dialog_item_main_content" + android:pathData="M14,20.725V18.675Q16.25,18.025 17.625,16.175Q19,14.325 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,15.15 19.05,17.587Q17.1,20.025 14,20.725ZM3,15V9H7L12,4V20L7,15ZM14,16V7.95Q15.125,8.475 15.812,9.575Q16.5,10.675 16.5,12Q16.5,13.325 15.812,14.4Q15.125,15.475 14,16ZM10,8.85 L7.85,11H5V13H7.85L10,15.15ZM7.5,12Z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/settings_input_antenna.xml b/packages/SystemUI/res/drawable/settings_input_antenna.xml new file mode 100644 index 000000000000..f2adcaf069ef --- /dev/null +++ b/packages/SystemUI/res/drawable/settings_input_antenna.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" + android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" + android:tint="?android:attr/textColorSecondary"> + <path android:fillColor="#FF000000" + android:pathData="M9,22.4 L7.6,21 11,17.6V14.3Q10.325,14 9.913,13.375Q9.5,12.75 9.5,12Q9.5,10.95 10.225,10.225Q10.95,9.5 12,9.5Q13.05,9.5 13.775,10.225Q14.5,10.95 14.5,12Q14.5,12.75 14.088,13.375Q13.675,14 13,14.3V17.6L16.4,21L15,22.4L12,19.4ZM5,12Q5,9.05 7.05,7.025Q9.1,5 12,5Q14.9,5 16.95,7.025Q19,9.05 19,12H17Q17,9.925 15.538,8.462Q14.075,7 12,7Q9.925,7 8.463,8.462Q7,9.925 7,12ZM1,12Q1,9.7 1.863,7.7Q2.725,5.7 4.225,4.212Q5.725,2.725 7.725,1.862Q9.725,1 12,1Q14.275,1 16.275,1.862Q18.275,2.725 19.775,4.212Q21.275,5.7 22.138,7.7Q23,9.7 23,12H21Q21,10.125 20.288,8.487Q19.575,6.85 18.35,5.625Q17.125,4.4 15.488,3.7Q13.85,3 12,3Q10.15,3 8.512,3.7Q6.875,4.4 5.65,5.625Q4.425,6.85 3.712,8.487Q3,10.125 3,12Z"/> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/broadcast_dialog.xml b/packages/SystemUI/res/layout/broadcast_dialog.xml new file mode 100644 index 000000000000..5ba2afe5b172 --- /dev/null +++ b/packages/SystemUI/res/layout/broadcast_dialog.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/dialog_bg" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/broadcast_dialog_margin" + android:orientation="vertical"> + + <ImageView + android:id="@+id/dialog_icon" + android:layout_width="@dimen/broadcast_dialog_icon_size" + android:layout_height="@dimen/broadcast_dialog_icon_size" + android:layout_marginTop="@dimen/broadcast_dialog_icon_margin_top" + android:layout_marginBottom="@dimen/broadcast_dialog_title_img_margin_top" + android:layout_gravity="center" + android:src="@drawable/settings_input_antenna"/> + + <TextView + style="@style/BroadcastDialogTitleStyle" + android:id="@+id/dialog_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:layout_gravity="center"/> + + <TextView + style="@style/BroadcastDialogBodyStyle" + android:id="@+id/dialog_subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:layout_gravity="center"/> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginHorizontal="@dimen/broadcast_dialog_margin" + android:layout_marginBottom="@dimen/broadcast_dialog_margin" + android:orientation="vertical"> + + <Button + android:layout_marginBottom="@dimen/broadcast_dialog_btn_margin_bottom" + android:id="@+id/switch_broadcast" + style="@style/BroadcastDialogButtonStyle"/> + + <Button + android:layout_marginBottom="@dimen/broadcast_dialog_btn_margin_bottom" + android:id="@+id/change_output" + android:text="@string/bt_le_audio_broadcast_dialog_different_output" + style="@style/BroadcastDialogButtonStyle"/> + + <Button + android:id="@+id/cancel" + android:text="@android:string/cancel" + style="@style/BroadcastDialogButtonStyle"/> + </LinearLayout> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml index 10bb6cbb95aa..085a5810608f 100644 --- a/packages/SystemUI/res/layout/clipboard_overlay.xml +++ b/packages/SystemUI/res/layout/clipboard_overlay.xml @@ -67,7 +67,7 @@ android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="@dimen/overlay_offset_x" - android:layout_marginBottom="@dimen/overlay_offset_y" + android:layout_marginBottom="8dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="@id/actions_container_background" android:elevation="7dp" diff --git a/packages/SystemUI/res/layout/screenshot.xml b/packages/SystemUI/res/layout/screenshot.xml index 890dbe592fc7..c29e11bff624 100644 --- a/packages/SystemUI/res/layout/screenshot.xml +++ b/packages/SystemUI/res/layout/screenshot.xml @@ -29,18 +29,11 @@ android:clickable="true" android:importantForAccessibility="no"/> <ImageView - android:id="@+id/screenshot_actions_background" - android:layout_height="@dimen/overlay_bg_protection_height" - android:layout_width="match_parent" - android:layout_gravity="bottom" - android:alpha="0.0" - android:src="@drawable/overlay_actions_background_protection"/> - <ImageView android:id="@+id/screenshot_flash" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" - android:elevation="@dimen/overlay_preview_elevation" + android:elevation="7dp" android:src="@android:color/white"/> <com.android.systemui.screenshot.ScreenshotSelectorView android:id="@+id/screenshot_selector" diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml index c60609b06d38..9c027495aa1e 100644 --- a/packages/SystemUI/res/layout/screenshot_static.xml +++ b/packages/SystemUI/res/layout/screenshot_static.xml @@ -24,7 +24,7 @@ android:visibility="gone" android:layout_height="0dp" android:layout_width="0dp" - android:elevation="1dp" + android:elevation="4dp" android:background="@drawable/action_chip_container_background" android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal" app:layout_constraintBottom_toBottomOf="@+id/actions_container" @@ -36,9 +36,10 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal" + android:layout_marginBottom="4dp" android:paddingEnd="@dimen/overlay_action_container_padding_right" android:paddingVertical="@dimen/overlay_action_container_padding_vertical" - android:elevation="1dp" + android:elevation="4dp" android:scrollbars="none" app:layout_constraintHorizontal_bias="0" app:layout_constraintWidth_percent="1.0" @@ -64,8 +65,8 @@ android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="@dimen/overlay_offset_x" - android:layout_marginBottom="@dimen/overlay_offset_y" - android:elevation="@dimen/overlay_preview_elevation" + android:layout_marginBottom="12dp" + android:elevation="7dp" android:alpha="0" android:background="@drawable/overlay_border" app:layout_constraintStart_toStartOf="parent" @@ -93,7 +94,7 @@ android:layout_margin="@dimen/overlay_border_width" android:layout_height="wrap_content" android:layout_gravity="center" - android:elevation="@dimen/overlay_preview_elevation" + android:elevation="7dp" android:contentDescription="@string/screenshot_edit_description" android:scaleType="fitEnd" android:background="@drawable/overlay_preview_background" @@ -108,7 +109,7 @@ android:id="@+id/screenshot_dismiss_button" android:layout_width="@dimen/overlay_dismiss_button_tappable_size" android:layout_height="@dimen/overlay_dismiss_button_tappable_size" - android:elevation="@dimen/overlay_dismiss_button_elevation" + android:elevation="10dp" android:visibility="gone" app:layout_constraintStart_toEndOf="@id/screenshot_preview" app:layout_constraintEnd_toEndOf="@id/screenshot_preview" @@ -130,5 +131,5 @@ android:visibility="gone" app:layout_constraintStart_toStartOf="@id/screenshot_preview" app:layout_constraintTop_toTopOf="@id/screenshot_preview" - android:elevation="@dimen/overlay_preview_elevation"/> + android:elevation="7dp"/> </com.android.systemui.screenshot.DraggableConstraintLayout> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index f295ac301757..7091dd4c50df 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probeer weer skermkiekie neem"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan nie skermkiekie stoor nie"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Die program of jou organisasie laat nie toe dat skermkiekies geneem word nie"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Die neem van skermskote word deur jou IT-admin geblokkeer"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Wysig"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Wysig skermkiekie"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Deel skermskoot"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Outo-draai"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Outodraai skerm"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Ligging"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameratoegang"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofoontoegang"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Beskikbaar"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Beursie"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Stel op om vinniger, veiliger aankope met jou foon te doen"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Wys alles"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Voeg \'n kaart by"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Dateer tans op"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ontsluit om te gebruik"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Kon nie jou kaarte kry nie; probeer later weer"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Skakel aan wanneer battery waarskynlik sal leegloop"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nee, dankie"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Stort SysUI-hoop"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In gebruik"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programme gebruik tans jou <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" en "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Beweeg nader om op <xliff:g id="DEVICENAME">%1$s</xliff:g> te speel"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Beweeg nader aan <xliff:g id="DEVICENAME">%1$s</xliff:g> om hier te speel"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Speel tans op <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Speel tans op hierdie foon"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Iets is fout. Probeer weer."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Onaktief, gaan program na"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nie gekry nie"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Stoor"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Begin tans …"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan nie uitsaai nie"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan nie stoor nie. Probeer weer."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan nie stoor nie."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string> <string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Wysig gekopieerde teks"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Wysig gekopieerde prent"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Stuur na toestel in die omtrek"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml index 93d26e8f1f83..3f3a2f3d04d4 100644 --- a/packages/SystemUI/res/values-af/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Af"</item> <item msgid="460891964396502657">"Aan"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index fc6402b5de84..c90d74d2ec1b 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"በራስ ሰር አሽከርክር"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ማያ ገጽን በራስ-አሽከርክር"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"አካባቢ"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"የካሜራ መዳረሻ"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"የማይክሮፎን መዳረሻ"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ይገኛል"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"ካርድ አክል"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"በማዘመን ላይ"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ለማየት ይክፈቱ"</string> <string name="wallet_error_generic" msgid="257704570182963611">"የእርስዎን ካርዶች ማግኘት ላይ ችግር ነበር፣ እባክዎ ቆይተው እንደገና ይሞክሩ"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ባትሪው የማለቅ ዕድሉ ከፍ ያለ ከሆነ ያብሩት"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"አይ፣ አመሰግናለሁ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI Heap አራግፍ"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"በጥቅም ላይ"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"መተግበሪያዎች የእርስዎን <xliff:g id="TYPES_LIST">%s</xliff:g> እየተጠቀሙ ነው።"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"፣ "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" እና "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"በ<xliff:g id="DEVICENAME">%1$s</xliff:g> ላይ ለማጫወት ጠጋ ያድርጉ"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"እዚህ ለመጫወት ወደ <xliff:g id="DEVICENAME">%1$s</xliff:g> ቀረብ ይበሉ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"በ<xliff:g id="DEVICENAME">%1$s</xliff:g> ላይ በማጫወት ላይ"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"በዚህ ስልክ በመጫወት ላይ"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"የሆነ ችግር ተፈጥሯል። እንደገና ይሞክሩ።"</string> <string name="controls_error_timeout" msgid="794197289772728958">"ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"አልተገኘም"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"አስቀምጥ"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"በመጀመር ላይ…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"መሰራጨት አይችልም"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ማስቀመጥ አልተቻለም። እንደገና ይሞክሩ።"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ማስቀመጥ አልተቻለም።"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string> <string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"የተቀዳ ጽሁፍ አርትዕ ያድርጉ"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"የተቀዳ ምስል አርትዕ ያድርጉ"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"በአቅራቢያ ወዳለ መሳሪያ ይላኩ"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml index 12be1ae2fd22..5bbe001fec47 100644 --- a/packages/SystemUI/res/values-am/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"አጥፋ"</item> <item msgid="460891964396502657">"አብራ"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 65e204925e07..7667fdae641e 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -231,6 +230,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"التدوير التلقائي"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"التدوير التلقائي للشاشة"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"الموقع الجغرافي"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"الوصول إلى الكاميرا"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"الوصول إلى الميكروفون"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"متاح"</string> @@ -481,7 +482,8 @@ <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="530725155985223497">"إضافة بطاقة"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"جارٍ تحديث تطبيق المحفظة"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"فتح القفل للاستخدام"</string> <string name="wallet_error_generic" msgid="257704570182963611">"حدثت مشكلة أثناء الحصول على البطاقات، يُرجى إعادة المحاولة لاحقًا."</string> @@ -749,8 +751,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"فعِّل الميزة إذا كان من المرجح نفاد شحن البطارية."</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"لا، شكرًا"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"تفريغ ذاكرة SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"قيد الاستخدام"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"تستخدم التطبيقات <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" و "</string> @@ -852,7 +853,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"عليك الاقتراب لتشغيل الوسائط على <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"يُرجى الاقتراب من <xliff:g id="DEVICENAME">%1$s</xliff:g> لتشغيل الوسائط هنا."</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"جارٍ تشغيل الوسائط على <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"جارٍ تشغيل الوسائط على هذا الهاتف"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"حدث خطأ. يُرجى إعادة المحاولة."</string> <string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string> <string name="controls_error_removed" msgid="6675638069846014366">"لم يتم العثور عليه."</string> @@ -882,6 +882,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"حفظ"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"جارٍ البدء…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"يتعذّر البث"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"لا يمكن إجراء الحفظ. يُرجى إعادة المحاولة."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"لا يمكن إجراء الحفظ."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string> <string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string> @@ -970,6 +972,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"تعديل النص المنسوخ"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"تعديل الصورة المنسوخة"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"الإرسال إلى جهاز مجاور"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml index b4fb760f5e65..e05421d09001 100644 --- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"غير مفعّل"</item> <item msgid="460891964396502657">"مفعّل"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 40f8f0d5d778..524cfe429fa4 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"স্বয়ং-ঘূৰ্ণন"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"অৱস্থান"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"কেমেৰাৰ এক্সেছ"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"মাইকৰ এক্সেছ"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"উপলব্ধ"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"এখন কাৰ্ড যোগ দিয়ক"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"আপডে’ট কৰি থকা হৈছে"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ব্যৱহাৰ কৰিবলৈ আনলক কৰক"</string> <string name="wallet_error_generic" msgid="257704570182963611">"আপোনাৰ কাৰ্ড লাভ কৰোঁতে এটা সমস্যা হৈছে, অনুগ্ৰহ কৰি পাছত পুনৰ চেষ্টা কৰক"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"বেটাৰী শেষ হোৱাৰ সম্ভাৱনা থাকিলে অন কৰক"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"নালাগে, ধন্যবাদ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI হীপ ডাম্প কৰক"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"ব্যৱহাৰ হৈ আছে"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"এপ্লিকেশ্বনসমূহে আপোনাৰ <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যৱহাৰ কৰি আছে।"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" আৰু "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ত প্লে’ কৰিবলৈ ওচৰলৈ যাওক"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ইয়াত খেলিবলৈ <xliff:g id="DEVICENAME">%1$s</xliff:g>ৰ আৰু ওচৰলৈ যাওক"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ত প্লে কৰি থকা হৈছে"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"এই ফ’নটোত প্লে কৰি থকা হৈছে"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"কিবা ভুল হ’ল। পুনৰ চেষ্টা কৰক।"</string> <string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্টো পৰীক্ষা কৰক"</string> <string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ছেভ কৰক"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"আৰম্ভ কৰা হৈছে…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্ৰচাৰ কৰিব নোৱাৰি"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ছেভ কৰিব নোৱাৰি। পুনৰ চেষ্টা কৰক।"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ছেভ কৰিব নোৱাৰি।"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string> <string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"প্ৰতিলিপি কৰা পাঠ সম্পাদনা কৰক"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"প্ৰতিলিপি কৰা প্ৰতিচ্ছবি সম্পাদনা কৰক"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"নিকটৱৰ্তী ডিভাইচলৈ পঠাওক"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml index 7767cfc6943a..4c900ef6626f 100644 --- a/packages/SystemUI/res/values-as/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"অফ"</item> <item msgid="460891964396502657">"অন"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 55a8fea352cd..d81afbd111ba 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Skrinşotu yenidən çəkin"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Skrinşotu yadda saxlamaq mümkün olmadı"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Skrinşot çəkməyə tətbiq və ya təşkilat tərəfindən icazə verilmir"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Skrinşot çəkilməsi İT admininiz tərəfindən bloklanıb"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Redaktə edin"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Skrinşota düzəliş edin"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Skrinşotu paylaşın"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avtodönüş"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranın avtomatik dönməsi"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Məkan"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameraya giriş"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofona giriş"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Əlçatan"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Pulqabı"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Telefonunuzla daha sürətli və təhlükəsiz satınalmalar etmək üçün ayarlayın"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Hamısını göstər"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Kart əlavə edin"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Güncəllənir"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"İstifadə etmək üçün kiliddən çıxarın"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Kartların əldə edilməsində problem oldu, sonra yenidən cəhd edin"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Batareya bitmək üzrə olduqda aktiv edin"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Xeyr, təşəkkür"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"İstifadə olunur"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Tətbiqlər <xliff:g id="TYPES_LIST">%s</xliff:g> istifadə edir."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" və "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oxutmaq üçün yaxınlaşın"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Burada oxutmaq üçün <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaxınlaşın"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oxudulur"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Bu telefonda oxudulur"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Xəta oldu. Yenə cəhd edin."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Tapılmadı"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Saxlayın"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Başlanır…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayımlamaq mümkün deyil"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Yadda saxlamaq mümkün deyil. Yenə cəhd edin."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Yadda saxlamaq mümkün deyil."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string> <string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Kopyalanmış mətni redaktə edin"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Kopyalanmış şəkli redaktə edin"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Yaxınlıqdakı cihaza göndərin"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml index 0311794de3cd..da6dc6e2e3f2 100644 --- a/packages/SystemUI/res/values-az/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Deaktiv"</item> <item msgid="460891964396502657">"Aktiv"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 768f58f7118d..024f83e475e1 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probajte da ponovo napravite snimak ekrana"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Čuvanje snimka ekrana nije uspelo"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT administrator blokira pravljenje snimaka ekrana"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Izmeni"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Izmenite snimak ekrana"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Delite snimak ekrana"</string> @@ -228,6 +227,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatska rotacija"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup kameri"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pristup mikrofonu"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupno"</string> @@ -472,7 +473,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Obavite konfigurisanje da biste mogli brže i sigurnije da kupujete pomoću telefona"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Prikaži sve"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Dodajte karticu"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ažurira se"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključaj radi korišćenja"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Došlo je do problema pri preuzimanju kartica. Probajte ponovo kasnije"</string> @@ -734,8 +736,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Uključite ako će baterija verovatno da se isprazni"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji SysUI mem."</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"U upotrebi"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string> @@ -834,7 +835,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite da biste puštali muziku na: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da biste na njemu puštali"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Pušta se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Pušta se na ovom telefonu"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo je do greške. Probajte ponovo."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string> @@ -864,6 +864,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Sačuvaj"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pokreće se…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitovanje nije uspelo"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Čuvanje nije uspelo. Probajte ponovo."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Čuvanje nije uspelo."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string> <string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string> @@ -949,6 +951,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Izmenite kopirani tekst"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Izmenite kopiranu sliku"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji na uređaj u blizini"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml index a057c48bbec9..0aa3475f05c5 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Isključeno"</item> <item msgid="460891964396502657">"Uključeno"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index f6d9183c94b3..02d23aa95d81 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Стварэнне здымкаў экрана заблакіравана IT-адміністратарам"</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> @@ -229,6 +228,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аўтапаварот"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аўтаматычны паварот экрана"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Месцазнаходжанне"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ да камеры"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Доступ да мікрафона"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Доступ дазволены"</string> @@ -475,7 +476,8 @@ <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="530725155985223497">"Дадаць карту"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ідзе абнаўленне"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Разблакіраваць для выкарыстання"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Узнікла праблема з загрузкай вашых карт. Паўтарыце спробу пазней"</string> @@ -739,8 +741,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Уключыце, калі зарад акумулятара заканчваецца"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Не, дзякуй"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Выкарыстоўваецца"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Праграмы выкарыстоўваюць: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" і "</string> @@ -840,7 +841,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Каб прайграць мультымедыя на прыладзе \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", наблізьцеся да яе"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Падыдзіце бліжэй да прылады \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", каб прайграць на гэтай"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Прайграецца на прыладзе \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\""</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Прайграецца на гэтым тэлефоне"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Нешта пайшло не так. Паўтарыце спробу."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не знойдзена"</string> @@ -870,6 +870,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Захаваць"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Запускаецца…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не ўдалося запусціць трансляцыю"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не ўдалося захаваць. Паўтарыце спробу."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не ўдалося захаваць."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string> <string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string> @@ -956,6 +958,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Змяніць скапіраваны тэкст"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Змяніць скапіраваны відарыс"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Адправіць на прыладу паблізу"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml index d2588113f37b..d578a5f3755d 100644 --- a/packages/SystemUI/res/values-be/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Выключана"</item> <item msgid="460891964396502657">"Уключана"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 04acd12a3e7c..43905059e9b9 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматична ориентация"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично завъртане на екрана"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Местоположение"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Достъп до камерата"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Достъп до микрофона"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Налице"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"Добавяне на карта"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Актуализира се"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Отключване с цел използване"</string> <string name="wallet_error_generic" msgid="257704570182963611">"При извличането на картите ви възникна проблем. Моля, опитайте отново по-късно"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Включване, когато е вероятно батерията да се изтощи"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Не, благодаря"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Използва се"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Някои приложения използват <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Прекарайте пръст, за да видите повече"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Препоръките се зареждат"</string> <string name="controls_media_title" msgid="1746947284862928133">"Мултимедия"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Да се скрие ли за <xliff:g id="APP_NAME">%1$s</xliff:g> тази контрола за мултимедията?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Скриване за <xliff:g id="APP_NAME">%1$s</xliff:g> на контролата за мултимедия?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Текущата сесия за мултимедия не бе скрита."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриване"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Преместете се по-близо, за да се възпроизведе на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g> за възпроизвеждане на това устройство"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Възпроизвежда се на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Възпроизвежда се на този телефон"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Нещо се обърка. Опитайте отново."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не е намерено"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Запазване"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Стартира се…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Предаването не е възможно"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не може да се запази. Опитайте отново."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не може да се запази."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string> <string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Редактиране на копирания текст"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Редактиране на копираното изображение"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Изпращане до устройство в близост"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml index da5c325aaa1c..4d36c319be72 100644 --- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Изкл."</item> <item msgid="460891964396502657">"Вкл."</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index e7639f72d709..a447c9f11752 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"নিজে থেকে ঘুরবে"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"অটো-রোটেট স্ক্রিন"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"লোকেশন"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"ক্যামেরা অ্যাক্সেস"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"মাইক্রোফোন অ্যাক্সেস"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"উপলভ্য"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"কার্ড যোগ করুন"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"আপডেট করা হচ্ছে"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ব্যবহার করতে আনলক করুন"</string> <string name="wallet_error_generic" msgid="257704570182963611">"আপনার কার্ড সংক্রান্ত তথ্য পেতে সমস্যা হয়েছে, পরে আবার চেষ্টা করুন"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ব্যাটারির চার্জ শেষ হয়ে যাওয়ার সম্ভাবনা দেখা দিলে চালু করুন"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"না থাক"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"ব্যবহার হচ্ছে"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"অ্যাপ্লিকেশনগুলি আপনার <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যবহার করছে।"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" এবং "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>-এ চালাতে আরও কাছে আনুন"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"এখান থেকে চালাতে <xliff:g id="DEVICENAME">%1$s</xliff:g>-এর কাছে নিয়ে যান"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>-এ ভিডিও চালানো হচ্ছে"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"এই ফোনে চালানো হচ্ছে"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"কোনও সমস্যা হয়েছে। আবার চেষ্টা করুন।"</string> <string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string> <string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"সেভ করুন"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"শুরু করা হচ্ছে…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্রচার করা যাচ্ছে না"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"সেভ করা যাচ্ছে না। আবার চেষ্টা করুন।"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"সেভ করা যাচ্ছে না।"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string> <string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"কপি করা টেক্সট এডিট করুন"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"কপি করা ছবি এডিট করুন"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"আশেপাশের ডিভাইসে পাঠান"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml index 784d974e2eba..868679700456 100644 --- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"বন্ধ আছে"</item> <item msgid="460891964396502657">"চালু আছে"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index db2bdf377f98..0a372d20676d 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Pokušajte ponovo snimiti ekran"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nije moguće sačuvati snimak ekrana"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ova aplikacija ili vaša organizacija ne dozvoljavaju snimanje ekrana"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Snimanje ekrana je blokirao IT administrator"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Uredite"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Uredite snimak ekrana"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Dijeljenje snimka ekrana"</string> @@ -228,6 +227,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatsko rotiranje"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup kameri"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pristup mikrofonu"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupno"</string> @@ -472,7 +473,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Novčanik"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Postavite aplikaciju za brže i sigurnije kupovine putem telefona"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Prikaži sve"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Dodajte karticu"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ažuriranje"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključajte da koristite"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Došlo je do problema prilikom preuzimanja vaših kartica. Pokušajte ponovo kasnije"</string> @@ -734,8 +736,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Uključite ako je vjerovatno da će se baterija istrošiti"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji SysUI mem."</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"U upotrebi"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string> @@ -814,7 +815,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Prevucite da vidite više"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Učitavanje preporuka"</string> <string name="controls_media_title" msgid="1746947284862928133">"Mediji"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Sakriti kontrolu medijskog sadržaja za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Sakriti kontrolu medija za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Trenutna sesija medija se ne može sakriti."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string> @@ -834,7 +835,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite se da reproducirate na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da na njemu reproducirate"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducira se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproducira se na ovom telefonu"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije uredu. Pokušajte ponovo."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string> @@ -864,6 +864,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Sačuvaj"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pokretanje…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nije moguće emitirati"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nije moguće sačuvati. Pokušajte ponovo."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nije moguće sačuvati."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string> <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string> @@ -949,6 +951,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Uredi kopirani tekst"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Uredi kopiranu sliku"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji na uređaj u blizini"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Dodaj"</string> <string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obavještenje ne podržava prevlačenje na podijeljeni ekran."</string> diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml index a057c48bbec9..0aa3475f05c5 100644 --- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Isključeno"</item> <item msgid="460891964396502657">"Uključeno"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 83b2e054ba6f..6f3e63b149ea 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prova de tornar a fer una captura de pantalla"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"No es pot desar la captura de pantalla"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'aplicació o la teva organització no permeten fer captures de pantalla"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"El teu administrador de TI ha bloquejat les captures de pantalla"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Edita"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Edita la captura de pantalla"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Comparteix la captura de pantalla"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Gira automàticament"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Gira la pantalla automàticament"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicació"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accés a la càmera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accés al micròfon"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Configura una manera més ràpida i segura de fer compres amb el telèfon"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Mostra-ho tot"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Afegeix una targeta"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"S\'està actualitzant"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloqueja per utilitzar"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Hi ha hagut un problema en obtenir les teves targetes; torna-ho a provar més tard"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Activa\'l quan sigui probable que et quedis sense bateria"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"No, gràcies"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Aboca el monticle de SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"En ús"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Algunes aplicacions estan fent servir el següent: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Mou més a prop per reproduir a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acosta\'t a <xliff:g id="DEVICENAME">%1$s</xliff:g> per reproduir el contingut aquí"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"S\'està reproduint a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"S\'està reproduint en aquest telèfon"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"S\'ha produït un error. Torna-ho a provar."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string> <string name="controls_error_removed" msgid="6675638069846014366">"No s\'ha trobat"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Desa"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"S\'està iniciant…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No es pot emetre"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No es pot desar. Torna-ho a provar."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No es pot desar."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string> <string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edita el text que has copiat"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edita la imatge que has copiat"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Envia a un dispositiu proper"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml index 5977679bb462..184959ea436d 100644 --- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Desactivat"</item> <item msgid="460891964396502657">"Activat"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 6889c71c1b7a..cb0a16c5f708 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Zkuste snímek pořídit znovu"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Snímek obrazovky se nepodařilo uložit"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikace nebo organizace zakazuje pořizování snímků obrazovky"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Pořizování snímků obrazovky je blokováno administrátorem IT"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Upravit"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Upravit snímek obrazovky"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Sdílet snímek obrazovky"</string> @@ -229,6 +228,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatické otáčení"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otočení obrazovky"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Přístup k fotoaparátu"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Přístup k mikrofonu"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupné"</string> @@ -285,8 +286,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do svítání"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Zapnout v <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Zapnout při večerce"</string> - <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"Dokud neskončí večerka"</string> + <string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Zapnout během nočního klidu"</string> + <string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"Dokud neskončí noční klid"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je vypnuto"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je zapnuto"</string> @@ -475,7 +476,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Peněženka"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Nastavte si rychlejší a bezpečnější platby pomocí telefonu"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Zobrazit vše"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Přidat kartu"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Aktualizace"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odemknout a použít"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Při načítání karet došlo k problému, zkuste to později"</string> @@ -739,8 +741,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Zapnout, když bude pravděpodobné, že se vybije baterie"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, díky"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Výpis haldy SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Používá se"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikace využívají tato oprávnění: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" a "</string> @@ -840,7 +841,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Pokud chcete přehrávat na zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>, přibližte se k němu"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Pokud zde chcete přehrávat média, přibližte se k zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Přehrávání v zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Přehrávání v tomto telefonu"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo k chybě. Zkuste to znovu."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivní, zkontrolujte aplikaci"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nenalezeno"</string> @@ -870,6 +870,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Uložit"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Spouštění…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Vysílání se nezdařilo"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Uložení se nezdařilo. Zkuste to znovu."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Uložení se nezdařilo."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string> <string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string> @@ -956,6 +958,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Upravit zkopírovaný text"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Upravit zkopírovaný obrázek"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Odeslat do zařízení v okolí"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml index 2af84d97653c..73b0452fd177 100644 --- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Vypnuto"</item> <item msgid="460891964396502657">"Zapnuto"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 17ffd19da2f3..da5b4799b675 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv at tage et screenshot igen"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Dit screenshot kunne ikke gemmes."</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller din organisation tillader ikke, at du tager screenshots"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Din it-administrator har blokeret screenshot-funktionen"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger screenshot"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Del screenshottet"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Roter automatisk"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Roter skærmen automatisk"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokation"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameraadgang"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonadgang"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tilgængelig"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Bliv klar til at foretage hurtigere og mere sikre køb med din telefon"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Vis alle"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Tilføj et kort"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Opdaterer"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås op for at bruge"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Dine kort kunne ikke hentes. Prøv igen senere."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Aktivér, når det ser ud til, at batteriet løber tør"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nej tak"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Gem SysUI-heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"I brug"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps anvender enhedens <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flyt enheden tættere på for at afspille på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ryk tættere på <xliff:g id="DEVICENAME">%1$s</xliff:g> for at afspille her"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Afspilles på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Afspilles på denne telefon"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Noget gik galt. Prøv igen."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ikke fundet"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Gem"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starter…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Der kan ikke udsendes en fællesbesked"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Der kan ikke gemmes. Prøv igen."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Der kan ikke gemmes."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string> <string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Rediger kopieret tekst"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Rediger kopieret billede"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send til enhed i nærheden"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml index 0fe06b3433c3..b6a0a2a1d67f 100644 --- a/packages/SystemUI/res/values-da/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Fra"</item> <item msgid="460891964396502657">"Til"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 6dab45b9016d..430b6781b228 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Versuche noch einmal, den Screenshot zu erstellen"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Screenshot kann nicht gespeichert werden"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Die App oder deine Organisation lässt das Erstellen von Screenshots nicht zu"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Dein IT-Administrator hat das Erstellen von Screenshots blockiert"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Bearbeiten"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Screenshot bearbeiten"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Screenshot teilen"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatisch drehen"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Bildschirm automatisch drehen"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Standort"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kamerazugriff"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonzugriff"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Verfügbar"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Geldbörse"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Füge eine Zahlungsmethode hinzu, um noch schneller und sicherer mit deinem Smartphone zu bezahlen"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Alle anzeigen"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Karte hinzufügen"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Wird aktualisiert"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Zum Verwenden entsperren"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Beim Abrufen deiner Karten ist ein Fehler aufgetreten – bitte versuch es später noch einmal"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Aktivieren, wenn der Akku wahrscheinlich nicht mehr lange hält"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nein danke"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In Verwendung"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps verwenden gerade Folgendes: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" und "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Gehe für die Wiedergabe näher an <xliff:g id="DEVICENAME">%1$s</xliff:g> heran"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Platziere für die Wiedergabe dein Gerät näher an „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Wird auf „<xliff:g id="DEVICENAME">%1$s</xliff:g>“ abgespielt"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Wird auf diesem Smartphone abgespielt"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Es gab ein Problem. Versuch es noch einmal."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nicht gefunden"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Speichern"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Wird gestartet…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Übertragung nicht möglich"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Speichern nicht möglich. Versuche es noch einmal."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Speichern nicht möglich."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string> <string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Kopierten Text bearbeiten"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Kopiertes Bild bearbeiten"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"An Gerät in der Nähe senden"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml index ba610b33ccfa..03198b178fbf 100644 --- a/packages/SystemUI/res/values-de/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Aus"</item> <item msgid="460891964396502657">"An"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 89474d9a7c47..3107a21fe26b 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Η λήψη στιγμιότυπων οθόνης έχει αποκλειστεί από τον διαχειριστή IT."</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Αυτόματη περιστροφή"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Αυτόματη περιστροφή οθόνης"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Τοποθεσία"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Πρόσβαση κάμερας"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Πρόσβαση μικροφώνου"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Διαθέσιμη"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"Προσθήκη κάρτας"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ενημέρωση σε εξέλιξη"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ξεκλείδωμα για χρήση"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Παρουσιάστηκε πρόβλημα με τη λήψη των καρτών σας. Δοκιμάστε ξανά αργότερα"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Ενεργοποίηση όταν υπάρχει σημαντική πιθανότητα εξάντλησης της μπαταρίας"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Όχι, ευχαριστώ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Στιγμ. μνήμης SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Χρησιμοποιείται"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Οι εφαρμογές χρησιμοποιούν τις λειτουργίες <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" και "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Πλησιάστε για αναπαραγωγή στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Μετακινηθείτε πιο κοντά στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g> για αναπαραγωγή εδώ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Αναπαραγωγή στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Αναπαραγωγή σε αυτό το τηλέφωνο"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Παρουσιάστηκε κάποιο πρόβλημα. Δοκιμάστε ξανά."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Ανενεργό, έλεγχος εφαρμογής"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Δεν βρέθηκε."</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Αποθήκευση"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Εκκίνηση…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Δεν είναι δυνατή η μετάδοση"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Δεν είναι δυνατή η αποθήκευση. Δοκιμάστε ξανά."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Δεν είναι δυνατή η αποθήκευση."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string> <string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Επεξεργασία αντιγραμμένου κειμένου"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Επεξεργασία αντιγραμμένης εικόνας"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Αποστολή σε κοντινή συσκευή"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml index 74c091e4ed18..06fbc3d6133c 100644 --- a/packages/SystemUI/res/values-el/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Ανενεργή"</item> <item msgid="460891964396502657">"Ενεργή"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index e9eb7414b78d..002411c88ad6 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Taking screenshots is blocked by your IT admin"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string> @@ -227,6 +226,7 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string> + <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string> @@ -469,7 +469,7 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Get set up to make faster, more secure purchases with your phone"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Show all"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Add a card"</string> + <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Tap to open"</string> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Updating"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Unlock to use"</string> <string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards. Please try again later."</string> @@ -729,8 +729,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"No, thanks"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In use"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string> @@ -828,7 +827,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> @@ -858,6 +856,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -942,6 +942,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Add"</string> <string name="manage_users" msgid="1823875311934643849">"Manage users"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string> diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml index 6f8cfb695ac6..56cdbef092f2 100644 --- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml @@ -171,4 +171,9 @@ <item msgid="146088982397753810">"Off"</item> <item msgid="460891964396502657">"On"</item> </string-array> + <string-array name="tile_states_dream"> + <item msgid="6184819793571079513">"Unavailable"</item> + <item msgid="8014986104355098744">"Off"</item> + <item msgid="5966994759929723339">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 75c6befebd85..bf588b548e6a 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Taking screenshots is blocked by your IT admin"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string> @@ -227,6 +226,7 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string> + <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string> @@ -469,7 +469,7 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Get set up to make faster, more secure purchases with your phone"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Show all"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Add a card"</string> + <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Tap to open"</string> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Updating"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Unlock to use"</string> <string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards. Please try again later."</string> @@ -729,8 +729,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"No, thanks"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In use"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string> @@ -828,7 +827,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> @@ -858,6 +856,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -942,6 +942,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Add"</string> <string name="manage_users" msgid="1823875311934643849">"Manage users"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string> diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml index 6f8cfb695ac6..56cdbef092f2 100644 --- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml @@ -171,4 +171,9 @@ <item msgid="146088982397753810">"Off"</item> <item msgid="460891964396502657">"On"</item> </string-array> + <string-array name="tile_states_dream"> + <item msgid="6184819793571079513">"Unavailable"</item> + <item msgid="8014986104355098744">"Off"</item> + <item msgid="5966994759929723339">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index e9eb7414b78d..002411c88ad6 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Taking screenshots is blocked by your IT admin"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string> @@ -227,6 +226,7 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string> + <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string> @@ -469,7 +469,7 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Get set up to make faster, more secure purchases with your phone"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Show all"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Add a card"</string> + <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Tap to open"</string> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Updating"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Unlock to use"</string> <string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards. Please try again later."</string> @@ -729,8 +729,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"No, thanks"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In use"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string> @@ -828,7 +827,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> @@ -858,6 +856,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -942,6 +942,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Add"</string> <string name="manage_users" msgid="1823875311934643849">"Manage users"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string> diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml index 6f8cfb695ac6..56cdbef092f2 100644 --- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml @@ -171,4 +171,9 @@ <item msgid="146088982397753810">"Off"</item> <item msgid="460891964396502657">"On"</item> </string-array> + <string-array name="tile_states_dream"> + <item msgid="6184819793571079513">"Unavailable"</item> + <item msgid="8014986104355098744">"Off"</item> + <item msgid="5966994759929723339">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index e9eb7414b78d..002411c88ad6 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Taking screenshots is blocked by your IT admin"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string> @@ -227,6 +226,7 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string> + <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string> @@ -469,7 +469,7 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Get set up to make faster, more secure purchases with your phone"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Show all"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Add a card"</string> + <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Tap to open"</string> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Updating"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Unlock to use"</string> <string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards. Please try again later."</string> @@ -729,8 +729,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"No, thanks"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In use"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string> @@ -828,7 +827,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> @@ -858,6 +856,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -942,6 +942,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Add"</string> <string name="manage_users" msgid="1823875311934643849">"Manage users"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string> diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml index 6f8cfb695ac6..56cdbef092f2 100644 --- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml @@ -171,4 +171,9 @@ <item msgid="146088982397753810">"Off"</item> <item msgid="460891964396502657">"On"</item> </string-array> + <string-array name="tile_states_dream"> + <item msgid="6184819793571079513">"Unavailable"</item> + <item msgid="8014986104355098744">"Off"</item> + <item msgid="5966994759929723339">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index d8b73965d9fd..b19c693ebbbb 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organization"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Taking screenshots is blocked by your IT admin"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string> @@ -227,6 +226,7 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string> + <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screen saver"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string> @@ -469,7 +469,7 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Get set up to make faster, more secure purchases with your phone"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Show all"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Add a card"</string> + <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Tap to open"</string> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Updating"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Unlock to use"</string> <string name="wallet_error_generic" msgid="257704570182963611">"There was a problem getting your cards, please try again later"</string> @@ -729,8 +729,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"No thanks"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In use"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string> @@ -828,7 +827,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Playing on this phone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> @@ -858,6 +856,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> @@ -942,6 +942,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit copied text"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit copied image"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send to nearby device"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Add"</string> <string name="manage_users" msgid="1823875311934643849">"Manage users"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Splitscreen."</string> diff --git a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml index 99ef50c9d8af..3a8e34c2ebdc 100644 --- a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml @@ -171,4 +171,9 @@ <item msgid="146088982397753810">"Off"</item> <item msgid="460891964396502657">"On"</item> </string-array> + <string-array name="tile_states_dream"> + <item msgid="6184819793571079513">"Unavailable"</item> + <item msgid="8014986104355098744">"Off"</item> + <item msgid="5966994759929723339">"On"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 080cac777638..03531353b8e7 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Vuelve a hacer una captura de pantalla"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"No se pudo guardar la captura de pantalla"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"La app o tu organización no permiten las capturas de pantalla"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Tu administrador de TI bloquea las capturas de pantalla"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de pantalla"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Girar automáticamente"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar la pantalla automáticamente"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acceso a la cámara"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acceso al mic."</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string> @@ -469,12 +470,13 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Prepárate para realizar compras rápidas y seguras con tu teléfono"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Mostrar todo"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Agregar una tarjeta"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Actualizando"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Ocurrió un problema al obtener las tarjetas; vuelve a intentarlo más tarde"</string> <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Configuración de pantalla de bloqueo"</string> - <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escanear código QR"</string> + <string name="qr_code_scanner_title" msgid="5290201053875420785">"Escanear QR"</string> <string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string> <string name="status_bar_airplane" msgid="4848702508684541009">"Modo de avión"</string> <string name="zen_alarm_warning" msgid="7844303238486849503">"No oirás la próxima alarma a la(s) <xliff:g id="WHEN">%1$s</xliff:g>"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Actívalo cuando la batería se esté por acabar"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"No, gracias"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Volcar pila de SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"En uso"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hay aplicaciones que están usando tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" y "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Desliza el dedo para ver más elementos"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string> <string name="controls_media_title" msgid="1746947284862928133">"Contenido multimedia"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"¿Quieres ocultar este control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"¿Ocultar control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"No se puede ocultar la sesión multimedia actual."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Acércate para reproducir en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproducir aquí"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproduciendo en este teléfono"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Se produjo un error. Vuelve a intentarlo."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"No se encontró"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Guardar"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Error al iniciar transmisión"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No se puede guardar. Vuelve a intentarlo."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No se puede guardar."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string> <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar el texto copiado"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar la imagen copiada"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar a dispositivos cercanos"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml index f7eaba68c338..c374ac3323d6 100644 --- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"No"</item> <item msgid="460891964396502657">"Sí"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 7d3009284659..2d9be5861bf4 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Vuelve a intentar hacer la captura de pantalla"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"No se puede guardar la captura de pantalla"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"La aplicación o tu organización no permiten realizar capturas de pantalla"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Tu administrador de TI ha bloqueado las capturas de pantalla"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de pantalla"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura de pantalla"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar pantalla automáticamente"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acceso a cámara"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acceso al micro"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string> @@ -346,9 +347,9 @@ <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres continuar con tu sesión?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string> <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string> - <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo Invitados"</string> - <string name="guest_notification_session_active" msgid="5567273684713471450">"Estás en modo Invitados"</string> - <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si añades un usuario nuevo, saldrás del modo Invitados y se eliminarán todas las aplicaciones y datos de la sesión de invitado actual."</string> + <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo Invitado"</string> + <string name="guest_notification_session_active" msgid="5567273684713471450">"Estás en modo Invitado"</string> + <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si añades un nuevo usuario, saldrás del modo Invitado y se eliminarán todas las aplicaciones y datos de la sesión de invitado actual."</string> <string name="user_limit_reached_title" msgid="2429229448830346057">"Has alcanzado el límite de usuarios"</string> <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398"> <item quantity="other">Puedes añadir hasta <xliff:g id="COUNT">%d</xliff:g> usuarios.</item> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Configura un método de pago para comprar de forma más rápida y segura con tu teléfono"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Mostrar todo"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Añade una tarjeta"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Actualizando"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Se ha producido un problema al obtener tus tarjetas. Inténtalo de nuevo más tarde."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Activar cuando sea probable que se quede sin batería"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"No, gracias"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Volcar montículo de SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"En uso"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hay aplicaciones que usan tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" y "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Desliza el dedo para ver más"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Cargando recomendaciones"</string> <string name="controls_media_title" msgid="1746947284862928133">"Multimedia"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"¿Ocultar este control multimedia a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"¿Ocultar este control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"La sesión multimedia no se puede ocultar."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para que se reproduzca en ese dispositivo"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para jugar aquí"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproduciendo en este dispositivo"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Se ha producido un error. Inténtalo de nuevo."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string> <string name="controls_error_removed" msgid="6675638069846014366">"No se ha encontrado"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Guardar"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No se puede emitir"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No se puede guardar. Inténtalo de nuevo."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No se puede guardar."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string> <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagen copiada"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar a dispositivo cercano"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml index 7d728ac1ef7e..d6c30a9bcc1c 100644 --- a/packages/SystemUI/res/values-es/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Desactivado"</item> <item msgid="460891964396502657">"Activado"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 1d753ff68a2e..1be80e45503f 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Proovige ekraanipilt uuesti jäädvustada"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ekraanipilti ei saa salvestada"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Rakendus või teie organisatsioon ei luba ekraanipilte jäädvustada"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT-administraator on ekraanipiltide jäädvustamise blokeerinud"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Muutmine"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Ekraanipildi muutmine"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Jaga ekraanipilti"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. pööramine"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Kuva automaatne pööramine"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Asukoht"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Juurdepääs kaamerale"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Juurdepääs mikrofonile"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Saadaval"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Rahakott"</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="530725155985223497">"Lisage kaart"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Värskendamine"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Avage kasutamiseks"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Teie kaartide hankimisel ilmnes probleem, proovige hiljem uuesti"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Lülitatakse sisse, kui aku hakkab tühjaks saama"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Tänan, ei"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Kasutusel"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Rakendused kasutavad järgmisi: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ja "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Pühkige sõrmega, et näha rohkem"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Soovituste laadimine"</string> <string name="controls_media_title" msgid="1746947284862928133">"Meedia"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Kas peita rakenduses <xliff:g id="APP_NAME">%1$s</xliff:g> see meedia juhtnupp?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Kas peita rakenduses <xliff:g id="APP_NAME">%1$s</xliff:g> see meediajuhik?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Praegust meediaseanssi ei saa peita."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Peida"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Teisaldage lähemale, et seadmes <xliff:g id="DEVICENAME">%1$s</xliff:g> esitada"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Siin esitamiseks liigutage seadmele <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemale"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Esitatakse seadmes <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Esitatakse selles telefonis"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Midagi läks valesti. Proovige uuesti."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ei leitud"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salvesta"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Alustamine …"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei saa üle kanda"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ei saa salvestada. Proovige uuesti."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ei saa salvestada."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string> <string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Muuda kopeeritud teksti"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Muuda kopeeritud pilti"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Saada läheduses olevasse seadmesse"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml index 29895d1a437a..4b22dfa99f7b 100644 --- a/packages/SystemUI/res/values-et/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Väljas"</item> <item msgid="460891964396502657">"Sees"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 382e52584b7e..b6a35d61130d 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Saiatu berriro pantaila-argazkia ateratzen"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ezin da gorde pantaila-argazkia"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikazioak edo erakundeak ez du onartzen pantaila-argazkiak ateratzea"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IKT saileko administratzaileak blokeatu egin dizu pantaila-argazkiak ateratzeko aukera"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Editatu"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Editatu pantaila-argazkia"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Partekatu pantaila-argazkia"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Biratze automatikoa"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Biratu pantaila automatikoki"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Kokapena"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kamera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonoa"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Baimenduta"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Konfiguratu erosketa bizkorrago eta seguruagoak egiteko telefonoarekin"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Erakutsi guztiak"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Gehitu txartel bat"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Eguneratzen"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desblokeatu erabiltzeko"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Arazo bat izan da txartelak eskuratzean. Saiatu berriro geroago."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Aktibatu aurrezlea bateria agortzeko arriskua dagoenean"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ez, eskerrik asko"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Erabiltzen ari da"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikazio batzuk <xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari dira."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" eta "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasatu hatza aukera gehiago ikusteko"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Gomendioak kargatzen"</string> <string name="controls_media_title" msgid="1746947284862928133">"Multimedia-edukia"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren multimedia-edukiaren kontrolagailu hau ezkutatu?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren multimedia kontr. aukerak ezkutatu?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Ezin da ezkutatu multimedia-saioa."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ezkutatu"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Gertura ezazu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailuan erreproduzitzeko"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Gerturatu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailura bertan erreproduzitzen ari dena hemen erreproduzitzeko"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> gailuan erreproduzitzen"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Telefono honetan erreproduzitzen"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Arazoren bat izan da. Saiatu berriro."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Gorde"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Abiarazten…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ezin da iragarri"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ezin da gorde. Saiatu berriro."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ezin da gorde."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string> <string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editatu kopiatutako testua"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editatu kopiatutako irudia"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Bidali inguruko gailu batera"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Gehitu"</string> <string name="manage_users" msgid="1823875311934643849">"Kudeatu erabiltzaileak"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Jakinarazpen hau ezin da arrastatu pantaila zatitura."</string> diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml index baddea16b833..1fcc7ec6afe4 100644 --- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Desaktibatuta"</item> <item msgid="460891964396502657">"Aktibatuta"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index e6f915b794e4..4c0870d11e47 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -60,7 +60,7 @@ <string name="wifi_debugging_title" msgid="7300007687492186076">"اشکالزدایی بیسیم در این شبکه مجاز شود؟"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"نام شبکه (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nنشانی Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"همیشه در این شبکه مجاز شود"</string> - <string name="wifi_debugging_allow" msgid="4573224609684957886">"مجاز است"</string> + <string name="wifi_debugging_allow" msgid="4573224609684957886">"اجازه دادن"</string> <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"اشکالزدایی بیسیم مجاز نیست"</string> <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"کاربری که درحالحاضر در این دستگاه به سیستم وارد شده است نمیتواند اشکالزدایی بیسیم را روشن کند. برای استفاده از این ویژگی، به کاربر اصلی بروید."</string> <string name="usb_contaminant_title" msgid="894052515034594113">"درگاه USB غیرفعال شده است"</string> @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"چرخش خودکار"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"چرخش خودکار صفحهنمایش"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"مکان"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"دسترسی به دوربین"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"دسترسی به میکروفون"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"دردسترس"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"افزودن کارت"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"درحال بهروزرسانی"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"برای استفاده، قفل را باز کنید"</string> <string name="wallet_error_generic" msgid="257704570182963611">"هنگام دریافت کارتها مشکلی پیش آمد، لطفاً بعداً دوباره امتحان کنید"</string> @@ -723,14 +725,13 @@ <string name="slice_permission_text_1" msgid="6675965177075443714">"- میتواند اطلاعات <xliff:g id="APP">%1$s</xliff:g> را بخواند"</string> <string name="slice_permission_text_2" msgid="6758906940360746983">"- میتواند در <xliff:g id="APP">%1$s</xliff:g> اقدام انجام دهد"</string> <string name="slice_permission_checkbox" msgid="4242888137592298523">"به <xliff:g id="APP">%1$s</xliff:g> اجازه داده شود تکههایی از برنامهها نشان دهد"</string> - <string name="slice_permission_allow" msgid="6340449521277951123">"مجاز"</string> + <string name="slice_permission_allow" msgid="6340449521277951123">"اجازه دادن"</string> <string name="slice_permission_deny" msgid="6870256451658176895">"مجاز نبودن"</string> <string name="auto_saver_title" msgid="6873691178754086596">"برای زمانبندی «بهینهسازی باتری» ضربه بزنید"</string> <string name="auto_saver_text" msgid="3214960308353838764">"وقتی باتری روبهاتمام است، بهینهسازی باتری را روشن کنید"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"نه متشکرم"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"استفاده شده"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"برنامهها از <xliff:g id="TYPES_LIST">%s</xliff:g> شما استفاده میکنند."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" و "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"برای پخش در <xliff:g id="DEVICENAME">%1$s</xliff:g> به دستگاه نزدیکتر شوید"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"برای پخش در اینجا، به <xliff:g id="DEVICENAME">%1$s</xliff:g> نزدیکتر شوید"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"درحال پخش در <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"درحال پخش در این تلفن"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"مشکلی پیش آمد. دوباره امتحان کنید."</string> <string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string> <string name="controls_error_removed" msgid="6675638069846014366">"پیدا نشد"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ذخیره کردن"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"درحال شروع…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"همهفرستی انجام نشد"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ذخیره نشد. دوباره امتحان کنید."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ذخیره نشد."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریدهدان کپی شد."</string> <string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"ویرایش نوشتار کپیشده"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ویرایش تصویر کپیشده"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ارسال به دستگاهی در اطراف"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml index ecc8d1cc7b13..8ff13727e51d 100644 --- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"خاموش"</item> <item msgid="460891964396502657">"روشن"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index e2483f0ba41a..1a64ee789029 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Yritä ottaa kuvakaappaus uudelleen."</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kuvakaappausta ei voi tallentaa"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Sovellus tai organisaatio ei salli kuvakaappauksien tallentamista."</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT-järjestelmänvalvoja on estänyt kuvakaappauksien ottamisen."</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Muuta"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Muokkaa kuvakaappausta"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Jaa kuvakaappaus"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automaattinen kääntö"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Käännä näyttöä automaattisesti."</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Sijainti"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pääsy kameraan"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pääsy mikrofoniin"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Käytettävissä"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Lisää maksutapa, niin voit maksaa nopeasti ja turvallisesti puhelimella"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Näytä kaikki"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Lisää kortti"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Päivitetään"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Avaa lukitus ja käytä"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Korttien noutamisessa oli ongelma, yritä myöhemmin uudelleen"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Ota käyttöön, jos akku todennäköisesti loppuu"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ei kiitos"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Luo SysUI-keon vedos"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Käytössä"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"<xliff:g id="TYPES_LIST">%s</xliff:g> ovat sovellusten käytössä."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ja "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Siirry lähemmäs, jotta <xliff:g id="DEVICENAME">%1$s</xliff:g> voi toistaa tämän"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Siirrä <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemmäs toistaaksesi täällä"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Toistetaan: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Toistetaan tällä puhelimella"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Jotain meni pieleen. Yritä uudelleen."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Epäaktiivinen, tarkista sovellus"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ei löydy"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Tallenna"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Aloitetaan…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei voi lähettää"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tallennus ei onnistu. Yritä uudelleen."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tallennus ei onnistu."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string> <string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Muokkaa kopioitua tekstiä"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Muokkaa kopioitua kuvaa"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Lähetä lähellä olevaan laitteeseen"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml index 5844fb9b79c5..9fc844530407 100644 --- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Poissa päältä"</item> <item msgid="460891964396502657">"Päällä"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index d09246e53571..7d94babbbb99 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Essayez de faire une autre capture d\'écran"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Impossible d\'enregistrer la capture d\'écran"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'application ou votre organisation n\'autorise pas les saisies d\'écran"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"La prise de captures d\'écran est bloquée par votre administrateur informatique"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Modifier"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Modifier la capture d\'écran"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Partagez la capture d\'écran"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation automatique"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accès à l\'appareil photo"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accès au micro"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Accessible"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Préparez-vous à faire des achats plus rapidement et de façon plus sûre avec votre téléphone"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Tout afficher"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Ajouter une carte"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Mise à jour en cours…"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Déverrouiller pour utiliser"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Un problème est survenu lors de la récupération de vos cartes, veuillez réessayer plus tard"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Activer si la pile est susceptible de s\'épuiser totalement"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Non merci"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Copier mémoire SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"En cours d\'utilisation"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Rapprochez-vous pour faire jouer le contenu sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Rapprochez-vous de <xliff:g id="DEVICENAME">%1$s</xliff:g> pour lire le contenu"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lecture sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Lecture sur ce téléphone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Enregistrer"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Démarrage en cours…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossible d\'enregistrer. Réessayez."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossible d\'enregistrer."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string> <string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifier le texte copié"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifier l\'image copiée"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Envoyer à un appareil à proximité"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml index 9d78e91f0f69..7acbb70727c5 100644 --- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Désactivé"</item> <item msgid="460891964396502657">"Activé"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 471b2976a598..1ef5b0c58890 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Essayez de nouveau de faire une capture d\'écran"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Impossible d\'enregistrer la capture d\'écran"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Les captures d\'écran ne sont pas autorisées par l\'application ni par votre organisation"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"La prise de captures d\'écran est bloquée par votre administrateur informatique"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Modifier"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Modifier la capture d\'écran"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Partager la capture d\'écran"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation automatique"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accès à l\'appareil photo"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accès au micro"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Configurez un mode de paiement pour régler vos achats de façon sûre et rapide via votre téléphone"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Tout afficher"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Ajouter une carte"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Mise à jour…"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Déverrouiller pour utiliser"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Problème de récupération de vos cartes. Réessayez plus tard"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Activer l\'économiseur de batterie si l\'autonomie restante risque d\'être insuffisante"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Non, merci"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Copier mémoire SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"En cours d\'utilisation"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Rapprochez-vous pour lire sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Rapprochez l\'appareil pour transférer la diffusion à votre <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lecture sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Lire sur ce téléphone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Enregistrer"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Démarrage…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossible d\'enregistrer. Réessayez."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossible d\'enregistrer."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string> <string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifier le texte copié"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifier l\'image copiée"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Envoyer à un appareil à proximité"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml index 47fa9c571402..eff302850c98 100644 --- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Désactivé"</item> <item msgid="460891964396502657">"Activé"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index c9beea95cea1..dbdad34cad54 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Volve tentar crear unha captura de pantalla"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Non se puido gardar a captura de pantalla"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"A aplicación ou a túa organización non permite realizar capturas de pantalla"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"O teu administrador de TI bloqueou a opción de facer capturas de pantalla"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar a captura de pantalla"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura de pantalla"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Xirar automaticamente"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Xirar pantalla automaticamente"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Localización"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acceso á cámara"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acceso ao micrófono"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dispoñible"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Configura un método de pago para comprar de xeito máis rápido e seguro co teléfono"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Amosar todo"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Engadir tarxeta"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Actualizando"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Produciuse un problema ao obter as tarxetas. Téntao de novo máis tarde"</string> @@ -529,7 +531,7 @@ <string name="feedback_prompt" msgid="3656728972307896379">"Faille saber a túa opinión ao programador. A información era correcta?"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Abríronse os controis de notificacións da aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"Pecháronse os controis de notificacións da aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="notification_more_settings" msgid="4936228656989201793">"Máis opcións"</string> + <string name="notification_more_settings" msgid="4936228656989201793">"Máis opcións de configuración"</string> <string name="notification_app_settings" msgid="8963648463858039377">"Personalizar"</string> <string name="notification_conversation_bubble" msgid="2242180995373949022">"Mostrar burbulla"</string> <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Quitar burbullas"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Activa a función se prevés que a batería pode esgotarse"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Non, grazas"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Baleirado mem. SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"En uso"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hai aplicacións que están utilizando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Achega o dispositivo para reproducir o contido en: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Achégate ao dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>) para reproducir o contido neste"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducindo contido noutro dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproducindo contido neste teléfono"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Produciuse un erro. Téntao de novo."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Non se atopou"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Gardar"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Non se puido iniciar a emisión"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Non se puido gardar a información. Téntao de novo."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Non se pode gardar a información."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string> <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imaxe copiada"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar a dispositivo próximo"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml index 229836c76e09..7832c4cb48cb 100644 --- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Desactivado"</item> <item msgid="460891964396502657">"Activado"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 0ee4ffe1228d..3d661a616c8d 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"તમારા IT ઍડમિન દ્વારા સ્ક્રીનશૉટ લેવાની સુવિધા બ્લૉક કરવામાં આવી છે"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ઑટો રોટેટ"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ઑટો રોટેટ સ્ક્રીન"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"સ્થાન"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"કૅમેરાનો ઍક્સેસ"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"માઇકનો ઍક્સેસ"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ઉપલબ્ધ છે"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"કોઈ કાર્ડ ઉમેરો"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"અપડેટ કરી રહ્યાં છીએ"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ઉપયોગ કરવા માટે અનલૉક કરો"</string> <string name="wallet_error_generic" msgid="257704570182963611">"તમારા કાર્ડની માહિતી મેળવવામાં સમસ્યા આવી હતી, કૃપા કરીને થોડા સમય પછી ફરી પ્રયાસ કરો"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"જ્યારે બૅટરી સંભવિત રૂપે પૂરી થવામાં હોય ત્યારે બૅટરી સેવર ચાલુ કરો"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"ના, આભાર"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"ઉપયોગમાં છે"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ઍપ્લિકેશન તમારા <xliff:g id="TYPES_LIST">%s</xliff:g>નો ઉપયોગ કરી રહી છે."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" અને "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> પર ચલાવવા માટે વધુ નજીક ખસેડો"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"આમાં ચલાવવા માટે ડિવાઇસને <xliff:g id="DEVICENAME">%1$s</xliff:g>ની નજીક ખસેડો"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> પર ચલાવવામાં આવી રહ્યું છે"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"આ ફોન પર ચલાવવામાં આવી રહ્યું છે"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"કંઈક ખોટું થયું. ફરી પ્રયાસ કરો."</string> <string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string> <string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"સાચવો"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"શરૂ થઈ રહ્યું છે…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"બ્રોડકાસ્ટ કરી શકતા નથી"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"સાચવી શકતા નથી. ફરી પ્રયાસ કરો."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"સાચવી શકતા નથી."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string> <string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"કૉપિ કરેલી ટેક્સ્ટમાં ફેરફાર કરો"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"કૉપિ કરેલી છબીમાં ફેરફાર કરો"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"નજીકના ડિવાઇસને મોકલો"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml index c502ba3e1ffa..244597bee8e4 100644 --- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"બંધ છે"</item> <item msgid="460891964396502657">"ચાલુ છે"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-h800dp/dimens.xml b/packages/SystemUI/res/values-h800dp/dimens.xml index 1d6f279afc66..e6af6f46ae69 100644 --- a/packages/SystemUI/res/values-h800dp/dimens.xml +++ b/packages/SystemUI/res/values-h800dp/dimens.xml @@ -16,7 +16,7 @@ <resources> <!-- Minimum margin between clock and top of screen or ambient indication --> - <dimen name="keyguard_clock_top_margin">38dp</dimen> + <dimen name="keyguard_clock_top_margin">26dp</dimen> <!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) --> <dimen name="large_clock_text_size">200dp</dimen> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 46d0249b8f7d..63df720c4c33 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रीन का अपने-आप दिशा बदलना (ऑटो-रोटेट)"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"जगह"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"कैमरे का ऐक्सेस"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"माइक्रोफ़ोन का ऐक्सेस"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"उपलब्ध"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"कार्ड जोड़ें"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"अपडेट हो रहा है"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"इस्तेमाल करने के लिए, डिवाइस अनलॉक करें"</string> <string name="wallet_error_generic" msgid="257704570182963611">"आपके कार्ड की जानकारी पाने में कोई समस्या हुई है. कृपया बाद में कोशिश करें"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"जब बैटरी खत्म होने वाली हो तब \'बैटरी सेवर\' चालू करें"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"जी नहीं, शुक्रिया"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"इस्तेमाल किया जा रहा है"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ऐप्लिकेशन आपकी <xliff:g id="TYPES_LIST">%s</xliff:g> का इस्तेमाल कर रहे हैं."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" और "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> पर मीडिया चलाने के लिए, अपने डिवाइस को उसके पास ले जाएं"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"अपने डिवाइस पर मीडिया फ़ाइल ट्रांसफ़र करने के लिए, उसे <xliff:g id="DEVICENAME">%1$s</xliff:g> के पास ले जाएं"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> पर मीडिया चल रहा है"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"इस फ़ोन पर मीडिया चल रहा है"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"कोई गड़बड़ी हुई. फिर से कोशिश करें."</string> <string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string> <string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल नहीं है"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"सेव करें"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"शुरू हो रहा है…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट नहीं किया जा सकता"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेव नहीं किया जा सका. फिर से कोशिश करें."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेव नहीं किया जा सका."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string> <string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"कॉपी किए गए टेक्स्ट में बदलाव करें"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"कॉपी की गई इमेज में बदलाव करें"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"कॉन्टेंट को आस-पास मौजूद डिवाइस पर भेजें"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml index 9af07bc65b8c..792536657a28 100644 --- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"बंद है"</item> <item msgid="460891964396502657">"चालू है"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index fb1bcd100ff6..a9328316f604 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Pokušajte ponovo napraviti snimku zaslona"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nije moguće spremiti snimku zaslona"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ili vaša organizacija ne dopuštaju snimanje zaslona"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Izradu snimki zaslona blokirao je IT administrator"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Uredi"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Uređivanje snimke zaslona"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Podijeli snimku zaslona"</string> @@ -228,6 +227,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. zakretanje"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko zakretanje zaslona"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup fotoaparatu"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pristup mikrofonu"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupno"</string> @@ -472,7 +473,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Novčanik"</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="530725155985223497">"Dodajte karticu"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ažuriranje"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključajte da biste koristili"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Pojavio se problem prilikom dohvaćanja kartica, pokušajte ponovo kasnije"</string> @@ -734,8 +736,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Uključite kad bi se baterija mogla isprazniti"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji mem. SysUI-a"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"U upotrebi"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije upotrebljavaju <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string> @@ -834,7 +835,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite se radi reprodukcije na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da biste na njemu reproducirali"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducira se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Reproducira se na ovom telefonu"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije u redu. Pokušajte ponovo."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, provjerite aplik."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string> @@ -864,6 +864,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Spremi"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pokretanje…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitiranje nije uspjelo"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Spremanje nije uspjelo. Pokušajte ponovo."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Spremanje nije uspjelo."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string> <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string> @@ -949,6 +951,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Uredi kopirani tekst"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Uredi kopiranu sliku"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošalji uređaju u blizini"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Dodaj"</string> <string name="manage_users" msgid="1823875311934643849">"Upravljanje korisnicima"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Ova obavijest ne podržava povlačenje na podijeljeni zaslon."</string> diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml index a057c48bbec9..0aa3475f05c5 100644 --- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Isključeno"</item> <item msgid="460891964396502657">"Uključeno"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 8e7ada393824..2c081c3ec382 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Próbálja meg újra elkészíteni a képernyőképet"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nem lehetséges a képernyőkép mentése"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Az alkalmazás vagy az Ön szervezete nem engedélyezi képernyőkép készítését"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"A képernyőkép készítésének lehetőségét a rendszergazda letiltotta"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Szerkesztés"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Képernyőkép szerkesztése"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Képernyőkép megosztása"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatikus elforgatás"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatikus képernyőforgatás"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Tartózkodási hely"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Hozzáférés a kamerához"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonelérés"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Rendelkezésre áll"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Végezze el a beállítást a telefonjával való gyorsabb és biztonságosabb vásárláshoz"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Összes mutatása"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Kártya hozzáadása"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Frissítés"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Oldja fel a használathoz"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Probléma merült fel a kártyák lekérésekor, próbálja újra később"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Kapcsolja be, ha az akkumulátor hamarosan lemerül"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nem"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI-memória-kiírás"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Használatban"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Több alkalmazás használja a következőket: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" és "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Menjen közelebb a következőn való lejátszáshoz: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Menjen közelebb a(z) <xliff:g id="DEVICENAME">%1$s</xliff:g> eszközhöz, hogy itt játszhassa le a tartalmat"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lejátszás folyamatban a(z) <xliff:g id="DEVICENAME">%1$s</xliff:g> eszközön"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Lejátszás ezen a telefonon"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Hiba történt. Próbálkozzon újra."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktív, ellenőrizze az appot"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nem található"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Mentés"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Indítás…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nem sikerült a közvetítés"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"A mentés nem sikerült. Próbálja újra."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"A mentés nem sikerült."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string> <string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Vágólapra másolt szöveg szerkesztése"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Vágólapra másolt kép szerkesztése"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Küldés közeli eszközre"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml index 47109a334e6d..80d6f99b3e6c 100644 --- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Ki"</item> <item msgid="460891964396502657">"Be"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index e4ba3567b5ec..4cd8b1b0e97c 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ինքնապտտում"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ավտոմատ պտտել էկրանը"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Տեղորոշում"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Տեսախցիկի հասանելիություն"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Խոսափողի հասանելիություն"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Հասանելի է"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"Ավելացնել քարտ"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Թարմացվում է"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ապակողպել՝ օգտագործելու համար"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Չհաջողվեց բեռնել քարտերը։ Նորից փորձեք։"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Միացնել էներգախնայումը, երբ մարտկոցի լիցքը գրեթե սպառված է"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ոչ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Օգտագործվում է"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Հավելվածներն օգտագործում են ձեր <xliff:g id="TYPES_LIST">%s</xliff:g>:"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" և "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ավելի մոտ եկեք՝ <xliff:g id="DEVICENAME">%1$s</xliff:g> սարքում նվագարկելու համար"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ավելի մոտեցեք «<xliff:g id="DEVICENAME">%1$s</xliff:g>» սարքին՝ նվագարկումը սկսելու համար"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Նվագարկվում է «<xliff:g id="DEVICENAME">%1$s</xliff:g>» սարքում"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Նվագարկվում է այս հեռախոսում"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Սխալ առաջացավ։ Նորից փորձեք։"</string> <string name="controls_error_timeout" msgid="794197289772728958">"Ակտիվ չէ, ստուգեք հավելվածը"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Չի գտնվել"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Պահել"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Սկսվում է…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Չհաջողվեց հեռարձակել"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Չհաջողվեց պահել։ Նորից փորձեք։"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Չհաջողվեց պահել։"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string> <string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Փոփոխել պատճենված տեքստը"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Փոփոխել պատճենված պատկերը"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Ուղարկել մոտակա սարքի"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml index a78b7a10e58e..4e33db2c02e2 100644 --- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Անջատված է"</item> <item msgid="460891964396502657">"Միացված է"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 8e3ce5cb68c0..32b7089aa7ba 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Coba ambil screenshot lagi"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Tidak dapat menyimpan screenshot"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Mengambil screenshot tidak diizinkan oleh aplikasi atau organisasi"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Mengambil screenshot diblokir oleh admin IT Anda"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Mengedit screenshot"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Bagikan screenshot"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Putar Otomatis"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Putar layar otomatis"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Akses kamera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Akses mikrofon"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tersedia"</string> @@ -427,8 +428,8 @@ <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Aplikasi akan terus ditampilkan sampai sematan dilepaskan. Geser ke atas dan tahan agar sematan lepas."</string> <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Ini akan terus ditampilkan sampai Anda melepas sematan. Sentuh lama tombol Ringkasan untuk melepas sematan."</string> <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Ini akan terus ditampilkan sampai Anda melepas sematan. Sentuh lama tombol Beranda untuk melepas sematan."</string> - <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Data pribadi dapat diakses (seperti kontak dan konten email)."</string> - <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Aplikasi yang disematkan dapat membuka aplikasi lain."</string> + <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Data pribadi mungkin dapat diakses (seperti kontak dan konten email)."</string> + <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Aplikasi yang disematkan mungkin dapat membuka aplikasi lain."</string> <string name="screen_pinning_toast" msgid="8177286912533744328">"Untuk melepas sematan aplikasi ini, sentuh lama tombol Kembali dan Ringkasan"</string> <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Untuk melepas sematan aplikasi ini, sentuh lama tombol Kembali dan Layar utama"</string> <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Untuk melepas sematan aplikasi ini, geser ke atas & tahan"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Siapkan metode pembayaran untuk melakukan pembelian dengan lebih cepat dan aman menggunakan ponsel Anda"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Tampilkan semua"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Tambahkan kartu"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Memperbarui"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Buka kunci untuk menggunakan"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Terjadi masalah saat mendapatkan kartu Anda, coba lagi nanti"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Aktifkan jika daya baterai kemungkinan akan habis"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Tidak, terima kasih"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Hapus Heap SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Sedang digunakan"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikasi menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dan "</string> @@ -782,7 +783,7 @@ <string name="accessibility_control_move" msgid="8980344493796647792">"Pindah ke posisi <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrol"</string> <string name="controls_favorite_subtitle" msgid="6481675111056961083">"Pilih kontrol untuk diakses dari Setelan Cepat"</string> - <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tahan & tarik untuk mengatur ulang kontrol"</string> + <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tahan & tarik untuk menata ulang kontrol"</string> <string name="controls_favorite_removed" msgid="5276978408529217272">"Semua kontrol dihapus"</string> <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Perubahan tidak disimpan"</string> <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Lihat aplikasi lainnya"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Dekatkan untuk memutar di <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Dekatkan ke <xliff:g id="DEVICENAME">%1$s</xliff:g> untuk memutar di sini"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Diputar di <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Diputar di ponsel ini"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Terjadi error. Coba lagi."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Simpan"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Memulai …"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat menyiarkan"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tidak dapat menyimpan. Coba lagi."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tidak dapat menyimpan."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string> <string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit teks yang disalin"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit gambar yang disalin"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Kirim ke perangkat di sekitar"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml index 6f81b29990cd..3a2fd93664be 100644 --- a/packages/SystemUI/res/values-in/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Nonaktif"</item> <item msgid="460891964396502657">"Aktif"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 8e3f5553ed0e..bf3366bf6b9d 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prófaðu að taka skjámynd aftur"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ekki er hægt að vista skjámynd"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Forritið eða fyrirtækið þitt leyfir ekki skjámyndatöku"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Kerfisstjórinn lokaði á skjámyndatöku"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Breyta"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Breyta skjámynd"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Deila skjámynd"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Sjálfvirkur snúningur"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Snúa skjá sjálfkrafa"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Staðsetning"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Aðgangur að myndavél"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Aðgangur að hljóðnema"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tiltækt"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Veski"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Stilltu hlutina þannig að þú getir verslað með símanum á hraðari og öruggari hátt"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Sýna allt"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Bæta korti við"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Uppfærir"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Taktu úr lás til að nota"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Vandamál kom upp við að sækja kortin þín. Reyndu aftur síðar"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Kveikja þegar rafhlaða er við það að klárast"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nei, takk"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Vista SysUI-gögn"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Í notkun"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Forrit eru að nota <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Færðu nær til að spila í <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Færðu tækið nær <xliff:g id="DEVICENAME">%1$s</xliff:g> til að spila hér"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Í spilun í <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Í spilun í þessum síma"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Eitthvað fór úrskeiðis. Reyndu aftur."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Fannst ekki"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Vista"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Ræsir…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ekki hægt að senda út"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ekki hægt að vista. Reyndu aftur."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ekki hægt að vista."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string> <string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Breyta afrituðum texta"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Breyta afritaðri mynd"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Senda í nálægt tæki"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml index 29bce8257913..f4b12f2d2da1 100644 --- a/packages/SystemUI/res/values-is/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Slökkt"</item> <item msgid="460891964396502657">"Kveikt"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index bb774b284472..837a54c3aa07 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Riprova ad acquisire lo screenshot"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Impossibile salvare lo screenshot"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'acquisizione di screenshot non è consentita dall\'app o dall\'organizzazione"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"L\'acquisizione di screenshot è stata bloccata dall\'amministratore IT"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Modifica"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Modifica screenshot"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Condividi screenshot"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotazione automatica"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotazione automatica dello schermo"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Geolocalizzazione"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accesso alla fotocamera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accesso al microfono"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponibile"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Portafoglio"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Imposta un metodo di pagamento per effettuare acquisti in modo più rapido e sicuro con il telefono"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Espandi"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Aggiungi una carta"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Aggiornamento in corso…"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Sblocca per usare"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Si è verificato un problema durante il recupero delle tue carte. Riprova più tardi."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Attiva questa funzionalità se è probabile che la batteria si scarichi"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"No grazie"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump heap SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In uso"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Le app stanno usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Avvicinati per riprodurre su <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Avvicinati a <xliff:g id="DEVICENAME">%1$s</xliff:g> per riprodurre i contenuti qui"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"In riproduzione su <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"In riproduzione su questo telefono"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Si è verificato un errore. Riprova."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inattivo, controlla l\'app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Controllo non trovato"</string> @@ -856,8 +856,10 @@ <string name="media_output_broadcast_name" msgid="8786127091542624618">"Nome annuncio"</string> <string name="media_output_broadcast_code" msgid="870795639644728542">"Password"</string> <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salva"</string> - <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Avvio in corso…"</string> + <string name="media_output_broadcast_starting" msgid="8130153654166235557">"In fase di avvio"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossibile trasmettere"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossibile salvare. Riprova."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossibile salvare."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string> <string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifica testo copiato"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifica immagine copiata"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Invia a dispositivo nelle vicinanze"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml index 757a866463e6..fc24b0b6fe25 100644 --- a/packages/SystemUI/res/values-it/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Off"</item> <item msgid="460891964396502657">"On"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index d5e27c033daa..85b4b8da0606 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"יצירת צילומי המסך נחסמה על ידי מנהל ה-IT"</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> @@ -229,6 +228,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"סיבוב אוטומטי"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"סיבוב אוטומטי של המסך"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"מיקום"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"גישה למצלמה"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"גישה למיקרופון"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"יש גישה"</string> @@ -250,7 +251,7 @@ <string name="quick_settings_inversion_label" msgid="3501527749494755688">"היפוך צבעים"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"תיקון צבע"</string> <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"הגדרות המשתמש"</string> - <string name="quick_settings_done" msgid="2163641301648855793">"בוצע"</string> + <string name="quick_settings_done" msgid="2163641301648855793">"סיום"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"סגירה"</string> <string name="quick_settings_connected" msgid="3873605509184830379">"מחובר"</string> <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"המכשיר מחובר. סוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> @@ -475,7 +476,8 @@ <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="530725155985223497">"הוספת כרטיס"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"מתבצע עדכון"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"יש לבטל את הנעילה כדי להשתמש"</string> <string name="wallet_error_generic" msgid="257704570182963611">"הייתה בעיה בקבלת הכרטיסים שלך. כדאי לנסות שוב מאוחר יותר"</string> @@ -739,8 +741,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"מומלץ להפעיל את התכונה כשיש סבירות גבוהה שהסוללה תתרוקן"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"לא תודה"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"בשימוש"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"אפליקציות משתמשות ב<xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" וגם "</string> @@ -840,7 +841,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"צריך להתקרב כדי להפעיל מוזיקה במכשיר <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"צריך להתקרב אל <xliff:g id="DEVICENAME">%1$s</xliff:g> כדי להפעיל כאן"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"פועלת ב-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"פועלת בטלפון הזה"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"משהו השתבש. יש לנסות שוב."</string> <string name="controls_error_timeout" msgid="794197289772728958">"לא פעיל, יש לבדוק את האפליקציה"</string> <string name="controls_error_removed" msgid="6675638069846014366">"לא נמצא"</string> @@ -870,6 +870,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"שמירה"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"בתהליך הפעלה…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"לא ניתן לשדר"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"לא ניתן לשמור. כדאי לנסות שוב."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"לא ניתן לשמור."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"מספר Build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"מספר ה-Build הועתק ללוח."</string> <string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string> @@ -956,6 +958,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"עריכת הטקסט שהועתק"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"עריכת התמונה שהועתקה"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"שליחה למכשיר בקרבת מקום"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml index 46be20c1f64d..18c703839ebb 100644 --- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"כבוי"</item> <item msgid="460891964396502657">"פועל"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index f7deb9c0388d..5e8a0d682eb6 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"スクリーンショットの撮影は IT 管理者によってブロックされています。"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動回転"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"画面を自動回転します"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"位置情報"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"カメラへのアクセス"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"マイクへのアクセス"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"使用可能"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"カードを追加する"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"更新しています"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ロックを解除して使用"</string> <string name="wallet_error_generic" msgid="257704570182963611">"カードの取得中に問題が発生しました。しばらくしてからもう一度お試しください"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"電池切れになる可能性が高くなると有効になります"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"いいえ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ヒープのダンプ"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"使用中"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"アプリは<xliff:g id="TYPES_LIST">%s</xliff:g>を使用しています。"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 、 "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"スワイプすると他の構造が表示されます"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"候補を読み込んでいます"</string> <string name="controls_media_title" msgid="1746947284862928133">"メディア"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> のこのメディア コントロールを非表示にしますか?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> のこのコントロールを非表示にしますか?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"現在のメディア セッションは非表示にできません。"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"非表示"</string> <string name="controls_media_resume" msgid="1933520684481586053">"再開"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>で再生するにはもっと近づけてください"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ここで再生するには<xliff:g id="DEVICENAME">%1$s</xliff:g>に近づいてください"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>で再生しています"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"このスマートフォンで再生しています"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"エラーが発生しました。もう一度お試しください。"</string> <string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string> <string name="controls_error_removed" msgid="6675638069846014366">"見つかりませんでした"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"保存"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"開始しています…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ブロードキャストできません"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"保存できません。もう一度お試しください。"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"保存できません。"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string> <string name="basic_status" msgid="2315371112182658176">"空の会話"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"コピーしたテキストを編集"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"コピーした画像を編集"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"付近のデバイスに送信"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml index fd966da986b8..0a7a808258bf 100644 --- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"OFF"</item> <item msgid="460891964396502657">"ON"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index deb8de1fb4b8..39ff4a8bdafe 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ეკრანის ანაბეჭდის გადაღება დაბლოკილია თქვენი IT ადმინისტრატორის მიერ"</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> @@ -227,6 +226,7 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ავტოროტაცია"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ეკრანის ავტომატური შეტრიალება"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"მდებარეობა"</string> + <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"ეკრანმზოგი"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"კამერაზე წვდომა"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"მიკროფონზე წვდომა"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ხელმისაწვდომი"</string> @@ -469,7 +469,7 @@ <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="530725155985223497">"ბარათის დამატება"</string> + <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"შეეხეთ გასახსნელად"</string> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"მიმდინარეობს განახლება"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"გამოსაყენებლად განბლოკვა"</string> <string name="wallet_error_generic" msgid="257704570182963611">"თქვენი ბარათების მიღებისას პრობლემა წარმოიშვა. ცადეთ ხელახლა მოგვიანებით"</string> @@ -729,8 +729,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ჩაირთოს, როცა ბატარეა დაცლის პირას არის"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"არა, გმადლობთ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI გროვის გამოტანა"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"გამოიყენება"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"აპლიკაციების მიერ გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" და "</string> @@ -828,7 +827,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"მიიტანეთ უფრო ახლოს, რომ დაუკრათ <xliff:g id="DEVICENAME">%1$s</xliff:g>-ზე"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"მიუახლოვდით <xliff:g id="DEVICENAME">%1$s</xliff:g>-ს მისი მეშვეობით დასაკრავად"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"მიმდინარეობს დაკვრა <xliff:g id="DEVICENAME">%1$s</xliff:g>-ზე"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"მიმდინარეობს დაკვრა ამ ტელეფონზე"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"რაღაც შეცდომა მოხდა. ცადეთ ხელახლა."</string> <string name="controls_error_timeout" msgid="794197289772728958">"არააქტიურია, გადაამოწმეთ აპი"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ვერ მოიძებნა"</string> @@ -858,6 +856,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"შენახვა"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"იწყება…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ტრანსლაცია შეუძლებელია"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"შენახვა ვერ ხერხდება. ცადეთ ხელახლა."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"შენახვა ვერ ხერხდება."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string> <string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string> @@ -942,6 +942,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"კოპირებული ტექსტის რედაქტირება"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"კოპირებული სურათის რედაქტირება"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ახლომახლო მოწყობილობაზე გაგზავნა"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml index 0c7d5af29890..c95187404d48 100644 --- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml @@ -171,4 +171,9 @@ <item msgid="146088982397753810">"გამორთვა"</item> <item msgid="460891964396502657">"ჩართვა"</item> </string-array> + <string-array name="tile_states_dream"> + <item msgid="6184819793571079513">"მიუწვდომელია"</item> + <item msgid="8014986104355098744">"გამორთულია"</item> + <item msgid="5966994759929723339">"ჩართულია"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 70dcdcc7e36e..bff42de9d702 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматты түрде бұру"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматты айналатын экран"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Локация"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Камераны пайдалану"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Микрофонды пайдалану"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Қолжетімді"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"Карта қосу"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Жаңартылуда"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Пайдалану үшін құлыпты ашу"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Карталарыңыз алынбады, кейінірек қайталап көріңіз."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Батареяның заряды бітуге жақындағанда қосыңыз."</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Жоқ, рақмет"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Қолданыста"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Қолданбаларда <xliff:g id="TYPES_LIST">%s</xliff:g> пайдаланылуда."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" және "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Толығырақ ақпарат алу үшін сырғытыңыз."</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Жүктеуге қатысты ұсыныстар"</string> <string name="controls_media_title" msgid="1746947284862928133">"Мультимедиа"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін медиамазмұн контроллері жасырылсын ба?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін медиа контроллері жасырылсын ба?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Ағымдағы мультимедиа сеансын жасыру мүмкін емес."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жасыру"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Жалғастыру"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысында музыка ойнату үшін оған жақындаңыз."</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Осы жерде ойнау үшін <xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысына жақындаңыз"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысында ойнатылуда."</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Осы телефонда ойнатылуда."</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Бірдеңе дұрыс болмады. Қайталап көріңіз."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Табылмады"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сақтау"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Басталып жатыр…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Тарату мүмкін емес"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Сақталмайды. Қайталап көріңіз."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Сақталмайды."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string> <string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Көшірілген мәтінді өңдеу"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Көшірілген суретті өңдеу"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Маңайдағы құрылғыға жіберу"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml index 546666327e69..3615a3a0f5ad 100644 --- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Өшірулі"</item> <item msgid="460891964396502657">"Қосулы"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 3adb680fb24f..edf08bcd16b0 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"បង្វិលស្វ័យប្រវត្តិ"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"បង្វិលអេក្រង់ស្វ័យប្រវត្តិ"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"ទីតាំង"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"ការចូលប្រើកាមេរ៉ា"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"ការចូលប្រើមីក្រូហ្វូន"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"អាចចូលប្រើបាន"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"បញ្ចូលកាត"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"កំពុងធ្វើបច្ចុប្បន្នភាព"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ដោះសោដើម្បីប្រើប្រាស់"</string> <string name="wallet_error_generic" msgid="257704570182963611">"មានបញ្ហាក្នុងការទាញយកកាតរបស់អ្នក សូមព្យាយាមម្ដងទៀតនៅពេលក្រោយ"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"បើកនៅពេលថ្មទំនងជាអស់"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"ទេ អរគុណ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"កំពុងប្រើ"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"កម្មវិធីកំពុងប្រើ <xliff:g id="TYPES_LIST">%s</xliff:g> របស់អ្នក។"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" និង "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"រំកិលឱ្យកាន់តែជិត ដើម្បីចាក់នៅលើ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"រំកិលឱ្យកាន់តែជិត <xliff:g id="DEVICENAME">%1$s</xliff:g> ដើម្បីចាក់នៅទីនេះ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"កំពុងចាក់នៅលើ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"កំពុងចាក់នៅលើទូរសព្ទនេះ"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"</string> <string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើលកម្មវិធី"</string> <string name="controls_error_removed" msgid="6675638069846014366">"រកមិនឃើញទេ"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"រក្សាទុក"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"កំពុងចាប់ផ្ដើម…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"មិនអាចផ្សាយបានទេ"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"មិនអាចរក្សាទុកបានទេ។ សូមព្យាយាមម្ដងទៀត។"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"មិនអាចរក្សាទុកបានទេ។"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខកំណែបង្កើត"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខកំណែបង្កើតទៅឃ្លីបបត។"</string> <string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"កែអត្ថបទដែលបានចម្លង"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"កែរូបភាពដែលបានចម្លង"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ផ្ញើទៅឧបករណ៍នៅជិត"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml index f4830f5bbb75..b9fab7120ba5 100644 --- a/packages/SystemUI/res/values-km/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"បិទ"</item> <item msgid="460891964396502657">"បើក"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index c63b8d28b31c..5322384afc29 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ನಿರ್ಬಂಧಿಸಿದ್ದಾರೆ"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ಸ್ವಯಂ-ತಿರುಗುವಿಕೆ"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ಪರದೆಯನ್ನು ಸ್ವಯಂ-ತಿರುಗಿಸಿ"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"ಸ್ಥಳ"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"ಕ್ಯಾಮರಾ ಆ್ಯಕ್ಸೆಸ್"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"ಮೈಕ್ ಆ್ಯಕ್ಸೆಸ್"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ಲಭ್ಯವಿದೆ"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"ಕಾರ್ಡ್ ಅನ್ನು ಸೇರಿಸಿ"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ಬಳಸಲು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string> <string name="wallet_error_generic" msgid="257704570182963611">"ನಿಮ್ಮ ಕಾರ್ಡ್ಗಳನ್ನು ಪಡೆಯುವಾಗ ಸಮಸ್ಯೆ ಉಂಟಾಗಿದೆ, ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ಬ್ಯಾಟರಿ ಖಾಲಿಯಾಗುವ ಸಾಧ್ಯತೆ ಇದ್ದಾಗ ಆನ್ ಮಾಡಿ"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"ಬೇಡ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"ಬಳಕೆಯಲ್ಲಿದೆ"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%s</xliff:g> ಅನ್ನು ಆ್ಯಪ್ಗಳು ಬಳಸುತ್ತಿವೆ."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ಮತ್ತು "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು ಅದರ ಹತ್ತಿರಕ್ಕೆ ಸರಿಯಿರಿ"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ಇಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು <xliff:g id="DEVICENAME">%1$s</xliff:g> ಸಮೀಪಕ್ಕೆ ಹೋಗಿ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಆಗುತ್ತಿದೆ"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ಈ ಫೋನ್ನಲ್ಲಿ ಪ್ಲೇ ಆಗುತ್ತಿದೆ"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ಏನೋ ತಪ್ಪಾಗಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="controls_error_timeout" msgid="794197289772728958">"ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ಕಂಡುಬಂದಿಲ್ಲ"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ಉಳಿಸಿ"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ಪ್ರಸಾರ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್ಬೋರ್ಡ್ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string> <string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"ನಕಲಿಸಿದ ಪಠ್ಯವನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ನಕಲಿಸಿದ ಚಿತ್ರವನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಕ್ಕೆ ಕಳುಹಿಸಿ"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml index 5cf2f5c2661e..5109a7ce1742 100644 --- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"ಆಫ್ ಮಾಡಿ"</item> <item msgid="460891964396502657">"ಆನ್ ಮಾಡಿ"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index b08ee75d1d49..256fc5d53eb3 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT 관리자가 스크린샷 촬영을 허용하지 않습니다."</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"자동 회전"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"화면 자동 회전"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"위치"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"카메라 액세스"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"마이크 액세스"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"사용 가능"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"카드 추가"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"업데이트 중"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"잠금 해제하여 사용"</string> <string name="wallet_error_generic" msgid="257704570182963611">"카드를 가져오는 중에 문제가 발생했습니다. 나중에 다시 시도해 보세요."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"배터리가 소진될 것 같으면 사용 설정"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"사용 안함"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"사용 중"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"애플리케이션이 <xliff:g id="TYPES_LIST">%s</xliff:g>을(를) 사용 중입니다."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 및 "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"자세히 보려면 스와이프하세요."</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"추천 제어 기능 로드 중"</string> <string name="controls_media_title" msgid="1746947284862928133">"미디어"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 이 미디어 컨트롤 숨기기"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>에 대한 미디어 컨트롤을 숨길까요?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"현재 미디어 세션은 숨길 수 없습니다."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"숨기기"</string> <string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>에서 재생하려면 기기를 더 가까이로 옮기세요."</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"현재 기기에서 재생하려면 <xliff:g id="DEVICENAME">%1$s</xliff:g>에 더 가까이 이동합니다."</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>에서 재생 중"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"휴대전화에서 재생 중"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"문제가 발생했습니다. 다시 시도해 주세요."</string> <string name="controls_error_timeout" msgid="794197289772728958">"비활성. 앱을 확인하세요."</string> <string name="controls_error_removed" msgid="6675638069846014366">"찾을 수 없음"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"저장"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"시작 중…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"방송할 수 없음"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"저장할 수 없습니다. 다시 시도해 주세요."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"저장할 수 없습니다."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string> <string name="basic_status" msgid="2315371112182658176">"대화 열기"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"복사된 텍스트 편집"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"복사된 이미지 편집"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"근처 기기에 전송"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml index 3244ffaec49c..8bb62690c862 100644 --- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"꺼짐"</item> <item msgid="460891964396502657">"켜짐"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 6bd690f1f492..3db5e2e10825 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT администраторуңуз скриншот тартууга тыюу салган"</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> @@ -128,7 +127,7 @@ <string name="phone_label" msgid="5715229948920451352">"телефонду ачуу"</string> <string name="voice_assist_label" msgid="3725967093735929020">"үн жардамчысысын ачуу"</string> <string name="camera_label" msgid="8253821920931143699">"камераны ачуу"</string> - <string name="cancel" msgid="1089011503403416730">"Жокко чыгаруу"</string> + <string name="cancel" msgid="1089011503403416730">"Жок"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Ырастоо"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Кайталоо"</string> <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Аныктыгын текшерүүнү жокко чыгаруу үчүн таптаңыз"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Авто буруу"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Экранды авто буруу"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Жайгашкан жер"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Камера"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Микрофон"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Жеткиликтүү"</string> @@ -247,7 +248,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Жарыктыгы"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Түстөрдү инверсиялоо"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Түстөрдү тууралоо"</string> - <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"Колдонуучунун жөндөөлөрү"</string> + <string name="quick_settings_more_user_settings" msgid="1064187451100861954">"Колдонуучунун параметрлери"</string> <string name="quick_settings_done" msgid="2163641301648855793">"Бүттү"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Жабуу"</string> <string name="quick_settings_connected" msgid="3873605509184830379">"Туташкан"</string> @@ -341,14 +342,14 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Жай кубатталууда • Толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> калды"</string> <string name="keyguard_indication_charging_time_dock" msgid="6150404291427377863">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Кубаттоо догу • Толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> калды"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string> - <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана маалыматтар өчүрүлөт."</string> + <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана аларга байланыштуу нерселер өчүрүлөт."</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Кайтып келишиңиз менен!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансыңызды улантасызбы?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Кайра баштоо"</string> <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ооба, уланта берели"</string> <string name="guest_notification_app_name" msgid="2110425506754205509">"Конок режими"</string> <string name="guest_notification_session_active" msgid="5567273684713471450">"Конок режиминдесиз"</string> - <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Жаңы колдонуучуну кошсоңуз, конок режими жабылат жана учурдагы конок сеансындагы бардык колдонмолор жана дайындар өчүрүлөт."</string> + <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Жаңы колдонуучуну кошсоңуз, конок режими жабылып, учурдагы конок сеансындагы бардык колдонмолор жана башка нерселер өчүп калат."</string> <string name="user_limit_reached_title" msgid="2429229448830346057">"Дагы колдонуучу кошууга болбойт"</string> <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398"> <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> колдонуучуга чейин кошууга болот.</item> @@ -469,7 +470,8 @@ <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="530725155985223497">"Картаны кошуу"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Жаңырууда"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Колдонуу үчүн кулпусун ачыңыз"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Кыйытмаларды алууда ката кетти. Бир аздан кийин кайталап көрүңүз."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Батареянын кубаты түгөнүп калганда, күйгүзүлсүн"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Жок, рахмат"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Колдонулууда"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Колдонмолор төмөнкүлөрдү пайдаланып жатышат: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" жана "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Дагы көрүү үчүн экранды сүрүп коюңуз"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Сунуштар жүктөлүүдө"</string> <string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> үчүн бул медиафайлдарды башкаруу жашырылсынбы?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда ушул нерсени жашырасызбы?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Учурдагы медиа сеансын жашыруу мүмкүн эмес."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жашыруу"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Улантуу"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүндө ойнотуу үчүн жакыныраак жылдырыңыз"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Бул жерде ойнотуу үчүн <xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүнө жакындатыңыз"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> аркылуу ойнотулууда"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Ушул телефондо ойнотулууда"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Бир жерден ката кетти. Кайра аракет кылыңыз."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Жигерсиз. Колдонмону текшериңиз"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Табылган жок"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сактоо"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Кабарлап баштады…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Кабарлоого болбойт"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Сакталган жок. Кайталап көрүңүз."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Сакталган жок."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string> <string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Көчүрүлгөн текстти түзөтүү"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Көчүрүлгөн сүрөттү түзөтүү"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Жакын жердеги түзмөккө жөнөтүү"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml index 5518fccac6ee..b48a5261a99e 100644 --- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Өчүк"</item> <item msgid="460891964396502657">"Күйүк"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index d3a014e923b7..1a2ac1a2cb39 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ໝຸນອັດຕະໂນມັດ"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ໝຸນໜ້າຈໍອັດຕະໂນມັດ"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"ສະຖານທີ່"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"ການເຂົ້າເຖິງກ້ອງຖ່າຍຮູບ"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"ການເຂົ້າເຖິງໄມ"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ສາມາດໃຊ້ໄດ້"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"ເພີ່ມບັດ"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"ກຳລັງອັບເດດ"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ປົດລັອກເພື່ອໃຊ້"</string> <string name="wallet_error_generic" msgid="257704570182963611">"ເກີດບັນຫາໃນການໂຫຼດບັດຂອງທ່ານ, ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ເປີດໃຊ້ເມື່ອແບັດເຕີຣີໜ້າຈະໃກ້ໝົດ"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"ບໍ່, ຂອບໃຈ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"ກຳລັງນຳໃຊ້ຢູ່"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ແອັບພລິເຄຊັນກຳລັງໃຊ້ <xliff:g id="TYPES_LIST">%s</xliff:g> ຂອງທ່ານ."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ແລະ "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"ຍ້າຍໄປໃກ້ຂຶ້ນເພື່ອຫຼິ້ນຢູ່ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ກະລຸນາຍ້າຍເຂົ້າໃກ້ <xliff:g id="DEVICENAME">%1$s</xliff:g> ເພື່ອຫຼິ້ນຢູ່ບ່ອນນີ້"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"ກຳລັງຫຼິ້ນຢູ່ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ກຳລັງຫຼິ້ນຢູ່ໂທລະສັບນີ້"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນ. ກະລຸນາລອງໃໝ່."</string> <string name="controls_error_timeout" msgid="794197289772728958">"ບໍ່ເຮັດວຽກ, ກະລຸນາກວດສອບແອັບ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ບໍ່ພົບ"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ບັນທຶກ"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ກໍາລັງເລີ່ມ…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ບໍ່ສາມາດອອກອາກາດໄດ້"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ບໍ່ສາມາດບັນທຶກໄດ້. ກະລຸນາລອງໃໝ່."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ບໍ່ສາມາດບັນທຶກໄດ້."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string> <string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"ແກ້ໄຂຂໍ້ຄວາມທີ່ສຳເນົາແລ້ວ"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ແກ້ໄຂຮູບທີ່ສຳເນົາແລ້ວ"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ສົ່ງໄປຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml index c6b7e6c6e74d..4c20f48d3eb2 100644 --- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"ປິດ"</item> <item msgid="460891964396502657">"ເປີດ"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 8a7f43ed4155..06367472cc64 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Pabandykite padaryti ekrano kopiją dar kartą"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ekrano kopijos išsaugoti nepavyko"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Jūsų organizacijoje arba naudojant šią programą neleidžiama daryti ekrano kopijų"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Jūsų IT administratorius užblokavo galimybę daryti ekrano kopijas."</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Redaguoti"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Redaguoti ekrano kopiją"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Bendrinti ekrano kopiją"</string> @@ -229,6 +228,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatinis pasukimas"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatiškai sukti ekraną"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Vietovė"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Prieiga prie fotoaparato"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Prieiga prie mikrofono"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Pasiekiama"</string> @@ -475,7 +476,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Piniginė"</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="530725155985223497">"Pridėti kortelę"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Atnaujinama"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Atrakinti, kad būtų galima naudoti"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Gaunant korteles kilo problema, bandykite dar kartą vėliau"</string> @@ -739,8 +741,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Įjunkite, jei akumuliatorius gali greitai išsekti"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, ačiū"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Pat. „SysUI“ krūvą"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Naudojama"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programos naudoja: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ir "</string> @@ -840,7 +841,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Prieikite arčiau, kad galėtumėte leisti įrenginyje „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Perkelkite arčiau „<xliff:g id="DEVICENAME">%1$s</xliff:g>“, kad būtų galima leisti čia"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Leidžiama įrenginyje „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Leidžiama šiame telefone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Kažkas ne taip. Bandykite dar kartą."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktyvu, patikrinkite progr."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nerasta"</string> @@ -870,6 +870,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Išsaugoti"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pradedama…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nepavyko transliuoti"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nepavyko išsaugoti. Bandykite dar kartą."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nepavyko išsaugoti."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string> <string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string> @@ -956,6 +958,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Redaguoti nukopijuotą tekstą"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Redaguoti nukopijuotą vaizdą"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Siųsti į įrenginį netoliese"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml index 3e289e1f21ce..d6efe11ffa31 100644 --- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Išjungta"</item> <item msgid="460891964396502657">"Įjungta"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index c50ff1ea4836..06d1a74404b2 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Mēģiniet izveidot jaunu ekrānuzņēmumu."</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nevar saglabāt ekrānuzņēmumu"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Lietotne vai jūsu organizācija neatļauj veikt ekrānuzņēmumus."</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Jūsu IT administrators ir bloķējis ekrānuzņēmumu izveidi"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Rediģēt"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediģēt ekrānuzņēmumu"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Kopīgot ekrānuzņēmumu"</string> @@ -228,6 +227,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automātiska pagriešana"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automātiska ekrāna pagriešana"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Atrašanās vieta"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kamera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofons"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Piekļuve atļauta"</string> @@ -472,7 +473,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Maks"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Iestatiet, lai ātrāk un drošāk veiktu pirkumus, izmantojot tālruni"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Rādīt visu"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Pievienojiet karti"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Notiek atjaunināšana"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lai izmantotu, atbloķējiet ekrānu"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Ienesot jūsu kartes, radās problēma. Lūdzu, vēlāk mēģiniet vēlreiz."</string> @@ -734,8 +736,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Ieslēgt, ja akumulators var izlādēties"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nē, paldies"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Pašlaik izmanto"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Lietojumprogrammas izmanto šādas funkcijas: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" un "</string> @@ -834,7 +835,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Pārvietojiet savu ierīci tuvāk, lai atskaņotu mūziku ierīcē “<xliff:g id="DEVICENAME">%1$s</xliff:g>”."</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Pārvietojieties tuvāk ierīcei “<xliff:g id="DEVICENAME">%1$s</xliff:g>”, lai atskaņotu šeit"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Notiek atskaņošana ierīcē <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Notiek atskaņošana šajā tālrunī"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Radās kļūda. Mēģiniet vēlreiz."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Netika atrasta"</string> @@ -864,6 +864,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Saglabāt"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Notiek palaišana…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nevar apraidīt"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nevar saglabāt. Mēģiniet vēlreiz."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nevar saglabāt."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string> <string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string> @@ -949,6 +951,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Rediģēt nokopēto tekstu"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Rediģēt nokopēto attēlu"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Sūtīt uz tuvumā esošu ierīci"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml index eb210c24bb50..caa8876a2040 100644 --- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Izslēgts"</item> <item msgid="460891964396502657">"Ieslēgts"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 664c65fbac60..08a795433e24 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Зачувувањето слики од екранот е блокирано од IT-администраторот"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматско ротирање"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматско ротирање на екранот"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Пристап до камерата"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Пристап до микрофонот"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Дозволен"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"Додајте картичка"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Се ажурира"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Отклучете за да користите"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Имаше проблем при преземањето на картичките. Обидете се повторно подоцна"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Вклучи ако е веројатно дека батеријата ќе се испразни"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Не, фала"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Извади SysUI-слика"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Во употреба"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликациите користат <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Повлечете за да видите повеќе"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Се вчитуваат препораки"</string> <string name="controls_media_title" msgid="1746947284862928133">"Аудиовизуелни содржини"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Да се сокрие контролоров за аудиовизуелни содржини за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Да се сокријат контролите за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Аудиовизуелнава сесија не може да се сокрие."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сокриј"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Продолжи"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближете се за да пуштите на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g> за да пуштите тука"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пуштено на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Пуштено на овој телефон"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Нешто не е во ред. Обидете се повторно."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не е најдено"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Зачувај"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Се стартува…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не може да се емитува"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не може да се зачува. Обидете се повторно."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не може да се зачува."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string> <string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Изменете го копираниот текст"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Изменете ја копираната слика"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Испратете до уред во близина"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml index 78be6dda9184..5d21e5361992 100644 --- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Исклучен"</item> <item msgid="460891964396502657">"Вклучен"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 9f4b22c21033..e2d12f0aa81d 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"സ്ക്രീൻ സ്വയമേവ തിരിയൽ"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"സ്ക്രീൻ സ്വയമേവ തിരിക്കുക"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"ലൊക്കേഷൻ"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"ക്യാമറ ആക്സസ്"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"മൈക്ക് ആക്സസ്"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ലഭ്യമാണ്"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"കാർഡ് ചേർക്കുക"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"അപ്ഡേറ്റ് ചെയ്യുന്നു"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ഉപയോഗിക്കാൻ അൺലോക്ക് ചെയ്യുക"</string> <string name="wallet_error_generic" msgid="257704570182963611">"നിങ്ങളുടെ കാർഡുകൾ ലഭ്യമാക്കുന്നതിൽ ഒരു പ്രശ്നമുണ്ടായി, പിന്നീട് വീണ്ടും ശ്രമിക്കുക"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ബാറ്ററി ചാർജ് തീരാൻ സാധ്യതയുണ്ടെങ്കിൽ ഓണാക്കുക"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"വേണ്ട"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ഹീപ്പ് ഡമ്പ് ചെയ്യുക"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"ഉപയോഗത്തിലാണ്"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ആപ്പുകൾ നിങ്ങളുടെ <xliff:g id="TYPES_LIST">%s</xliff:g> ഉപയോഗിക്കുന്നു."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" കൂടാതെ "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിൽ പ്ലേ ചെയ്യാൻ അടുത്തേക്ക് നീക്കുക"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ഇവിടെ പ്ലേ ചെയ്യാൻ <xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിന് അടുത്തേക്ക് നീക്കുക"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിൽ പ്ലേ ചെയ്യുന്നു"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ഈ ഫോണിൽ പ്ലേ ചെയ്യുന്നു"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"എന്തോ കുഴപ്പമുണ്ടായി. വീണ്ടും ശ്രമിക്കുക."</string> <string name="controls_error_timeout" msgid="794197289772728958">"നിഷ്ക്രിയം, ആപ്പ് പരിശോധിക്കൂ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"കണ്ടെത്തിയില്ല"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"സംരക്ഷിക്കുക"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ആരംഭിക്കുന്നു…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ബ്രോഡ്കാസ്റ്റ് ചെയ്യാനാകുന്നില്ല"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"സംരക്ഷിക്കാൻ കഴിയില്ല. വീണ്ടും ശ്രമിക്കുക."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"സംരക്ഷിക്കാൻ കഴിയില്ല."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string> <string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"പകർത്തിയ ടെക്സ്റ്റ് എഡിറ്റ് ചെയ്യുക"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"പകർത്തിയ ചിത്രം എഡിറ്റ് ചെയ്യുക"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"സമീപത്തുള്ള ഉപകരണത്തിലേക്ക് അയയ്ക്കുക"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml index 12089288d134..dfa80480e6a9 100644 --- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"ഓഫാണ്"</item> <item msgid="460891964396502657">"ഓണാണ്"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 214c886a500d..4e70da55b7fd 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Таны IT админ дэлгэцийн агшин авахыг блоклосон байна"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматаар эргэх"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Дэлгэцийг автоматаар эргүүлэх"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Байршил"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Камерын хандалт"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Микрофоны хандалт"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Боломжтой"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"Карт нэмэх"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Шинэчилж байна"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ашиглахын тулд түгжээг тайлах"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Таны картыг авахад асуудал гарлаа. Дараа дахин оролдоно уу"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Батарей дуусах гэж байгаа үед асаана уу"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Үгүй, баярлалаа"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Ашиглаж байгаа"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Аппууд таны <xliff:g id="TYPES_LIST">%s</xliff:g>-г ашиглаж байна."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" болон "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> дээр тоглуулахын тулд төхөөрөмжөө ойртуулна уу"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Энд тоглуулахын тулд <xliff:g id="DEVICENAME">%1$s</xliff:g>-д ойртоно уу"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> дээр тоглуулж байна"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Энэ утсан дээр тоглуулж байна"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Алдаа гарлаа. Дахин оролдоно уу."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Олдсонгүй"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Хадгалах"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Эхлүүлж байна…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Нэвтрүүлэх боломжгүй"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Хадгалах боломжгүй. Дахин оролдоно уу."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Хадгалах боломжгүй."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийцийн дугаар"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Хийцийн дугаарыг түр санах ойд хуулсан."</string> <string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Хуулсан текстийг засах"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Хуулсан зургийг засах"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Ойролцоох төхөөрөмж рүү илгээх"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml index 3748440058b6..badc79696895 100644 --- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Унтраалттай"</item> <item msgid="460891964396502657">"Асаалттай"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index be13e58dc217..349157632466 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ऑटो-रोटेट स्क्रीन"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"स्थान"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"कॅमेराचा अॅक्सेस"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"माइकचा ॲक्सेस"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"उपलब्ध आहे"</string> @@ -348,7 +349,7 @@ <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"होय, सुरू ठेवा"</string> <string name="guest_notification_app_name" msgid="2110425506754205509">"अतिथी मोड"</string> <string name="guest_notification_session_active" msgid="5567273684713471450">"तुम्ही अतिथी मोडमध्ये आहात"</string> - <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"नवीन वापरकर्ता जोडल्याने अतिथी मोडमधून बाहेर पडेल आणि सध्याच्या अतिथी सत्रातील सर्व अॅप्स व डेटा हटवला जाईल."</string> + <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"नवीन वापरकर्ता जोडल्याने अतिथी मोडमधून बाहेर पडाल आणि सध्याच्या अतिथी सत्रातील सर्व अॅप्स व डेटा हटवला जाईल."</string> <string name="user_limit_reached_title" msgid="2429229448830346057">"वापरकर्ता मर्यादा गाठली"</string> <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398"> <item quantity="other">तुम्ही <xliff:g id="COUNT">%d</xliff:g> वापरकर्त्यांपर्यंत जोडू शकता.</item> @@ -469,7 +470,8 @@ <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="530725155985223497">"कार्ड जोडा"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"अपडेट करत आहे"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"वापरण्यासाठी अनलॉक करा"</string> <string name="wallet_error_generic" msgid="257704570182963611">"तुमची कार्ड मिळवताना समस्या आली, कृपया नंतर पुन्हा प्रयत्न करा"</string> @@ -529,7 +531,7 @@ <string name="feedback_prompt" msgid="3656728972307896379">"डेव्हलपरला तुमचा फीडबॅक कळवा. हे बरोबर होते का?"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी सूचना नियंत्रणे खुली आहेत"</string> <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी सूचना नियंत्रणे बंद आहेत"</string> - <string name="notification_more_settings" msgid="4936228656989201793">"अधिक सेटिंग्ज"</string> + <string name="notification_more_settings" msgid="4936228656989201793">"आणखी सेटिंग्ज"</string> <string name="notification_app_settings" msgid="8963648463858039377">"कस्टमाइझ करा"</string> <string name="notification_conversation_bubble" msgid="2242180995373949022">"बबल दाखवा"</string> <string name="notification_conversation_unbubble" msgid="6908427185031099868">"बबल काढून टाका"</string> @@ -587,7 +589,7 @@ <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ब्राउझर"</string> <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"संपर्क"</string> <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ईमेल"</string> - <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string> + <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"एसएमएस"</string> <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"संगीत"</string> <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"कॅलेंडर"</string> <string name="volume_and_do_not_disturb" msgid="502044092739382832">"व्यत्यय आणू नका"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"बॅटरी संपण्याची शक्यता असल्यास सुरू करा"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"नाही नको"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI हीप डंप करा"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"वापरात आहे"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ॲप्लिकेशन्स तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहे."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" आणि "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> वर प्ले करण्यासाठी जवळ जा"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"येथे प्ले करण्यासाठी <xliff:g id="DEVICENAME">%1$s</xliff:g> च्या जवळ जा"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> वर प्ले केला जात आहे"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"या फोनवर प्ले होत आहे"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"काहीतरी चूक झाली. पुन्हा प्रयत्न करा."</string> <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string> <string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"सेव्ह करा"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"सुरू करत आहे…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट करू शकत नाही"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेव्ह करू शकत नाही. पुन्हा प्रयत्न करा."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेव्ह करू शकत नाही."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string> <string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"कॉपी केलेला मजकूर संपादित करा"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"कॉपी केलेली इमेज संपादित करा"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"जवळपासच्या डिव्हाइसवर पाठवा"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml index a6a3873f95d7..7a601f876339 100644 --- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"बंद आहे"</item> <item msgid="460891964396502657">"सुरू आहे"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 41798606c02b..879fcb06e613 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Cuba ambil tangkapan skrin sekali lagi"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Tidak dapat menyimpan tangkapan skrin"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Pengambilan tangkapan skrin tidak dibenarkan oleh apl atau organisasi anda"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Pengambilan tangkapan skrin disekat oleh pentadbir IT anda"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit tangkapan skrin"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Kongsi tangkapan skrin"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoputar"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoputar skrin"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Akses kamera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Akses mikrofon"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tersedia"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Buat persediaan untuk membuat pembelian yang lebih pantas dan selamat dengan telefon anda"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Tunjukkan semua"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Tambahkan kad"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Mengemas kini"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Buka kunci untuk menggunakan"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Terdapat masalah sewaktu mendapatkan kad anda. Sila cuba sebentar lagi"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Hidupkan apabila bateri berkemungkinan habis"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Tidak perlu"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"DumpSys"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Sedang digunakan"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikasi sedang menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g> anda."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dan "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Alihkan lebih dekat untuk bermain pada<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Dekatkan dengan <xliff:g id="DEVICENAME">%1$s</xliff:g> untuk bermain di sini"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Dimainkan pada <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Dimainkan pada telefon ini"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Kesilapan telah berlaku. Cuba lagi."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Tidak aktif, semak apl"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Simpan"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Memulakan…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat disiarkan"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tidak dapat disimpan. Cuba lagi."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tidak dapat disimpan."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string> <string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edit teks yang disalin"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edit imej yang disalin"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Hantar ke peranti berdekatan"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml index cfd831a1d94b..ef303a7a5545 100644 --- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Mati"</item> <item msgid="460891964396502657">"Hidup"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index a5f5a3567251..dc8905ce6998 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ဖန်သားပြင်ဓာတ်ပုံရိုက်ခြင်းကို သင့် IT စီမံခန့်ခွဲသူက ပိတ်ထားသည်"</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> @@ -227,6 +226,7 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"အော်တို-လည်"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"မျက်နှာပြင်အား အလိုအလျောက်လှည့်ခြင်း"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"တည်နေရာ"</string> + <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"စကရင်ချွေတာစနစ်"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"ကင်မရာသုံးခွင့်"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"မိုက်သုံးခွင့်"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ရနိုင်သည်"</string> @@ -469,7 +469,7 @@ <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="530725155985223497">"ကတ်ထည့်ရန်"</string> + <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"တို့၍ ဖွင့်ရန်"</string> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"အပ်ဒိတ်လုပ်နေပါသည်"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"သုံးရန် လော့ခ်ဖွင့်ပါ"</string> <string name="wallet_error_generic" msgid="257704570182963611">"သင်၏ကတ်များ ရယူရာတွင် ပြဿနာရှိနေသည်၊ နောက်မှ ထပ်စမ်းကြည့်ပါ"</string> @@ -729,8 +729,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ဘက်ထရီကုန်ခါနီးတွင် ဖွင့်ပါ"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"မလိုပါ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"အသုံးပြုနေသည်"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"အပလီကေးရှင်းများက သင်၏ <xliff:g id="TYPES_LIST">%s</xliff:g> ကို အသုံးပြုနေသည်။"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"၊ "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" နှင့် "</string> @@ -808,7 +807,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"ပိုကြည့်ရန် ပွတ်ဆွဲပါ"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"အကြံပြုချက်များ ဖွင့်နေသည်"</string> <string name="controls_media_title" msgid="1746947284862928133">"မီဒီယာ"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ၏ ဤမီဒီယာ ထိန်းချုပ်ကိရိယာကို ဖျောက်ထားမလား။"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် ဤမီဒီယာထိန်းချုပ်မှု ဖျောက်ထားမလား။"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"လက်ရှိ မီဒီယာစက်ရှင်ကို ဝှက်၍မရပါ။"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ဖျောက်ထားမည်"</string> <string name="controls_media_resume" msgid="1933520684481586053">"ဆက်လုပ်ရန်"</string> @@ -828,7 +827,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> တွင်ဖွင့်ရန် အနီးသို့ရွှေ့ပါ"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ဤနေရာတွင်ဖွင့်ရန် <xliff:g id="DEVICENAME">%1$s</xliff:g> အနီးသို့တိုးပါ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> တွင် ဖွင့်နေသည်"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ဤဖုန်းတွင် ဖွင့်နေသည်"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"တစ်ခုခုမှားသွားသည်။ ထပ်စမ်းကြည့်ပါ။"</string> <string name="controls_error_timeout" msgid="794197289772728958">"ရပ်နေသည်၊ အက်ပ်ကို စစ်ဆေးပါ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"မတွေ့ပါ"</string> @@ -858,6 +856,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"သိမ်းရန်"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"စတင်နေသည်…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ထုတ်လွှင့်၍ မရပါ"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"သိမ်း၍မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"သိမ်း၍မရပါ။"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string> <string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string> @@ -942,6 +942,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"ကူးထားသည့်စာသားကို တည်းဖြတ်ရန်"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ကူးထားသည့်ပုံကို ပြင်ဆင်ရန်"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"အနီးတစ်ဝိုက်ရှိ စက်များသို့ ပို့ရန်"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml index 665af20761c7..493a7f0977c6 100644 --- a/packages/SystemUI/res/values-my/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml @@ -171,4 +171,9 @@ <item msgid="146088982397753810">"ပိတ်"</item> <item msgid="460891964396502657">"ဖွင့်"</item> </string-array> + <string-array name="tile_states_dream"> + <item msgid="6184819793571079513">"မရနိုင်ပါ"</item> + <item msgid="8014986104355098744">"ပိတ်"</item> + <item msgid="5966994759929723339">"ဖွင့်"</item> + </string-array> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index da3309822851..cbeb9cd2ccde 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv å ta skjermdump på nytt"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan ikke lagre skjermdumpen"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisasjonen din tillater ikke at du tar skjermdumper"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Funksjonen for å ta skjermdumper er blokkert av IT-administratoren din"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger skjermdumpen"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Del skjermdumpen"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotér automatisk"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotér skjermen automatisk"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Sted"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameratilgang"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofontilgang"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tilgjengelig"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Legg til en betalingsmåte for å gjennomføre kjøp raskere og sikrere med telefonen"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Vis alle"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Legg til et kort"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Oppdaterer"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås opp for å bruke"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Det oppsto et problem med henting av kortene. Prøv på nytt senere"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Slå på når det er sannsynlig at du går tom for batteri"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nei takk"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI-heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"I bruk"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apper bruker <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flytt nærmere for å spille av på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Flytt deg nærmere <xliff:g id="DEVICENAME">%1$s</xliff:g> for å spille av her"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Spilles av på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Spilles av på denne telefonen"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Noe gikk galt. Prøv på nytt."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ikke funnet"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Lagre"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starter …"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan ikke kringkaste"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan ikke lagre. Prøv på nytt."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan ikke lagre."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string> <string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Rediger den kopierte teksten"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Rediger det kopierte bildet"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Send til en enhet i nærheten"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml index a28b817b765b..6d1e88ee1b7e 100644 --- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Av"</item> <item msgid="460891964396502657">"På"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 35a47a47f60c..9adc65a2f9d1 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"अटो रोटेट"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रिन स्वतःघुम्ने"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"लोकेसन"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"क्यामेरा प्रयोग गर्ने अनुमति"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"माइक प्रयोग गर्ने अनुमति"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"उपलब्ध छ"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"कार्ड हाल्नुहोस्"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"अपडेट गरिँदै छ"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"यो वालेट प्रयोग गर्न डिभाइस अनलक गर्नुहोस्"</string> <string name="wallet_error_generic" msgid="257704570182963611">"तपाईंका कार्डहरू प्राप्त गर्ने क्रममा समस्या भयो, कृपया पछि फेरि प्रयास गर्नुहोस्"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ब्याट्री सकिने सम्भावना भएमा अन गर्नुहोस्"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"पर्दैन धन्यवाद"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"प्रयोगमा छ"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"एपहरूले तपाईंको <xliff:g id="TYPES_LIST">%s</xliff:g> प्रयोग गर्दै छन्।"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" र "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> मा प्ले गर्न आफ्नो डिभाइस नजिकै लैजानुहोस्"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"तपाईं यहाँ प्ले गर्न चाहनुहुन्छ भने आफ्नो डिभाइसलाई <xliff:g id="DEVICENAME">%1$s</xliff:g> नजिकै लैजानुहोस्"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> मा प्ले गरिँदै छ"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"यो फोनमा प्ले गरिँदै छ"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"केही चिज गडबड भयो। फेरि प्रयास गर्नुहोस्।"</string> <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string> <string name="controls_error_removed" msgid="6675638069846014366">"फेला परेन"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"सेभ गर्नुहोस्"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"सुरु गरिँदै छ…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"प्रसारण गर्न सकिएन"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेभ गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेभ गर्न सकिएन।"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string> <string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"कपी गरिएको टेक्स्ट सम्पादन गर्नुहोस्"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"कपी गरिएको फोटो सम्पादन गर्नुहोस्"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"नजिकैको डिभाइसमा पठाउनुहोस्"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml index 80edf29f4985..c0f32e5f8198 100644 --- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"अफ छ"</item> <item msgid="460891964396502657">"अन छ"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index e81634d9a5be..a8cd6a4ae77e 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probeer opnieuw een screenshot te maken"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan screenshot niet opslaan"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Het maken van screenshots wordt niet toegestaan door de app of je organisatie"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Screenshots maken is geblokkeerd door je IT-beheerder"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Bewerken"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Screenshot bewerken"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Screenshot delen"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatisch draaien"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Scherm automatisch draaien"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Locatie"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Cameratoegang"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Microfoontoegang"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Beschikbaar"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Portemonnee"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Zorg dat je sneller en beter beveiligd aankopen kunt doen met je telefoon"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Alles tonen"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Kaart toevoegen"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Updaten"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ontgrendelen om te gebruiken"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Er is een probleem opgetreden bij het ophalen van je kaarten. Probeer het later opnieuw."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Aanzetten als de batterij waarschijnlijk leeg raakt"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nee, bedankt"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In gebruik"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps gebruiken je <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" en "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ga dichter naar <xliff:g id="DEVICENAME">%1$s</xliff:g> toe om af te spelen"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ga dichter bij <xliff:g id="DEVICENAME">%1$s</xliff:g> staan om hier af te spelen"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Afspelen op <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Afspelen op deze telefoon"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Er is iets misgegaan. Probeer het opnieuw."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactief, check de app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Niet gevonden"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Opslaan"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starten…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan niet uitzenden"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan niet opslaan. Probeer het opnieuw."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan niet opslaan."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummer naar klembord gekopieerd."</string> <string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Gekopieerde tekst bewerken"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Gekopieerde afbeelding bewerken"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Naar apparaat in de buurt sturen"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml index c4603b22157c..688d81bca018 100644 --- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Uit"</item> <item msgid="460891964396502657">"Aan"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 3c3e6abd3da4..a6cc8915b26d 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -36,7 +36,7 @@ <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ଆକ୍ସେସ୍ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ କି?\nଏହି ଆପ୍କୁ ରେକର୍ଡ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ କିନ୍ତୁ ଏହି USB ଡିଭାଇସ୍ ଜରିଆରେ ଅଡିଓ କ୍ୟାପ୍ଟର୍ କରିପାରିବ।"</string> <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>କୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string> <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>କୁ ନିୟନ୍ତ୍ରଣ କରିବା ପାଇଁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଖୋଲିବେ?"</string> - <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ଏହି ଆପକୁ ରେକର୍ଡ କରିବା ପାଇଁ ଅନୁମତି ଦିଆଯାଇନାହିଁ, କିନ୍ତୁ ଏହି USB ଡିଭାଇସ ମାଧ୍ୟମରେ ଏହା ଅଡିଓକୁ କ୍ୟାପଚର କରିପାରିବ। ଏହି ଡିଭାଇସରେ <xliff:g id="APPLICATION">%1$s</xliff:g> ବ୍ୟବହାର କରିବା କଲ, ବିଜ୍ଞପ୍ତି ଏବଂ ଆଲାରାମଗୁଡ଼ିକୁ ଶୁଣିବାରୁ ପ୍ରତିରୋଧ କରିପାରେ।"</string> + <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"ଏହି ଆପକୁ ରେକର୍ଡ କରିବା ପାଇଁ ଅନୁମତି ଦିଆଯାଇନାହିଁ, କିନ୍ତୁ ଏହି USB ଡିଭାଇସ ମାଧ୍ୟମରେ ଏହା ଅଡିଓକୁ କ୍ୟାପଚର କରିପାରିବ। ଏହି ଡିଭାଇସରେ <xliff:g id="APPLICATION">%1$s</xliff:g> ବ୍ୟବହାର କଲେ କଲ, ବିଜ୍ଞପ୍ତି ଏବଂ ଆଲାରାମଗୁଡ଼ିକୁ ଶୁଣିବାରୁ ପ୍ରତିରୋଧ କରାଯାଇପାରେ।"</string> <string name="usb_audio_device_prompt" msgid="7944987408206252949">"ଏହି ଡିଭାଇସରେ <xliff:g id="APPLICATION">%1$s</xliff:g> ବ୍ୟବହାର କରିବା କଲ, ବିଜ୍ଞପ୍ତି ଏବଂ ଆଲାରାମଗୁଡ଼ିକୁ ଶୁଣିବାରୁ ପ୍ରତିରୋଧ କରିପାରେ।"</string> <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ଆକ୍ସେସ୍ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string> <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ନିୟନ୍ତ୍ରଣ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g> ଖୋଲିବେ?"</string> @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ସ୍କ୍ରିନସଟଗୁଡ଼ିକ ନେବା ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ଦ୍ୱାରା ବ୍ଲକ କରାଯାଇଛି"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ଅଟୋ-ରୋଟେଟ୍"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ଅଟୋ-ରୋଟେଟ୍ ସ୍କ୍ରିନ୍"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"ଲୋକେସନ୍"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"କ୍ୟାମେରା ଆକ୍ସେସ୍"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"ମାଇକ୍ ଆକ୍ସେସ୍"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ଉପଲବ୍ଧ"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"ଏକ କାର୍ଡ ଯୋଗ କରନ୍ତୁ"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"ଅପଡେଟ୍ ହେଉଛି"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string> <string name="wallet_error_generic" msgid="257704570182963611">"ଆପଣଙ୍କ କାର୍ଡଗୁଡ଼ିକ ପାଇବାରେ ଏକ ସମସ୍ୟା ହୋଇଥିଲା। ଦୟାକରି ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ବ୍ୟାଟେରୀ ସରିବାକୁ ଥିବା ସମୟରେ ଚାଲୁ କରନ୍ତୁ"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"ନାହିଁ, ଥାଉ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ହିପ୍ ଡମ୍ପ୍ କରନ୍ତୁ"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"ବ୍ୟବହାର ହେଉଛି"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ଆପ୍ଲିକେସନ୍ଗୁଡିକ ଆପଣଙ୍କ <xliff:g id="TYPES_LIST">%s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି।"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ଏବଂ "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ଚଲାଇବା ପାଇଁ ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ଏଠାରେ ଚଲାଇବା ପାଇଁ <xliff:g id="DEVICENAME">%1$s</xliff:g>ର ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ଚାଲୁଛି"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ଏହି ଫୋନରେ ଚାଲୁଛି"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"କିଛି ତ୍ରୁଟି ହୋଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ମିଳିଲା ନାହିଁ"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ସେଭ କରନ୍ତୁ"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ଆରମ୍ଭ ହେଉଛି…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ବ୍ରଡକାଷ୍ଟ କରାଯାଇପାରିବ ନାହିଁ"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ସେଭ କରାଯାଇପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ସେଭ କରାଯାଇପାରିଲା ନାହିଁ।"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string> <string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"କପି କରାଯାଇଥିବା ଟେକ୍ସଟକୁ ଏଡିଟ କରନ୍ତୁ"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"କପି କରାଯାଇଥିବା ଇମେଜକୁ ଏଡିଟ କରନ୍ତୁ"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ନିକଟସ୍ଥ ଡିଭାଇସକୁ ପଠାନ୍ତୁ"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml index 2d9fb84790cd..7ae1f11dca3f 100644 --- a/packages/SystemUI/res/values-or/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"ବନ୍ଦ ଅଛି"</item> <item msgid="460891964396502657">"ଚାଲୁ ଅଛି"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 8012c2cb423e..2f905bbca623 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ਸਵੈ-ਘੁਮਾਓ"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ਸਕ੍ਰੀਨ ਨੂੰ ਆਪਣੇ ਆਪ ਘੁੰਮਾਓ"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"ਟਿਕਾਣਾ"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"ਕੈਮਰਾ ਪਹੁੰਚ"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"ਮਾਈਕ ਪਹੁੰਚ"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ਉਪਲਬਧ"</string> @@ -424,9 +425,9 @@ <string name="screen_pinning_title" msgid="9058007390337841305">"ਐਪ ਨੂੰ ਪਿੰਨ ਕੀਤਾ ਗਿਆ ਹੈ"</string> <string name="screen_pinning_description" msgid="8699395373875667743">"ਇਹ ਇਸ ਨੂੰ ਤਦ ਤੱਕ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਰੱਖਦਾ ਹੈ ਜਦ ਤੱਕ ਤੁਸੀਂ ਅਨਪਿੰਨ ਨਹੀਂ ਕਰਦੇ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਪਿੱਛੇ\' ਅਤੇ \'ਰੂਪ-ਰੇਖਾ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string> <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਨਪਿੰਨ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਪਿੱਛੇ\' ਅਤੇ \'ਹੋਮ\' ਨੂੰ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string> - <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਨਪਿੰਨ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਰੱਖੋ।"</string> + <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਣਪਿੰਨ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਣਪਿੰਨ ਕਰਨ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਰੱਖੋ।"</string> <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"ਇਹ ਇਸ ਨੂੰ ਤਦ ਤੱਕ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਰੱਖਦਾ ਹੈ ਜਦ ਤੱਕ ਤੁਸੀਂ ਅਨਪਿੰਨ ਨਹੀਂ ਕਰਦੇ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਰੂਪ-ਰੇਖਾ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string> - <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਨਪਿੰਨ ਨਾ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਹੋਮ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string> + <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਣਪਿੰਨ ਨਾ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਣਪਿੰਨ ਕਰਨ ਲਈ \'ਹੋਮ\' ਨੂੰ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string> <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"ਨਿੱਜੀ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ (ਜਿਵੇਂ ਕਿ ਸੰਪਰਕ ਅਤੇ ਈਮੇਲ ਸਮੱਗਰੀ)।"</string> <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"ਪਿੰਨ ਕੀਤੀ ਐਪ ਹੋਰ ਐਪਾਂ ਨੂੰ ਖੋਲ੍ਹ ਸਕਦੀ ਹੈ।"</string> <string name="screen_pinning_toast" msgid="8177286912533744328">"ਇਸ ਐਪ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, \'ਪਿੱਛੇ\' ਅਤੇ \'ਰੂਪ-ਰੇਖਾ\' ਬਟਨਾਂ ਨੂੰ ਸਪਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"ਕੋਈ ਕਾਰਡ ਸ਼ਾਮਲ ਕਰੋ"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"ਅੱਪਡੇਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string> <string name="wallet_error_generic" msgid="257704570182963611">"ਤੁਹਾਡੇ ਕਾਰਡ ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਕੋਈ ਸਮੱਸਿਆ ਆਈ, ਕਿਰਪਾ ਕਰਕੇ ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"ਬੈਟਰੀ ਖਤਮ ਹੋਣ ਦੀ ਸੰਭਾਵਨਾ \'ਤੇ ਚਾਲੂ ਹੁੰਦਾ ਹੈ"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"ਨਹੀਂ ਧੰਨਵਾਦ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ਹੀਪ ਡੰਪ ਕਰੋ"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"ਵਰਤੋਂ ਵਿੱਚ"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ਐਪਲੀਕੇਸ਼ਨਾਂ ਤੁਹਾਡੇ <xliff:g id="TYPES_LIST">%s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ।"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ਅਤੇ "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"ਹੋਰ ਦੇਖਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"ਸਿਫ਼ਾਰਸ਼ਾਂ ਲੋਡ ਹੋ ਰਹੀਆਂ ਹਨ"</string> <string name="controls_media_title" msgid="1746947284862928133">"ਮੀਡੀਆ"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਇਸ ਮੀਡੀਆ ਕੰਟਰੋਲ ਲੁਕਾਉਣਾ ਹੈ?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਇਹ ਮੀਡੀਆ ਕੰਟਰੋਲ ਲੁਕਾਉਣਾ ਹੈ?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"ਮੌਜੂਦਾ ਮੀਡੀਆ ਸੈਸ਼ਨ ਲੁਕਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ਲੁਕਾਓ"</string> <string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> \'ਤੇ ਚਲਾਉਣ ਲਈ ਨੇੜੇ ਲਿਜਾਓ"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ਇੱਥੇ ਚਲਾਉਣ ਲਈ <xliff:g id="DEVICENAME">%1$s</xliff:g> ਦੇ ਨੇੜੇ ਜਾਓ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> \'ਤੇ ਚਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ਇਸ ਫ਼ੋਨ \'ਤੇ ਚਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> <string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ਰੱਖਿਅਤ ਕਰੋ"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ਸ਼ੁਰੂ ਹੋ ਰਿਹਾ ਹੈ…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ਪ੍ਰਸਾਰਨ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string> <string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"ਕਾਪੀ ਕੀਤੀ ਲਿਖਤ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ਕਾਪੀ ਕੀਤੇ ਗਏ ਚਿੱਤਰ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸ \'ਤੇ ਭੇਜੋ"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml index 737b2b60ac60..74b2bdd31f65 100644 --- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"ਬੰਦ"</item> <item msgid="460891964396502657">"ਚਾਲੂ"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 1a14fdc054e6..ccbccb38eb72 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Spróbuj jeszcze raz wykonać zrzut ekranu"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nie można zapisać zrzutu ekranu."</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Nie możesz wykonać zrzutu ekranu, bo nie zezwala na to aplikacja lub Twoja organizacja."</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Robienie zrzutów ekranu zostało zablokowane przez administratora IT"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Edytuj"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Edytuj zrzut ekranu"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Udostępnij zrzut ekranu"</string> @@ -229,6 +228,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoobracanie"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoobracanie ekranu"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokalizacja"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Dostęp do aparatu"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Dostęp do mikrofonu"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Odblokowany"</string> @@ -475,7 +476,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Portfel"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Skonfiguruj formę płatności, aby szybciej i bezpieczniej płacić telefonem za zakupy"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Pokaż wszystko"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Dodaj kartę"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Aktualizuję"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odblokuj, aby użyć"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Podczas pobierania kart wystąpił problem. Spróbuj ponownie później."</string> @@ -739,8 +741,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Oszczędzanie baterii włącza się, jeśli bateria jest prawie wyczerpana"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nie, dziękuję"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Zrzut stosu SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"W użyciu"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacje używają: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string> @@ -820,7 +821,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Przesuń palcem, by zobaczyć więcej"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Wczytuję rekomendacje"</string> <string name="controls_media_title" msgid="1746947284862928133">"Multimedia"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Ukryć tę opcję sterowania multimediami w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Ukryć sterowanie multimediami w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Nie można ukryć tej sesji multimediów."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ukryj"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Wznów"</string> @@ -840,7 +841,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Przysuń się bliżej, aby odtwarzać na urządzeniu <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Zbliż do urządzenia <xliff:g id="DEVICENAME">%1$s</xliff:g>, aby na nim odtwarzać"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Odtwarzam na ekranie <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Odtwarzam na tym telefonie"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Coś poszło nie tak. Spróbuj ponownie."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nie znaleziono"</string> @@ -870,6 +870,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Zapisz"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Uruchamiam…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nie można przesyłać"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nie można zapisać. Spróbuj ponownie."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nie można zapisać."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string> <string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string> @@ -956,6 +958,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Edytuj skopiowany tekst"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Edytuj skopiowany obraz"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Wyślij na urządzenie w pobliżu"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml index f5d8f1fe815d..496d2c717e0b 100644 --- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml @@ -127,9 +127,9 @@ <item msgid="578444932039713369">"Włączony"</item> </string-array> <string-array name="tile_states_reverse"> - <item msgid="3574611556622963971">"Niedostępny"</item> - <item msgid="8707481475312432575">"Wyłączony"</item> - <item msgid="8031106212477483874">"Włączony"</item> + <item msgid="3574611556622963971">"Niedostępne"</item> + <item msgid="8707481475312432575">"Wyłączone"</item> + <item msgid="8031106212477483874">"Włączone"</item> </string-array> <string-array name="tile_states_reduce_brightness"> <item msgid="1839836132729571766">"Niedostępny"</item> @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Wyłączony"</item> <item msgid="460891964396502657">"Włączony"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 1f41ae18796d..2627860cbe6e 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Tente fazer a captura de tela novamente"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Não foi possível salvar a captura de tela"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"O app ou a organização não permitem capturas de tela"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"As capturas de tela foram bloqueadas pelo administrador de TI"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de tela"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Compartilhar captura de tela"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso à câmera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acesso ao microfone"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Carteira"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Prepare tudo para fazer compras mais rápidas e seguras com seu smartphone"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Mostrar tudo"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Adicionar um cartão"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Atualizando"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Ocorreu um problema ao carregar os cards. Tente novamente mais tarde"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Ativada quando há possibilidade de a bateria acabar"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Não"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar heap SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Em uso"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime os dispositivos para tocar a mídia neste: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para abrir a mídia aqui"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Mídia aberta no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Mídia aberta neste smartphone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salvar"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Falha ao salvar. Tente de novo."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Falha ao salvar."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string> <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagem copiada"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar para dispositivo próximo"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Adicionar"</string> <string name="manage_users" msgid="1823875311934643849">"Gerenciar usuários"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não tem suporte para ser arrastada para a tela dividida."</string> diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml index abf8749e84d7..788938a1ea8c 100644 --- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Desativado"</item> <item msgid="460891964396502657">"Ativado"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 043efeb9e444..adc9faa727e5 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Experimente voltar a efetuar a captura de ecrã."</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Não é possível guardar a captura de ecrã."</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"A app ou a sua entidade não permitem tirar capturas de ecrã"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"A capacidade de fazer capturas de ecrã foi bloqueada pelo administrador de TI"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de ecrã"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Partilhar captura de ecrã"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotação auto."</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rodar o ecrã automaticamente"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso câmara"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Ac. microfone"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string> @@ -427,7 +428,7 @@ <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Esta opção mantém o item visível até o soltar. Deslize rapidamente para cima e mantenha pressionado para soltar."</string> <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Vista geral para soltar."</string> <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Página inicial para soltar."</string> - <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Os dados pessoais podem ficar acessíveis (tais como contactos e conteúdo do email)."</string> + <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Os dados pessoais, tais como contactos e conteúdo do email, podem ficar acessíveis."</string> <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"Uma app fixada pode abrir outras apps."</string> <string name="screen_pinning_toast" msgid="8177286912533744328">"Para soltar esta app, toque sem soltar nos botões Anterior e Vista geral."</string> <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Para soltar esta app, toque sem soltar nos botões Anterior e Página inicial."</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Carteira"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Configure para efetuar pagamentos mais rápidos e seguros com o seu telemóvel"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Mostrar tudo"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Adicionar um cartão"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"A atualizar"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para utilizar"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Ocorreu um problema ao obter os seus cartões. Tente novamente mais tarde."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Ativar quando for provável que a bateria se esgote"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Não"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar pilha SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Em utilização"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"As aplicações estão a utilizar o(a) <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Deslize rapidamente para ver mais."</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"A carregar recomendações…"</string> <string name="controls_media_title" msgid="1746947284862928133">"Multimédia"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar este controlo de multimédia para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar controlo de multimédia para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Não pode ocultar a sessão de multimédia atual."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime-se para reproduzir no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproduzir aqui"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"A reproduzir no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"A reproduzir neste telemóvel"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Algo correu mal. Tente novamente."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inativa. Consulte a app."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado."</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Guardar"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"A iniciar…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não é possível transmitir"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Não é possível guardar. Tente novamente."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Não é possível guardar."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string> <string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagem copiada"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar para dispositivo próximo"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Adicionar"</string> <string name="manage_users" msgid="1823875311934643849">"Gerir utilizadores"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não pode ser arrastada para o ecrã dividido."</string> diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml index 8ffa760f637c..8e98030b1d76 100644 --- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Desativado"</item> <item msgid="460891964396502657">"Ativado"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 1f41ae18796d..2627860cbe6e 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Tente fazer a captura de tela novamente"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Não foi possível salvar a captura de tela"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"O app ou a organização não permitem capturas de tela"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"As capturas de tela foram bloqueadas pelo administrador de TI"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de tela"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Compartilhar captura de tela"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso à câmera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acesso ao microfone"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Carteira"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Prepare tudo para fazer compras mais rápidas e seguras com seu smartphone"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Mostrar tudo"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Adicionar um cartão"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Atualizando"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Ocorreu um problema ao carregar os cards. Tente novamente mais tarde"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Ativada quando há possibilidade de a bateria acabar"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Não"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar heap SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Em uso"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime os dispositivos para tocar a mídia neste: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para abrir a mídia aqui"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Mídia aberta no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Mídia aberta neste smartphone"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salvar"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Falha ao salvar. Tente de novo."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Falha ao salvar."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string> <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editar texto copiado"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editar imagem copiada"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Enviar para dispositivo próximo"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Adicionar"</string> <string name="manage_users" msgid="1823875311934643849">"Gerenciar usuários"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não tem suporte para ser arrastada para a tela dividida."</string> diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml index abf8749e84d7..788938a1ea8c 100644 --- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Desativado"</item> <item msgid="460891964396502657">"Ativado"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index e20b85f7c54c..2c6e0cf08d74 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Încercați să faceți din nou o captură de ecran"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nu se poate salva captura de ecran"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Crearea capturilor de ecran nu este permisă de aplicație sau de organizația dvs."</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Administratorul IT a blocat crearea capturilor de ecran"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Editați"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Editați captura de ecran"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Trimiteți captura de ecran"</string> @@ -228,6 +227,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotire automată"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotirea automată a ecranului"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Locație"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acces la cameră"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acces la microfon"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponibil"</string> @@ -472,7 +473,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Configurați pentru a face achiziții mai rapide și mai sigure cu telefonul dvs."</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Afișați-le pe toate"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Adăugați un card"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Se actualizează"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Deblocați pentru a folosi"</string> <string name="wallet_error_generic" msgid="257704570182963611">"A apărut o problemă la preluarea cardurilor. Încercați din nou mai târziu"</string> @@ -734,8 +736,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Porniți dacă este probabil ca bateria să se descarce"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nu, mulțumesc"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Extrageți memoria SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"În uz"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicațiile folosesc <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" și "</string> @@ -834,7 +835,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Apropiați-vă pentru a reda pe <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Mergeți mai aproape de <xliff:g id="DEVICENAME">%1$s</xliff:g> ca să redați acolo"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Se redă pe <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Se redă pe acest telefon"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"A apărut o eroare. Încercați din nou."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verificați aplicația"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nu s-a găsit"</string> @@ -864,6 +864,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salvați"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Începe…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nu se poate transmite"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nu se poate salva. Încercați din nou."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nu se poate salva."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string> <string name="basic_status" msgid="2315371112182658176">"Deschideți conversația"</string> @@ -949,6 +951,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Editați textul copiat"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Editați imaginea copiată"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Trimiteți către un dispozitiv din apropiere"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml index 1ad0a75f39ba..b5641f7df9f6 100644 --- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Dezactivat"</item> <item msgid="460891964396502657">"Activat"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 150d86664119..910b369e738e 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -229,6 +228,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоповорот"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоповорот экрана"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Геолокация"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ к камере"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Доступ к микрофону"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Доступно"</string> @@ -475,7 +476,8 @@ <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="530725155985223497">"Добавьте карту"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Обновление…"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Разблокировать для использования"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Не удалось получить информацию о картах. Повторите попытку позже."</string> @@ -609,8 +611,8 @@ <string name="accessibility_status_bar_headset" msgid="2699275863720926104">"Гарнитура подключена"</string> <string name="data_saver" msgid="3484013368530820763">"Экономия трафика"</string> <string name="accessibility_data_saver_on" msgid="5394743820189757731">"Режим экономии трафика включен"</string> - <string name="switch_bar_on" msgid="1770868129120096114">"Включено"</string> - <string name="switch_bar_off" msgid="5669805115416379556">"Отключено"</string> + <string name="switch_bar_on" msgid="1770868129120096114">"Вкл."</string> + <string name="switch_bar_off" msgid="5669805115416379556">"Откл."</string> <string name="tile_unavailable" msgid="3095879009136616920">"Недоступно"</string> <string name="tile_disabled" msgid="373212051546573069">"Отключено"</string> <string name="nav_bar" msgid="4642708685386136807">"Панель навигации"</string> @@ -739,8 +741,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Включать, если высока вероятность, что батарея скоро разрядится"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Нет, спасибо"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Передача SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Используется"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"В приложениях используется <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string> @@ -820,7 +821,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Проведите по экрану, чтобы увидеть больше"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Загрузка рекомендаций…"</string> <string name="controls_media_title" msgid="1746947284862928133">"Медиа"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Скрыть этот элемент управления в приложении \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Скрыть этот элемент в приложении \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Этот мультимедийный сеанс невозможно скрыть."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скрыть"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Возобновить"</string> @@ -840,7 +841,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Чтобы начать трансляцию на устройстве \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", подойдите к нему ближе."</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Для воспроизведения на этом устройстве подойдите ближе к другому (<xliff:g id="DEVICENAME">%1$s</xliff:g>)."</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Воспроизводится на устройстве \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\"."</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Воспроизводится на этом телефоне."</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Произошла ошибка. Повторите попытку."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Нет ответа. Проверьте приложение."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не найдено."</string> @@ -870,6 +870,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сохранить"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Запуск…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не удалось запустить трансляцию"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не удалось сохранить. Повторите попытку."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не удалось сохранить."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string> <string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string> @@ -956,6 +958,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Изменить скопированный текст"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Изменить скопированное изображение"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Отправить на устройство поблизости"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml index e1ee39fd79ee..9e73d24a18c2 100644 --- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Отключен"</item> <item msgid="460891964396502657">"Включен"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index bffa671de329..d1cd5f89745a 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"තිර රූ ගැනීම ඔබගේ IT පරිපාලක විසින් අවහිර කර ඇත"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ස්වයංක්රීය කරකැවීම"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ස්වයංක්රීයව-භ්රමණය වන තිරය"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"ස්ථානය"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"කැමරා ප්රවේශය"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"මයික් ප්රවේශය"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"තිබේ"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"කාඩ්පතක් එක් කරන්න"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"යාවත්කාලීන වේ"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"භාවිත කිරීමට අගුලු හරින්න"</string> <string name="wallet_error_generic" msgid="257704570182963611">"ඔබගේ කාඩ්පත ලබා ගැනීමේ ගැටලුවක් විය, කරුණාකර පසුව නැවත උත්සාහ කරන්න"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"බැටරිය අවසන් වීමට යන විට සක්රීය කරන්න"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"එපා ස්තූතියි"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"භාවිතයේ ඇත"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"යෙදුම් ඔබේ <xliff:g id="TYPES_LIST">%s</xliff:g> භාවිත කරමින් සිටී."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" සහ "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> හි වාදනය කිරීමට වඩාත් ළං වන්න"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"මෙහි ක්රීඩා කිරීමට <xliff:g id="DEVICENAME">%1$s</xliff:g> වෙත වඩා සමීප වන්න"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> හි වාදනය කරමින්"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"මෙම දුරකථනයෙහි වාදනය කරමින්"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"යම් දෙයක් වැරදිණි. නැවත උත්සාහ කරන්න."</string> <string name="controls_error_timeout" msgid="794197289772728958">"අක්රියයි, යෙදුම පරීක්ෂා කරන්න"</string> <string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"සුරකින්න"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ආරම්භ කරමින්…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"විකාශනය කළ නොහැකිය"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"සුරැකිය නොහැකිය. නැවත උත්සාහ කරන්න."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"සුරැකිය නොහැකිය."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string> <string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"පිටපත් කළ පෙළ සංස්කරණය කරන්න"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"පිටපත් කළ රූපය සංස්කරණය කරන්න"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"අවට උපාංගය වෙත යවන්න"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml index 8a16acbb7c57..3aba31a3b6b6 100644 --- a/packages/SystemUI/res/values-si/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"ක්රියාවිරහිතයි"</item> <item msgid="460891964396502657">"ක්රියාත්මකයි"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 17883e005777..e834b81ac2db 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Skúste snímku urobiť znova"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Snímka obrazovky sa nedá uložiť"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Vytváranie snímok obrazovky je zakázané aplikáciou alebo vašou organizáciou"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Vytváranie snímok obrazovky zablokoval váš správca IT"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Upraviť"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Upraviť snímku obrazovky"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Zdieľať snímku obrazovky"</string> @@ -229,6 +228,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatické otáčanie"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otáčanie obrazovky"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Prístup ku kamere"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Prístup k mikrofónu"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"K dispozícii"</string> @@ -475,7 +476,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Peňaženka"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Nastavte si všetko potrebné na rýchlejšie a bezpečnejšie nákupy telefónom"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Zobraziť všetko"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Pridať kartu"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Aktualizuje sa"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odomknúť a použiť"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Pri načítavaní kariet sa vyskytol problém. Skúste to neskôr."</string> @@ -739,8 +741,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Zapnite, keď je batéria takmer vybitá"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nie, vďaka"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Výpis haldy SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Používa sa"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikácie používajú zoznam <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" a "</string> @@ -840,7 +841,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ak chcete prehrávať v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>, priblížte sa"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ak chcete prehrávať v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>, priblížte sa k nemu"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Prehráva sa v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Prehráva sa v tomto telefóne"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Niečo sa pokazilo. Skúste to znova."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktívne, preverte aplikáciu"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nenájdené"</string> @@ -870,6 +870,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Uložiť"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Spúšťa sa…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nedá sa vysielať"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nedá sa uložiť. Skúste to znova."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nedá sa uložiť."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string> <string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string> @@ -956,6 +958,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Upraviť skopírovaný text"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Upraviť skopírovaný obrázok"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Odoslať do zariadenia v okolí"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Pridať"</string> <string name="manage_users" msgid="1823875311934643849">"Spravovať používateľov"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Toto upozornenie nepodporuje presun na rozdelenú obrazovku."</string> diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml index dcdfb3a901b5..1726aaac0575 100644 --- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Vypnuté"</item> <item msgid="460891964396502657">"Zapnuté"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index db4486963726..c3d3094173ed 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Poskusite znova ustvariti posnetek zaslona"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Posnetka zaslona ni mogoče shraniti"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ali vaša organizacija ne dovoljuje posnetkov zaslona"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Skrbnik za IT je onemogočil zajemanje posnetkov zaslona."</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Uredi"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Urejanje posnetka zaslona"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Deljenje posnetka zaslona"</string> @@ -229,6 +228,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Samodejno sukanje"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Samodejno sukanje zaslona"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Dostop do fotoaparata"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Dostop do mikrofona"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Na voljo"</string> @@ -475,7 +476,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Denarnica"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Nastavite možnost hitrejšega in varnejšega plačevanja s telefonom."</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Prikaži vse"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Dodajte kartico"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Posodabljanje"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Odklenite za uporabo"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Pri pridobivanju kartic je prišlo do težave. Poskusite znova pozneje."</string> @@ -739,8 +741,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Vklop, če je verjetno, da se bo baterija izpraznila"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Izvoz kopice SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"V uporabi"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije uporabljajo <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" in "</string> @@ -820,7 +821,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Če si želite ogledati več, povlecite"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Nalaganje priporočil"</string> <string name="controls_media_title" msgid="1746947284862928133">"Predstavnost"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Želite skriti ta nadzor predstavnosti za apl. <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Želite skriti ta nadzor predstavnosti za <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Trenutne seje predstavnosti ni mogoče skriti."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrij"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Nadaljuj"</string> @@ -840,7 +841,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Za predvajanje v napravi <xliff:g id="DEVICENAME">%1$s</xliff:g> bolj približajte telefon."</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približajte napravi <xliff:g id="DEVICENAME">%1$s</xliff:g> za predvajanje v tej napravi"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Predvajanje v napravi <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Predvajanje v tem telefonu"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Prišlo je do napake. Poskusite znova."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ni mogoče najti"</string> @@ -870,6 +870,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Shrani"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Začenjanje …"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Oddajanje ni mogoče"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ni mogoče shraniti. Poskusite znova."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ni mogoče shraniti."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string> <string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string> @@ -956,6 +958,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Uredi kopirano besedilo"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Uredi kopirano sliko"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Pošlji v napravo v bližini"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml index f1ebee4f8f92..9314531ce0ed 100644 --- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Izklopljeno"</item> <item msgid="460891964396502657">"Vklopljeno"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 601d280f36a3..03d6c28ef5ef 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Provo ta nxjerrësh përsëri pamjen e ekranit"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Pamja e ekranit nuk mund të ruhet"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Nxjerrja e pamjeve të ekranit nuk lejohet nga aplikacioni ose organizata jote."</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Shkrepja e pamjeve të ekranit është bllokuar nga administratori i teknologjisë së informacionit"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Modifiko"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Modifiko pamjen e ekranit"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Ndaj pamjen e ekranit"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rrotullim automatik"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rrotullimi automatik i ekranit"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Vendndodhja"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Qasja te kamera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Qasja te mikrofoni"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"E disponueshme"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</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="530725155985223497">"Shto një kartë"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Po përditësohet"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Shkyçe për ta përdorur"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Pati një problem me marrjen e kartave të tua. Provo përsëri më vonë"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Aktivizoje kur bateria mund të mbarojë"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Jo"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Hidh grumbullin SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Në përdorim"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacionet po përdorin <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dhe "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Afrohu për të luajtur në <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Afrohu te <xliff:g id="DEVICENAME">%1$s</xliff:g> për ta luajtur këtu"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Po luhet në <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Po luhet në këtë telefon"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Ndodhi një gabim. Provo përsëri."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Joaktive, kontrollo aplikacionin"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nuk u gjet"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Ruaj"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Po fillon…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nuk mund të transmetohet"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nuk mund të ruhet. Provo përsëri."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nuk mund të ruhet."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string> <string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Modifiko tekstin e kopjuar"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Modifiko imazhin e kopjuar"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Dërgo te pajisja në afërsi"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml index e24abf64c6f8..7bb33c48cce6 100644 --- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Joaktiv"</item> <item msgid="460891964396502657">"Aktiv"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 0069d444a83d..48a5d23762f1 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -228,6 +227,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аутоматска ротација"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аутоматско ротирање екрана"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Приступ камери"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Приступ микрофону"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Доступно"</string> @@ -472,7 +473,8 @@ <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="530725155985223497">"Додајте картицу"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ажурира се"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Откључај ради коришћења"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Дошло је до проблема при преузимању картица. Пробајте поново касније"</string> @@ -734,8 +736,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Укључите ако ће батерија вероватно да се испразни"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Не, хвала"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Издвоји SysUI мем."</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"У употреби"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликације користе <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string> @@ -834,7 +835,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближите да бисте пуштали музику на: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближите се уређају <xliff:g id="DEVICENAME">%1$s</xliff:g> да бисте на њему пуштали"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пушта се на уређају <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Пушта се на овом телефону"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Дошло је до грешке. Пробајте поново."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string> @@ -864,6 +864,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сачувај"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Покреће се…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Емитовање није успело"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Чување није успело. Пробајте поново."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Чување није успело."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string> <string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string> @@ -949,6 +951,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Измените копирани текст"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Измените копирану слику"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Пошаљи на уређај у близини"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml index 0cef5a66c232..fc1646664d26 100644 --- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Искључено"</item> <item msgid="460891964396502657">"Укључено"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 550b3f57a4d8..9c1581fa66c9 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Testa att ta en skärmbild igen"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Det gick inte att spara skärmbilden"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisationen tillåter inte att du tar skärmbilder"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Möjligheten att ta skärmbilder blockeras av IT-administratören"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Redigera"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Redigera skärmbild"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Dela skärmbild"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotera automatiskt"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotera skärmen automatiskt"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Plats"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameraåtkomst"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonåtkomst"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tillgänglig"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Lägg till en betalningsmetod för att betala snabbare och säkrare med telefonen"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Visa alla"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Lägg till ett kort"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Uppdaterar"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Lås upp för att använda"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Det gick inte att hämta dina kort. Försök igen senare."</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Aktivera när batteriet håller på att ta slut"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Nej tack"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI-heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Används"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"<xliff:g id="TYPES_LIST">%s</xliff:g> används av appar."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" och "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flytta närmare för att spela upp på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Flytta dig närmare <xliff:g id="DEVICENAME">%1$s</xliff:g> om du vill spela här"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Spelas upp på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Spelas upp på denna telefon"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Något gick fel. Försök igen."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Hittades inte"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Spara"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Startar …"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Det gick inte att sända ut"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Det gick inte att spara. Försök igen."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Det gick inte att spara."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string> <string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Redigera kopierad text"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Redigera kopierad bild"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Skicka till enhet i närheten"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml index 410a6bc4645f..fbe8bdef3efc 100644 --- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Av"</item> <item msgid="460891964396502657">"På"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 588a76d9c3cf..8f62f82045f3 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Jaribu kupiga picha ya skrini tena"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Imeshindwa kuhifadhi picha ya skrini"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Programu au shirika lako halikuruhusu kupiga picha za skrini"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Kupiga picha za skrini kumezuiwa na Msimamizi wako wa TEHAMA"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Badilisha"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Badilisha picha ya skrini"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Shiriki picha ya skrini"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Zungusha kiotomatiki"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Skrini ijizungushe kiotomatiki"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Mahali"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Ufikiaji wa kamera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Ufikiaji wa maikrofoni"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Unapatikana"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Weka njia ya kulipa ili uweze kununua kwa njia salama na haraka zaidi ukitumia simu yako"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Onyesha zote"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Weka kadi"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Inasasisha"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Fungua ili utumie"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Hitilafu imetokea wakati wa kuleta kadi zako, tafadhali jaribu tena baadaye"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Washa wakati betri inakaribia kuisha"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Hapana"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Inatumika"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programu zinatumia <xliff:g id="TYPES_LIST">%s</xliff:g> yako."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" na "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Telezesha kidole ili uone zaidi"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Inapakia mapendekezo"</string> <string name="controls_media_title" msgid="1746947284862928133">"Maudhui"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Ungependa kuficha kidhibiti hiki cha maudhui kwa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Ungependa kuficha kidhibiti hiki kwa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Kipindi cha sasa cha maudhui hakiwezi kufichwa."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ficha"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Sogea karibu ili ucheze kwenye <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Sogeza karibu na <xliff:g id="DEVICENAME">%1$s</xliff:g> ili kucheza hapa"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Inacheza kwenye <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Inacheza kwenye simu hii"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Hitilafu fulani imetokea. Jaribu tena."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Hakipatikani"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Hifadhi"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Inaanza…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Imeshindwa kutuma arifa"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Imeshindwa kuhifadhi. Jaribu tena."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Imeshindwa kuhifadhi."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string> <string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Badilisha maandishi yaliyonakiliwa"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Badilisha picha iliyonakiliwa"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Tuma kwenye kifaa kilicho karibu"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml index 79d29ab7b11e..b9307af8f321 100644 --- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Imezimwa"</item> <item msgid="460891964396502657">"Imewashwa"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 17d4cab95a24..e5c59846a501 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ஸ்கிரீன்ஷாட்கள் எடுப்பதை உங்கள் IT நிர்வாகி தடைசெய்துள்ளார்"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"தானாகச் சுழற்று"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"திரையைத் தானாகச் சுழற்று"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"இருப்பிடம்"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"கேமரா அணுகல்"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"மைக் அணுகல்"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"கிடைக்கிறது"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"கார்டைச் சேர்"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"புதுப்பிக்கிறது"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"பயன்படுத்துவதற்கு அன்லாக் செய்க"</string> <string name="wallet_error_generic" msgid="257704570182963611">"உங்கள் கார்டுகளின் விவரங்களைப் பெறுவதில் சிக்கல் ஏற்பட்டது, பிறகு முயலவும்"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"பேட்டரி தீர்ந்துபோகும் நிலையில் இருக்கும் போது ஆன் செய்யப்படும்"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"வேண்டாம்"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"உபயோகத்தில் உள்ளது"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"உங்கள் <xliff:g id="TYPES_LIST">%s</xliff:g> ஆகியவற்றை ஆப்ஸ் பயன்படுத்துகின்றன."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" மற்றும் "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்தில் இயக்க உங்கள் சாதனத்தை அருகில் எடுத்துச் செல்லுங்கள்"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"இங்கு பிளே செய்ய உங்கள் சாதனத்தை <xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்திற்கு அருகில் நகர்த்துங்கள்"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்தில் பிளே ஆகிறது"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"இந்த மொபைலில் பிளே ஆகிறது"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ஏதோ தவறாகிவிட்டது. மீண்டும் முயலவும்."</string> <string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string> <string name="controls_error_removed" msgid="6675638069846014366">"இல்லை"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"சேமி"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"தொடங்குகிறது…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ஒளிபரப்ப முடியவில்லை"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"சேமிக்க முடியவில்லை. மீண்டும் முயலவும்."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"சேமிக்க முடியவில்லை."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string> <string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"நகலெடுத்த வார்த்தைகளைத் திருத்து"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"நகலெடுத்த படத்தைத் திருத்து"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"அருகிலுள்ள சாதனத்திற்கு அனுப்பு"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml index 52fca126922e..bd58c9d0f03d 100644 --- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"முடக்கப்பட்டுள்ளது"</item> <item msgid="460891964396502657">"இயக்கப்பட்டுள்ளது"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 8f04626b82b7..42e98921c333 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"స్క్రీన్షాట్లు తీయడాన్ని మీ IT అడ్మిన్ బ్లాక్ చేశారు"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ఆటో-రొటేట్"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"స్క్రీన్ ఆటో-రొటేట్"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"లొకేషన్"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"కెమెరా యాక్సెస్"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"మైక్ యాక్సెస్"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"అందుబాటులో ఉంది"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"కార్డ్ను జోడించండి"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"అప్డేట్ చేస్తోంది"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ఉపయోగించడానికి అన్లాక్ చేయండి"</string> <string name="wallet_error_generic" msgid="257704570182963611">"మీ కార్డ్లను పొందడంలో సమస్య ఉంది, దయచేసి తర్వాత మళ్లీ ట్రై చేయండి"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"బ్యాటరీ ఛార్జింగ్ పూర్తిగా అయిపోతున్న తరుణంలో ఆన్ చేస్తుంది"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"వద్దు, ధన్యవాదాలు"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"డంప్ SysUI హీప్"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"వినియోగంలో ఉంది"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"అప్లికేషన్లు మీ <xliff:g id="TYPES_LIST">%s</xliff:g>ని ఉపయోగిస్తున్నాయి."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" మరియు "</string> @@ -808,9 +809,9 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"మరిన్నింటిని చూడటం కోసం స్వైప్ చేయండి"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"సిఫార్సులు లోడ్ అవుతున్నాయి"</string> <string name="controls_media_title" msgid="1746947284862928133">"మీడియా"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం ఈ మీడియా కంట్రోల్ను దాచాలా?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసమై ఏర్పరిచిన ఈ మీడియా కంట్రోల్ను దాచాలా?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"ప్రస్తుత మీడియా సెషన్ను దాచడం సాధ్యం కాదు."</string> - <string name="controls_media_dismiss_button" msgid="4485675693008031646">"దాచు"</string> + <string name="controls_media_dismiss_button" msgid="4485675693008031646">"దాచండి"</string> <string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్లు"</string> <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి ప్లే అవుతోంది"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>లో ప్లే చేయడానికి దగ్గరగా వెళ్లండి"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ఇక్కడ ప్లే చేయడానికి <xliff:g id="DEVICENAME">%1$s</xliff:g>కి దగ్గరగా వెళ్లండి"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>లో ప్లే అవుతోంది"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"ఈ ఫోన్లో ప్లే అవుతోంది"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ఏదో తప్పు జరిగింది. మళ్లీ ట్రై చేయండి."</string> <string name="controls_error_timeout" msgid="794197289772728958">"ఇన్యాక్టివ్, యాప్ చెక్ చేయండి"</string> <string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"సేవ్ చేయండి"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ప్రారంభించబడుతోంది…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ప్రసారం చేయడం సాధ్యపడలేదు"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"సేవ్ చేయడం సాధ్యపడదు. మళ్లీ ట్రై చేయండి."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"సేవ్ చేయడం సాధ్యపడదు."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్బోర్డ్కు కాపీ చేయబడింది."</string> <string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"కాపీ చేసిన టెక్స్ట్ను ఎడిట్ చేయండి"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"కాపీ చేసిన ఇమేజ్లను ఎడిట్ చేయండి"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"సమీపంలోని పరికరానికి పంపండి"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml index 60997928082e..1bdedcc88ff6 100644 --- a/packages/SystemUI/res/values-te/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"ఆఫ్"</item> <item msgid="460891964396502657">"ఆన్"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 799b5e25abb1..86506bc293d7 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"หมุนอัตโนมัติ"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"หมุนหน้าจออัตโนมัติ"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"ตำแหน่ง"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"สิทธิ์เข้าถึงกล้อง"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"สิทธิ์เข้าถึงไมโครโฟน"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"พร้อมให้ใช้งาน"</string> @@ -346,8 +347,8 @@ <string name="guest_wipe_session_message" msgid="3393823610257065457">"คุณต้องการอยู่ในเซสชันต่อไปไหม"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"เริ่มต้นใหม่"</string> <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ใช่ ดำเนินการต่อ"</string> - <string name="guest_notification_app_name" msgid="2110425506754205509">"โหมดผู้มาเยือน"</string> - <string name="guest_notification_session_active" msgid="5567273684713471450">"คุณอยู่ในโหมดผู้มาเยือน"</string> + <string name="guest_notification_app_name" msgid="2110425506754205509">"โหมดผู้ใช้ชั่วคราว"</string> + <string name="guest_notification_session_active" msgid="5567273684713471450">"คุณอยู่ในโหมดผู้ใช้ชั่วคราว"</string> <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"การเพิ่มผู้ใช้ใหม่จะเป็นการออกจากโหมดผู้มาเยือน และจะลบแอปและข้อมูลจากเซสชันผู้มาเยือนในปัจจุบัน"</string> <string name="user_limit_reached_title" msgid="2429229448830346057">"ถึงขีดจำกัดผู้ใช้แล้ว"</string> <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398"> @@ -422,11 +423,11 @@ <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"เปิดใช้"</string> <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ปิดใช้"</string> <string name="screen_pinning_title" msgid="9058007390337841305">"ปักหมุดแอปอยู่"</string> - <string name="screen_pinning_description" msgid="8699395373875667743">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"กลับ\" และ \"ภาพรวม\" ค้างไว้เพื่อเลิกตรึง"</string> - <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"กลับ\" และ \"หน้าแรก\" ค้างไว้เพื่อเลิกตรึง"</string> + <string name="screen_pinning_description" msgid="8699395373875667743">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกปักหมุด แตะ \"กลับ\" และ \"ภาพรวม\" ค้างไว้เพื่อเลิกปักหมุด"</string> + <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกปักหมุด แตะ \"กลับ\" และ \"หน้าแรก\" ค้างไว้เพื่อเลิกปักหมุด"</string> <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"วิธีนี้ช่วยให้เห็นแอปบนหน้าจอตลอดจนกว่าจะเลิกปักหมุด ปัดขึ้นค้างไว้เพื่อเลิกปักหมุด"</string> - <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"ภาพรวม\" ค้างไว้เพื่อเลิกตรึง"</string> - <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"หน้าแรก\" ค้างไว้เพื่อเลิกตรึง"</string> + <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกปักหมุด แตะ \"ภาพรวม\" ค้างไว้เพื่อเลิกปักหมุด"</string> + <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกปักหมุด แตะ \"หน้าแรก\" ค้างไว้เพื่อเลิกปักหมุด"</string> <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"อาจมีการเข้าถึงข้อมูลส่วนตัว (เช่น รายชื่อติดต่อและเนื้อหาในอีเมล)"</string> <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"แอปที่ปักหมุดไว้อาจเปิดแอปอื่นๆ"</string> <string name="screen_pinning_toast" msgid="8177286912533744328">"หากต้องการเลิกปักหมุดแอปนี้ ให้แตะปุ่ม \"กลับ\" และ \"ภาพรวม\" ค้างไว้"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"เพิ่มบัตร"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"กำลังอัปเดต"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ปลดล็อกเพื่อใช้"</string> <string name="wallet_error_generic" msgid="257704570182963611">"เกิดปัญหาในการดึงข้อมูลบัตรของคุณ โปรดลองอีกครั้งในภายหลัง"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"เปิดเมื่อมีแนวโน้มว่าแบตเตอรี่จะหมด"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"ไม่เป็นไร"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"ใช้งานอยู่"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"หลายแอปพลิเคชันใช้<xliff:g id="TYPES_LIST">%s</xliff:g>ของคุณอยู่"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" และ "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"ขยับเข้ามาใกล้ขึ้นเพื่อเล่นใน <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ขยับไปใกล้ <xliff:g id="DEVICENAME">%1$s</xliff:g> มากขึ้นเพื่อเล่นที่นี่"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"กำลังเล่นใน <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"กำลังเล่นในโทรศัพท์เครื่องนี้"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"เกิดข้อผิดพลาด โปรดลองอีกครั้ง"</string> <string name="controls_error_timeout" msgid="794197289772728958">"ไม่มีการใช้งาน โปรดตรวจสอบแอป"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ไม่พบ"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"บันทึก"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"กำลังเริ่มต้น…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ออกอากาศไม่ได้"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"บันทึกไม่ได้ โปรดลองอีกครั้ง"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"บันทึกไม่ได้"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string> <string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"แก้ไขข้อความที่คัดลอก"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"แก้ไขรูปภาพที่คัดลอก"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ส่งไปยังอุปกรณ์ที่อยู่ใกล้เคียง"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml index 4565f35fbef2..56c206c40d13 100644 --- a/packages/SystemUI/res/values-th/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"ปิด"</item> <item msgid="460891964396502657">"เปิด"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 6d2dff064a32..9bbfe6c9614a 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Subukang kumuhang muli ng screenshot"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Hindi ma-save ang screenshot"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Hindi pinahihintulutan ng app o ng iyong organisasyon ang pagkuha ng mga screenshot"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Na-block ng iyong IT admin ang pagkuha ng mga screenshot"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"I-edit"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"I-edit ang screenshot"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Ibahagi ang screenshot"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"I-auto rotate"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Awtomatikong i-rotate ang screen"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasyon"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Access sa camera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Access sa mic"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"I-set up para makapagsagawa ng mas mabibilis, mas secure na pagbili gamit ang telepono mo"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Ipakita lahat"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Magdagdag ng card"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ina-update"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"I-unlock para magamit"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Nagkaproblema sa pagkuha ng iyong mga card, pakisubukan ulit sa ibang pagkakataon"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"I-on kapag malamang na maubos ang baterya"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Hindi, salamat na lang"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Ginagamit"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Ginagamit ng mga application ang iyong <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" at "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Lumapit pa para mag-play sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Lumapit sa <xliff:g id="DEVICENAME">%1$s</xliff:g> para mag-play rito"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Nagpe-play sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Nagpe-play sa teleponong ito"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Nagkaproblema. Subukan ulit."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Hindi nahanap"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"I-save"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Nagsisimula…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Hindi makapag-broadcast"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Hindi ma-save. Subukan ulit."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Hindi ma-save."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string> <string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"I-edit ang kinopyang text"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"I-edit ang kinopyang larawan"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Ipadala sa kalapit na device"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml index 59fed0f6b247..a309c16a8825 100644 --- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Naka-off"</item> <item msgid="460891964396502657">"Naka-on"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 3a7a0eed47d2..9d5a198a088e 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Tekrar ekran görüntüsü almayı deneyin"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ekran görüntüsü kaydedilemiyor"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Uygulama veya kuruluşunuz, ekran görüntüsü alınmasına izin vermiyor."</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"BT yöneticiniz ekran görüntüsü almayı engelledi"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Düzenle"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Ekran görüntüsünü düzenle"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Ekranı paylaş"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Otomatik döndür"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranı otomatik döndür"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Konum"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kamera erişimi"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofon erişimi"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Kullanılabilir"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Cüzdan"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Telefonunuzla daha hızlı ve güvenli satın alma işlemleri gerçekleştirmek için gerekli ayarları yapın"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Tümünü göster"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Kart ekleyin"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Güncelleniyor"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Kullanmak için kilidi aç"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Kartlarınız alınırken bir sorun oluştu. Lütfen daha sonra tekrar deneyin"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Piliniz bitecek gibiyse bu özelliği açın"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Hayır, teşekkürler"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI Yığın Dökümü"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Kullanımda"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Uygulamalar şunları kullanıyor: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ve "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında çalmak için yaklaşın"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Burada oynatmak için <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaklaşın"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oynatılıyor"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Bu telefonda oynatılıyor"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Bir sorun oldu. Tekrar deneyin."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Bulunamadı"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Kaydet"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Başlatılıyor…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayınlanamıyor"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kaydedilemiyor. Tekrar deneyin."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kaydedilemiyor."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string> <string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Kopyalanan metni düzenle"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Kopyalanan resmi düzenle"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Yakındaki cihaza gönder"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml index d06d72715d44..b82aac47a722 100644 --- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Kapalı"</item> <item msgid="460891964396502657">"Açık"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 06a8679ff9e3..2ceb3d8c1422 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <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> @@ -229,6 +228,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматичне обертання"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично обертати екран"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Геодані"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ до камери"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Доступ до мікрофона"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Дозволено"</string> @@ -475,7 +476,8 @@ <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="530725155985223497">"Додати картку"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Оновлення"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Розблокувати, щоб використовувати"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Не вдалось отримати ваші картки. Повторіть спробу пізніше."</string> @@ -535,7 +537,7 @@ <string name="feedback_prompt" msgid="3656728972307896379">"Надішліть розробнику свій відгук. Усе правильно?"</string> <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Елементи керування сповіщеннями для додатка <xliff:g id="APP_NAME">%1$s</xliff:g> відкрито"</string> <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"Елементи керування сповіщеннями для додатка <xliff:g id="APP_NAME">%1$s</xliff:g> закрито"</string> - <string name="notification_more_settings" msgid="4936228656989201793">"Більше налаштувань"</string> + <string name="notification_more_settings" msgid="4936228656989201793">"Інші налаштування"</string> <string name="notification_app_settings" msgid="8963648463858039377">"Налаштувати"</string> <string name="notification_conversation_bubble" msgid="2242180995373949022">"Показувати як спливаюче сповіщення"</string> <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Вимкнути спливаючі чати"</string> @@ -739,8 +741,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Вмикати, коли заряд акумулятора закінчується"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Ні, дякую"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Використовується"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Додатки використовують <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" і "</string> @@ -820,7 +821,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Гортайте, щоб переглянути інші"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Завантаження рекомендацій"</string> <string name="controls_media_title" msgid="1746947284862928133">"Медіа"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"Приховати цей елемент керування медіасеансом для <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"Приховати цей елемент керування для <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Поточний медіасеанс не можна приховати."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Приховати"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Відновити"</string> @@ -840,7 +841,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Щоб відтворити контент на пристрої <xliff:g id="DEVICENAME">%1$s</xliff:g>, наблизьтеся до нього"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Наблизьтеся до пристрою <xliff:g id="DEVICENAME">%1$s</xliff:g>, щоб відтворити медіафайли на ньому"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Відтворюється на пристрої <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Відтворюється на цьому телефоні"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Сталася помилка. Повторіть спробу."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не знайдено"</string> @@ -870,6 +870,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Зберегти"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Запуск…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Неможливо транслювати"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не вдалося зберегти. Повторіть спробу."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не вдалося зберегти."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string> <string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string> @@ -956,6 +958,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Редагувати скопійований текст"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Редагувати скопійоване зображення"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Надіслати на пристрій поблизу"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml index 040fb4d3d6e3..a3018a271ac1 100644 --- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Вимкнено"</item> <item msgid="460891964396502657">"Увімкнено"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 3b5e1a38cfac..f36d5e203a1a 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT منتظم نے اسکرین شاٹس لینا مسدود کر دیا ہے"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"خود کار طور پر گھمائیں"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"اسکرین کو خود کار طور پر گھمائیں"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"مقام"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"کیمرا تک رسائی"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"مائیکروفون تک رسائی"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"دستیاب ہے"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"کارڈ شامل کریں"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"اپ ڈیٹ ہو رہا ہے"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"استعمال کرنے کے لیے غیر مقفل کریں"</string> <string name="wallet_error_generic" msgid="257704570182963611">"آپ کے کارڈز حاصل کرنے میں ایک مسئلہ درپیش تھا، براہ کرم بعد میں دوبارہ کوشش کریں"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"جب بیٹری کے ختم ہونے کا امکان ہو تو آن کریں"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"نہیں شکریہ"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"زیر استعمال"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ایپلیکیشنز آپ کی <xliff:g id="TYPES_LIST">%s</xliff:g> کا استعمال کر رہی ہیں۔"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" اور "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"مزید دیکھنے کیلئے سوائپ کریں"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"تجاویز لوڈ ہو رہی ہیں"</string> <string name="controls_media_title" msgid="1746947284862928133">"میڈیا"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے اس میڈیا کنٹرول کو چھپائیں؟"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے اس میڈیا کنٹرول کو چھپائیں؟"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"میڈیا کے موجودہ سیشن کو چھپایا نہیں جا سکتا۔"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"چھپائیں"</string> <string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چلانے کے لیے قریب کریں"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"یہاں چلانے کے ليے <xliff:g id="DEVICENAME">%1$s</xliff:g> کے قریب جائیں"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چل رہا ہے"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"اس فون پر چل رہا ہے"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"کچھ غلط ہوگیا۔ پھر کوشش کریں۔"</string> <string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string> <string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"محفوظ کریں"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"شروع ہو رہا ہے…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"براڈکاسٹ نہیں کیا جا سکتا"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"محفوظ نہیں کیا جا سکا۔ پھر کوشش کریں۔"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"محفوظ نہیں کیا جا سکا۔"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string> <string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"کاپی کردہ ٹیکسٹ میں ترمیم کریں"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"کاپی کردہ تصویر میں ترمیم کریں"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"قریبی آلے کو بھیجیں"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml index 79d2cf6d0624..46c10004f5a8 100644 --- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"آف"</item> <item msgid="460891964396502657">"آن"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index f30942035cc9..d7366590ff4d 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Qayta skrinshot olib ko‘ring"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Skrinshot saqlanmadi"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ilova yoki tashkilotingiz skrinshot olishni taqiqlagan"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Skrinshot olishni AT administratori taqiqlagan"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Tahrirlash"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Skrinshotni tahrirlash"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Skrinshot yuborish"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avto-burilish"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranning avtomatik burilishi"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Joylashuv"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameraga ruxsat"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonga ruxsat"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Mavjud"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Telefonda tezroq va xavfsizroq xarid qilish uchun sozlang"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Hammasi"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Karta kiritish"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Yangilanmoqda"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Foydalanish uchun qulfdan chiqarish"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Bildirgilarni yuklashda xatolik yuz berdi, keyinroq qaytadan urining"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Batareya quvvati kamayishi aniqlanganda yoqilsin"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Kerak emas"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Foydalanilmoqda"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Ilovalarda ishlatilmoqda: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" va "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Batafsil axborot olish uchun suring"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Tavsiyalar yuklanmoqda"</string> <string name="controls_media_title" msgid="1746947284862928133">"Media"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun media boshqaruvi yashirilsinmi?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun media boshqaruvi berkitilsinmi?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"Joriy media seansi berkitilmadi."</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Berkitish"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Davom etish"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>da ijro etish uchun yaqinroq keling"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Bu yerda ijro qilish uchun <xliff:g id="DEVICENAME">%1$s</xliff:g>qurilmasiga yaqinlashtiring"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> qurilmasida ijro qilinmoqda"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Bu telefonda ijro etilmoqda"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Xatolik yuz berdi. Qayta urining."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Nofaol. Ilovani tekshiring"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Topilmadi"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Saqlash"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Ishga tushmoqda…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Uzatilmadi"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Saqlanmadi. Qayta urining."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Saqlanmadi."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string> <string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Nusxa olingan matnni tahrirlash"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Nusxa olingan rasmni tahrirlash"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Yaqin-atrofdagi qurilmaga yuborish"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml index b6875974d2de..417749cad72b 100644 --- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Oʻchiq"</item> <item msgid="460891964396502657">"Yoniq"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index c70400acbc33..b7fd663c9141 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Hãy thử chụp lại màn hình"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Không thể lưu ảnh chụp màn hình"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ứng dụng hoặc tổ chức của bạn không cho phép chụp ảnh màn hình"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Quản trị viên CNTT chặn tính năng chụp ảnh màn hình"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Chỉnh sửa"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Chỉnh sửa ảnh chụp màn hình"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Chia sẻ ảnh chụp màn hình"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Tự động xoay"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Tự động xoay màn hình"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Vị trí"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Truy cập máy ảnh"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Truy cập micrô"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Được phép"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"Ví"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Thiết lập để mua hàng nhanh hơn và an toàn hơn bằng điện thoại"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Hiện tất cả"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Thêm thẻ"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Đang cập nhật"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Mở khóa để sử dụng"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Đã xảy ra sự cố khi tải thẻ của bạn. Vui lòng thử lại sau"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Bật khi pin sắp hết"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Không, cảm ơn"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Trích xuất bộ nhớ SysUI"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Đang được sử dụng"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Các ứng dụng đang dùng <xliff:g id="TYPES_LIST">%s</xliff:g> của bạn."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" và "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Đưa thiết bị đến gần hơn để phát trên <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Di chuyển đến gần <xliff:g id="DEVICENAME">%1$s</xliff:g> hơn để phát tại đây"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Đang phát trên <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Đang phát trên điện thoại này"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Đã xảy ra lỗi. Hãy thử lại."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Không tìm thấy"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Lưu"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Đang bắt đầu…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Không thể truyền"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Không lưu được. Hãy thử lại."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Không lưu được."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string> <string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Chỉnh sửa văn bản đã sao chép"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Chỉnh sửa hình ảnh đã sao chép"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Gửi đến thiết bị ở gần"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <string name="add" msgid="81036585205287996">"Thêm"</string> <string name="manage_users" msgid="1823875311934643849">"Quản lý người dùng"</string> <string name="drag_split_not_supported" msgid="4326847447699729722">"Thông báo này không hỗ trợ thao tác kéo để Chia đôi màn hình."</string> diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml index 827c72ae2867..95c089debd3e 100644 --- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Đang tắt"</item> <item msgid="460891964396502657">"Đang bật"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 230e6f5f2641..f5f647b83c90 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"您的 IT 管理员已禁止截取屏幕截图"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自动旋转屏幕"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自动旋转屏幕"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"位置信息"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"摄像头使用权限"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"麦克风使用权限"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"已允许"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"添加卡"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"正在更新"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"解锁设备即可使用"</string> <string name="wallet_error_generic" msgid="257704570182963611">"获取您的卡片时出现问题,请稍后重试"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"在电池电量可能会耗尽时,系统会开启此模式"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"不用了"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"转储 SysUI 堆"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"正在使用"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多个应用正在使用您的<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"若要在“<xliff:g id="DEVICENAME">%1$s</xliff:g>”上播放,请靠近这台设备"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"若要在此设备上播放,请靠近“<xliff:g id="DEVICENAME">%1$s</xliff:g>”"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在“<xliff:g id="DEVICENAME">%1$s</xliff:g>”上播放"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"正在此手机上播放"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"出了点问题,请重试。"</string> <string name="controls_error_timeout" msgid="794197289772728958">"无效,请检查应用"</string> <string name="controls_error_removed" msgid="6675638069846014366">"未找到"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"保存"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"即将开始…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"无法广播"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"无法保存,请重试。"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"无法保存。"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string> <string name="basic_status" msgid="2315371112182658176">"开放式对话"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"修改所复制的文字"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"编辑所复制的图片"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"发送到附近的设备"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml index 3c628721aa5b..f19cfa24f0d7 100644 --- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"已关闭"</item> <item msgid="460891964396502657">"已开启"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 9233be06b13b..5848bc54bd64 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"您的 IT 管理員已禁止擷取螢幕截圖"</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> @@ -143,21 +142,21 @@ <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"已識別面孔。按解鎖圖示即可繼續。"</string> <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"驗證咗"</string> <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN"</string> - <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用圖形"</string> + <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用圖案"</string> <string name="biometric_dialog_use_password" msgid="3445033859393474779">"使用密碼"</string> <string name="biometric_dialog_wrong_pin" msgid="1878539073972762803">"PIN 錯誤"</string> - <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"圖形錯誤"</string> + <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"圖案錯誤"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"密碼錯誤"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"輸入錯誤的次數太多,\n請於 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試。"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"請再試一次。您已嘗試 <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> 次,最多可試 <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> 次。"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"您的資料將會刪除"</string> - <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"如果您下次畫出錯誤的上鎖圖形,系統將會刪除此裝置上的資料。"</string> + <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"如果您下次畫出錯誤的上鎖圖案,系統將會刪除此裝置上的資料。"</string> <string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"如果您下次輸入錯誤的 PIN,系統將會刪除此裝置上的資料。"</string> <string name="biometric_dialog_last_password_attempt_before_wipe_device" msgid="2363778585575998317">"如果您下次輸入錯誤的密碼,系統將會刪除此裝置上的資料。"</string> - <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"如果您下次畫出錯誤的上鎖圖形,系統將會刪除此使用者。"</string> + <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"如果您下次畫出錯誤的上鎖圖案,系統將會刪除此使用者。"</string> <string name="biometric_dialog_last_pin_attempt_before_wipe_user" msgid="4159878829962411168">"如果您下次輸入錯誤的 PIN,系統將會刪除此使用者。"</string> <string name="biometric_dialog_last_password_attempt_before_wipe_user" msgid="4695682515465063885">"如果您下次輸入錯誤的密碼,系統將會刪除此使用者。"</string> - <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"如果您下次畫出錯誤的上鎖圖形,系統將會刪除工作設定檔和相關資料。"</string> + <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"如果您下次畫出錯誤的上鎖圖案,系統將會刪除工作設定檔和相關資料。"</string> <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"如果您下次輸入錯誤的 PIN,系統將會刪除工作設定檔和相關資料。"</string> <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"如果您下次輸入錯誤的密碼,系統將會刪除工作設定檔和相關資料。"</string> <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"請輕觸指紋感應器"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"位置"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"相機存取權"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"麥克風存取權"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"允許"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"新增付款卡"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"更新中"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"解鎖即可使用"</string> <string name="wallet_error_generic" msgid="257704570182963611">"擷取資訊卡時發生問題,請稍後再試。"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"在電池電量可能耗盡前啟用「省電模式」"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"不用了,謝謝"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"使用中"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"如要在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放,請靠近一點"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"如要在此裝置上播放,請靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"正在此手機上播放"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string> <string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string> <string name="controls_error_removed" msgid="6675638069846014366">"找不到"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"儲存"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"啟動中…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"無法儲存,請再試一次。"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"無法儲存。"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string> <string name="basic_status" msgid="2315371112182658176">"開啟對話"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"編輯已複製的文字"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"編輯已複製的圖片"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"傳送至附近的裝置"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml index ee4106639a67..6020627fef20 100644 --- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"關閉"</item> <item msgid="460891964396502657">"開啟"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 11073b93ddd6..fcbf19d9a92b 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -78,8 +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> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"你的 IT 管理員已禁止擷取螢幕畫面"</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> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"定位"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"相機存取權"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"麥克風存取權"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"可以使用"</string> @@ -469,7 +470,8 @@ <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="530725155985223497">"新增卡片"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"更新中"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"解鎖即可使用"</string> <string name="wallet_error_generic" msgid="257704570182963611">"擷取卡片時發生問題,請稍後再試"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"在電池電量即將耗盡時開啟"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"不用了,謝謝"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"使用中"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string> @@ -808,7 +809,7 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"滑動即可查看其他結構"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"正在載入建議控制項"</string> <string name="controls_media_title" msgid="1746947284862928133">"媒體"</string> - <string name="controls_media_close_session" msgid="4780485355795635052">"要隱藏「<xliff:g id="APP_NAME">%1$s</xliff:g>」的這個媒體控制選項嗎?"</string> + <string name="controls_media_close_session" msgid="4780485355795635052">"要隱藏「<xliff:g id="APP_NAME">%1$s</xliff:g>」的媒體控制選項嗎?"</string> <string name="controls_media_active_session" msgid="3146882316024153337">"無法隱藏目前的媒體工作階段。"</string> <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string> <string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"如要在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放,請靠近一點"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"如要在這部裝置上播放,請移到更靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」的位置"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"正在這支手機上播放"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string> <string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string> <string name="controls_error_removed" msgid="6675638069846014366">"找不到控制項"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"儲存"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"啟動中…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"無法儲存,請再試一次。"</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"無法儲存。"</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string> <string name="basic_status" msgid="2315371112182658176">"開放式對話"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"編輯複製的文字"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"編輯複製的圖片"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"傳送到鄰近裝置"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml index 1f707408b95b..63ea305f4e8e 100644 --- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"已關閉"</item> <item msgid="460891964396502657">"已開啟"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 7425bc6944ba..ebc2a33231c4 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -78,8 +78,7 @@ <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Zama ukuthatha isithombe-skrini futhi"</string> <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ayikwazi ukulondoloza isithombe-skrini"</string> <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ukuthatha izithombe-skrini akuvunyelwe uhlelo lokusebenza noma inhlangano yakho"</string> - <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) --> - <skip /> + <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Ukuthatha isithombe-skrini kuvinjwe umlawuli wakho we-IT"</string> <string name="screenshot_edit_label" msgid="8754981973544133050">"Hlela"</string> <string name="screenshot_edit_description" msgid="3333092254706788906">"Hlela isithombe-skrini"</string> <string name="screenshot_share_description" msgid="2861628935812656612">"Yabelana ngesithombe-skrini"</string> @@ -227,6 +226,8 @@ <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ukuphenduka okuzenzakalelayo"</string> <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Phendula iskrini ngokuzenzakalela"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"Indawo"</string> + <!-- no translation found for quick_settings_screensaver_label (1495003469366524120) --> + <skip /> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Ukufinyelela kwekhamera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Ukufinyelela kwe-mic"</string> <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Iyatholakala"</string> @@ -469,7 +470,8 @@ <string name="wallet_title" msgid="5369767670735827105">"I-wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"Lungela ukuthenga ngokushesha, ngokuphepha ngefoni yakho"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"Bonisa konke"</string> - <string name="wallet_secondary_label_no_card" msgid="530725155985223497">"Engeza ikhadi"</string> + <!-- no translation found for wallet_secondary_label_no_card (8488069304491125713) --> + <skip /> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Iyabuyekeza"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Vula ukuze usebenzise"</string> <string name="wallet_error_generic" msgid="257704570182963611">"Kube khona inkinga yokuthola amakhadi akho, sicela uzame futhi ngemuva kwesikhathi"</string> @@ -729,8 +731,7 @@ <string name="auto_saver_text" msgid="3214960308353838764">"Vula uma ibhethri sekungenzeka liphele"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"Cha ngiyabonga"</string> <string name="heap_dump_tile_name" msgid="2464189856478823046">"I-Dump SysUI Heap"</string> - <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) --> - <skip /> + <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"Kuyasebenza"</string> <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Izinhlelo zokusebenza zisebenzisa i-<xliff:g id="TYPES_LIST">%s</xliff:g> yakho."</string> <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string> <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" kanye "</string> @@ -828,7 +829,6 @@ <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Sondeza eduze ukudlala ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Sondela eduze ne-<xliff:g id="DEVICENAME">%1$s</xliff:g> ukuze udlale lapha"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Idlala ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> - <string name="media_transfer_playing_this_device" msgid="1856890686844499172">"Okudlala kule foni"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Kukhona okungahambanga kahle. Zama futhi."</string> <string name="controls_error_timeout" msgid="794197289772728958">"Akusebenzi, hlola uhlelo lokusebenza"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ayitholakali"</string> @@ -858,6 +858,8 @@ <string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Londoloza"</string> <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iyaqala…"</string> <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ayikwazi ukusakaza"</string> + <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ayikwazi ukulondoloza. Zama futhi."</string> + <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ayikwazi ukulondoloza."</string> <string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string> <string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string> <string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string> @@ -942,6 +944,8 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"Hlela umbhalo okopishiwe"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"Hlela umfanekiso okopishiwe"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"Thumela kudivayisi eseduze"</string> + <!-- no translation found for clipboard_text_hidden (7926899867471812305) --> + <skip /> <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/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml index cc8bbb071449..0cc241c5c7fa 100644 --- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml @@ -171,4 +171,7 @@ <item msgid="146088982397753810">"Valiwe"</item> <item msgid="460891964396502657">"Vuliwe"</item> </string-array> + <!-- no translation found for tile_states_dream:0 (6184819793571079513) --> + <!-- no translation found for tile_states_dream:1 (8014986104355098744) --> + <!-- no translation found for tile_states_dream:2 (5966994759929723339) --> </resources> diff --git a/packages/SystemUI/res/values/defaults.xml b/packages/SystemUI/res/values/defaults.xml deleted file mode 100644 index f96c178b119a..000000000000 --- a/packages/SystemUI/res/values/defaults.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/** - * Copyright (c) 2009, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<resources> - <!-- Default for SystemUiDeviceConfigFlags.DEFAULT_QR_CODE_SCANNER. - To be set if the device wants to support out of the box QR code scanning experience --> - <string name="def_qr_code_component" translatable="false"></string> -</resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index a014efb7d176..be34eaa1a407 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -282,15 +282,12 @@ <!-- Spacing between chip icon and chip text --> <dimen name="overlay_action_chip_spacing">8dp</dimen> <dimen name="overlay_action_chip_text_size">14sp</dimen> - <dimen name="overlay_offset_y">8dp</dimen> <dimen name="overlay_offset_x">16dp</dimen> - <dimen name="overlay_preview_elevation">4dp</dimen> <dimen name="overlay_action_container_margin_horizontal">8dp</dimen> <dimen name="overlay_bg_protection_height">242dp</dimen> <dimen name="overlay_action_container_corner_radius">18dp</dimen> <dimen name="overlay_action_container_padding_vertical">4dp</dimen> <dimen name="overlay_action_container_padding_right">8dp</dimen> - <dimen name="overlay_dismiss_button_elevation">7dp</dimen> <dimen name="overlay_dismiss_button_tappable_size">48dp</dimen> <dimen name="overlay_dismiss_button_margin">8dp</dimen> <dimen name="overlay_border_width">4dp</dimen> @@ -1134,7 +1131,7 @@ <!-- Output switcher panel related dimensions --> <dimen name="media_output_dialog_list_margin">12dp</dimen> - <dimen name="media_output_dialog_list_max_height">364dp</dimen> + <dimen name="media_output_dialog_list_max_height">355dp</dimen> <dimen name="media_output_dialog_header_album_icon_size">72dp</dimen> <dimen name="media_output_dialog_header_back_icon_size">32dp</dimen> <dimen name="media_output_dialog_header_icon_padding">16dp</dimen> @@ -1466,4 +1463,18 @@ <dimen name="media_output_broadcast_info_title_height">24dp</dimen> <dimen name="media_output_broadcast_info_summary_height">20dp</dimen> <dimen name="media_output_broadcast_info_edit">18dp</dimen> + + <!-- Broadcast dialog --> + <dimen name="broadcast_dialog_title_img_margin_top">18dp</dimen> + <dimen name="broadcast_dialog_title_text_size">24sp</dimen> + <dimen name="broadcast_dialog_title_text_margin">16dp</dimen> + <dimen name="broadcast_dialog_title_text_margin_top">18dp</dimen> + <dimen name="broadcast_dialog_subtitle_text_size">14sp</dimen> + <dimen name="broadcast_dialog_icon_size">24dp</dimen> + <dimen name="broadcast_dialog_icon_margin_top">25dp</dimen> + <dimen name="broadcast_dialog_btn_radius">100dp</dimen> + <dimen name="broadcast_dialog_btn_margin_bottom">4dp</dimen> + <dimen name="broadcast_dialog_btn_text_size">16sp</dimen> + <dimen name="broadcast_dialog_btn_minHeight">44dp</dimen> + <dimen name="broadcast_dialog_margin">16dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 1a05970759e6..f0ed31450068 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2534,4 +2534,18 @@ =1 {# notification} other {# notifications} }</string> + + <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, media app is broadcasting --> + <string name="broadcasting_description_is_broadcasting">Broadcasting</string> + <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, title --> + <string name="bt_le_audio_broadcast_dialog_title">Stop broadcasting <xliff:g id="app_name" example="App Name 1">%1$s</xliff:g>?</string> + <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, sub-title --> + <string name="bt_le_audio_broadcast_dialog_sub_title">If you broadcast <xliff:g id="switchApp" example="App Name 2">%1$s</xliff:g> or change the output, your current broadcast will stop</string> + <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, switch to others app. --> + <string name="bt_le_audio_broadcast_dialog_switch_app">Broadcast <xliff:g id="switchApp" example="App Name 2">%1$s</xliff:g></string> + <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, different output. --> + <string name="bt_le_audio_broadcast_dialog_different_output">Change output</string> + <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, media app is unknown --> + <string name="bt_le_audio_broadcast_dialog_unknown_name">Unknown</string> + </resources> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 0c25f5473416..8b2481cff2a9 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -1196,4 +1196,48 @@ <item name="android:shadowColor">@color/keyguard_shadow_color</item> <item name="android:shadowRadius">?attr/shadowRadius</item> </style> + + <style name="BroadcastDialogTitleStyle"> + <item name="android:textAppearance">@style/TextAppearanceBroadcastDialogTitle</item> + <item name="android:layout_marginStart">@dimen/broadcast_dialog_title_text_margin</item> + <item name="android:layout_marginEnd">@dimen/broadcast_dialog_title_text_margin</item> + <item name="android:layout_marginTop">@dimen/broadcast_dialog_title_text_margin_top</item> + <item name="android:layout_marginBottom">18dp</item> + </style> + + <style name="TextAppearanceBroadcastDialogTitle" parent="@android:style/TextAppearance.DeviceDefault.Headline"> + <item name="android:textSize">@dimen/broadcast_dialog_title_text_size</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textDirection">locale</item> + <item name="android:ellipsize">end</item> + </style> + + <style name="BroadcastDialogBodyStyle"> + <item name="android:textAppearance">@style/TextAppearanceBroadcastDialogSubTitle</item> + <item name="android:layout_margin">@dimen/broadcast_dialog_title_text_margin</item> + </style> + + <style name="TextAppearanceBroadcastDialogSubTitle" parent="@android:style/TextAppearance.DeviceDefault.Headline"> + <item name="android:textSize">@dimen/broadcast_dialog_subtitle_text_size</item> + <item name="android:textColor">?android:attr/textColorSecondary</item> + <item name="android:textDirection">locale</item> + <item name="android:ellipsize">end</item> + </style> + + <style name="BroadcastDialogButtonStyle"> + <item name="android:textAppearance">@style/TextAppearanceBroadcastDialogButton</item> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_gravity">center</item> + <item name="android:gravity">center</item> + <item name="android:stateListAnimator">@null</item> + <item name="android:elevation">0dp</item> + <item name="android:minHeight">@dimen/broadcast_dialog_btn_minHeight</item> + <item name="android:background">@drawable/broadcast_dialog_btn_bg</item> + </style> + + <style name="TextAppearanceBroadcastDialogButton" parent="@android:style/TextAppearance.DeviceDefault.Headline"> + <item name="android:textColor">?androidprv:attr/textColorOnAccent</item> + <item name="android:textSize">@dimen/broadcast_dialog_btn_text_size</item> + </style> </resources> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java index 6345d113faed..1d6a3bf3b62e 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/navigationbar/RegionSamplingHelper.java @@ -92,9 +92,18 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener, } }; + /** + * @deprecated Pass a main executor. + */ public RegionSamplingHelper(View sampledView, SamplingCallback samplingCallback, Executor backgroundExecutor) { this(sampledView, samplingCallback, sampledView.getContext().getMainExecutor(), + backgroundExecutor); + } + + public RegionSamplingHelper(View sampledView, SamplingCallback samplingCallback, + Executor mainExecutor, Executor backgroundExecutor) { + this(sampledView, samplingCallback, mainExecutor, backgroundExecutor, new SysuiCompositionSamplingListener()); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index f5e31dd84e8a..7df3b69667bb 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -188,6 +188,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private static final int MSG_KEYGUARD_GOING_AWAY = 342; private static final int MSG_TIME_FORMAT_UPDATE = 344; private static final int MSG_REQUIRE_NFC_UNLOCK = 345; + private static final int MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED = 346; /** Biometric authentication state: Not listening. */ private static final int BIOMETRIC_STATE_STOPPED = 0; @@ -2025,6 +2026,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab case MSG_REQUIRE_NFC_UNLOCK: handleRequireUnlockForNfc(); break; + case MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED: + handleKeyguardDismissAnimationFinished(); + break; default: super.handleMessage(msg); break; @@ -2815,7 +2819,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab * Note: checking fingerprint enrollment directly with the AuthController requires an IPC. */ public boolean getCachedIsUnlockWithFingerprintPossible(int userId) { - return mIsUnlockWithFingerprintPossible.get(userId); + return mIsUnlockWithFingerprintPossible.getOrDefault(userId, false); } private boolean isUnlockWithFacePossible(int userId) { @@ -3297,6 +3301,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } /** + * Handle {@link #MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED} + */ + private void handleKeyguardDismissAnimationFinished() { + Assert.isMainThread(); + for (int i = 0; i < mCallbacks.size(); i++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); + if (cb != null) { + cb.onKeyguardDismissAnimationFinished(); + } + } + } + + /** * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION} */ private void handleReportEmergencyCallAction() { @@ -3634,6 +3651,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mHandler.sendMessage(mHandler.obtainMessage(MSG_KEYGUARD_GOING_AWAY, goingAway)); } + /** + * Sends a message to notify the keyguard dismiss animation is finished. + */ + public void dispatchKeyguardDismissAnimationFinished() { + mHandler.sendEmptyMessage(MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED); + } + public boolean isDeviceInteractive() { return mDeviceInteractive; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index 2620195ae8c4..051b81e484d8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -109,6 +109,14 @@ public class KeyguardUpdateMonitorCallback { public void onKeyguardBouncerFullyShowingChanged(boolean bouncerIsFullyShowing) { } /** + * Called when the dismissing animation of keyguard and surfaces behind is finished. + * If the surface behind is the Launcher, we may still be playing in-window animations + * when this is called (since it's only called once we dismiss the keyguard and end the + * remote animation). + */ + public void onKeyguardDismissAnimationFinished() { } + + /** * Called when visibility of lockscreen clock changes, such as when * obscured by a widget. */ diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index dd312186afee..ca731c50f48c 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -957,11 +957,19 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab } else { pw.println(" mScreenDecorHwcLayer: null"); } - pw.println(" mOverlays(left,top,right,bottom)=(" - + (mOverlays != null && mOverlays[BOUNDS_POSITION_LEFT] != null) + "," - + (mOverlays != null && mOverlays[BOUNDS_POSITION_TOP] != null) + "," - + (mOverlays != null && mOverlays[BOUNDS_POSITION_RIGHT] != null) + "," - + (mOverlays != null && mOverlays[BOUNDS_POSITION_BOTTOM] != null) + ")"); + if (mOverlays != null) { + pw.println(" mOverlays(left,top,right,bottom)=(" + + (mOverlays[BOUNDS_POSITION_LEFT] != null) + "," + + (mOverlays[BOUNDS_POSITION_TOP] != null) + "," + + (mOverlays[BOUNDS_POSITION_RIGHT] != null) + "," + + (mOverlays[BOUNDS_POSITION_BOTTOM] != null) + ")"); + + for (int i = BOUNDS_POSITION_LEFT; i < BOUNDS_POSITION_LENGTH; i++) { + if (mOverlays[i] != null) { + mOverlays[i].dump(pw, getWindowTitleByPos(i)); + } + } + } mRoundedCornerResDelegate.dump(pw, args); } diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index 56fbe6d9bf14..6b859763eb6f 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -102,6 +102,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, AppOpsManager.OP_RECORD_AUDIO, + AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION @@ -375,7 +376,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon Log.w(TAG, String.format("onActiveChanged(%d,%d,%s,%s,%d,%d)", code, uid, packageName, Boolean.toString(active), attributionChainId, attributionFlags)); } - if (attributionChainId != AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE + if (active && attributionChainId != AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE && attributionFlags != AppOpsManager.ATTRIBUTION_FLAGS_NONE && (attributionFlags & AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR) == 0 && (attributionFlags & AppOpsManager.ATTRIBUTION_FLAG_TRUSTED) == 0) { @@ -535,7 +536,8 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon } private boolean isOpMicrophone(int op) { - return op == AppOpsManager.OP_RECORD_AUDIO || op == AppOpsManager.OP_PHONE_CALL_MICROPHONE; + return op == AppOpsManager.OP_RECORD_AUDIO || op == AppOpsManager.OP_PHONE_CALL_MICROPHONE + || op == AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO; } protected class H extends Handler { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt index 4cd40d2f186b..203578123999 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt @@ -15,9 +15,11 @@ */ package com.android.systemui.biometrics +import com.android.systemui.broadcast.BroadcastSender import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.phone.SystemUIDialogManager +import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager /** @@ -28,6 +30,7 @@ class UdfpsBpViewController( statusBarStateController: StatusBarStateController, panelExpansionStateManager: PanelExpansionStateManager, systemUIDialogManager: SystemUIDialogManager, + val broadcastSender: BroadcastSender, dumpManager: DumpManager ) : UdfpsAnimationViewController<UdfpsBpView>( view, @@ -37,4 +40,29 @@ class UdfpsBpViewController( dumpManager ) { override val tag = "UdfpsBpViewController" + private val bpPanelExpansionListener = PanelExpansionListener { event -> + // Notification shade can be expanded but not visible (fraction: 0.0), for example + // when a heads-up notification (HUN) is showing. + notificationShadeVisible = event.expanded && event.fraction > 0f + view.onExpansionChanged(event.fraction) + cancelAuth() + } + + fun cancelAuth() { + if (shouldPauseAuth()) { + broadcastSender.closeSystemDialogs() + } + } + + override fun onViewAttached() { + super.onViewAttached() + + panelExpansionStateManager.addExpansionListener(bpPanelExpansionListener) + } + + override fun onViewDetached() { + super.onViewDetached() + + panelExpansionStateManager.removeExpansionListener(bpPanelExpansionListener) + } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 471240e25005..f0af858c3a74 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -54,6 +54,7 @@ import com.android.internal.util.LatencyTracker; import com.android.keyguard.ActiveUnlockConfig; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.animation.ActivityLaunchAnimator; +import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.DozeReceiver; @@ -125,6 +126,7 @@ public class UdfpsController implements DozeReceiver { @NonNull private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; @NonNull private final LatencyTracker mLatencyTracker; + @NonNull private final BroadcastSender mBroadcastSender; @VisibleForTesting @NonNull final BiometricDisplayListener mOrientationListener; @NonNull private final ActivityLaunchAnimator mActivityLaunchAnimator; @@ -205,7 +207,7 @@ public class UdfpsController implements DozeReceiver { mUnlockedScreenOffAnimationController, mHalControlsIllumination, mHbmProvider, requestId, reason, callback, (view, event, fromUdfpsView) -> onTouch(requestId, event, - fromUdfpsView), mActivityLaunchAnimator))); + fromUdfpsView), mActivityLaunchAnimator, mBroadcastSender))); } @Override @@ -574,7 +576,8 @@ public class UdfpsController implements DozeReceiver { @NonNull SystemUIDialogManager dialogManager, @NonNull LatencyTracker latencyTracker, @NonNull ActivityLaunchAnimator activityLaunchAnimator, - @NonNull Optional<AlternateUdfpsTouchProvider> aternateTouchProvider) { + @NonNull Optional<AlternateUdfpsTouchProvider> aternateTouchProvider, + @NonNull BroadcastSender broadcastSender) { mContext = context; mExecution = execution; mVibrator = vibrator; @@ -604,6 +607,7 @@ public class UdfpsController implements DozeReceiver { mLatencyTracker = latencyTracker; mActivityLaunchAnimator = activityLaunchAnimator; mAlternateTouchProvider = aternateTouchProvider.orElse(null); + mBroadcastSender = broadcastSender; mOrientationListener = new BiometricDisplayListener( context, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt index 2d51c973b0b1..faa93a5a2ad3 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt @@ -41,6 +41,7 @@ import androidx.annotation.LayoutRes import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.R import com.android.systemui.animation.ActivityLaunchAnimator +import com.android.systemui.broadcast.BroadcastSender import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.LockscreenShadeTransitionController @@ -83,7 +84,8 @@ class UdfpsControllerOverlay( @ShowReason val requestReason: Int, private val controllerCallback: IUdfpsOverlayControllerCallback, private val onTouch: (View, MotionEvent, Boolean) -> Boolean, - private val activityLaunchAnimator: ActivityLaunchAnimator + private val activityLaunchAnimator: ActivityLaunchAnimator, + private val broadcastSender: BroadcastSender ) { /** The view, when [isShowing], or null. */ var overlayView: UdfpsView? = null @@ -102,8 +104,8 @@ class UdfpsControllerOverlay( fitInsetsTypes = 0 gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS - flags = - (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or WindowManager.LayoutParams.FLAG_SPLIT_TOUCH) + flags = (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS + or WindowManager.LayoutParams.FLAG_SPLIT_TOUCH) privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY // Avoid announcing window title. accessibilityTitle = " " @@ -221,6 +223,7 @@ class UdfpsControllerOverlay( statusBarStateController, panelExpansionStateManager, dialogManager, + broadcastSender, dumpManager ) } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java index 9139699af26a..f28fedb9155b 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java @@ -32,6 +32,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.asynclayoutinflater.view.AsyncLayoutInflater; @@ -44,6 +45,8 @@ import com.airbnb.lottie.LottieProperty; import com.airbnb.lottie.model.KeyPath; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * View corresponding with udfps_keyguard_view.xml @@ -52,7 +55,6 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { private UdfpsDrawable mFingerprintDrawable; // placeholder private LottieAnimationView mAodFp; private LottieAnimationView mLockScreenFp; - private int mStatusBarState; // used when highlighting fp icon: private int mTextColorPrimary; @@ -70,7 +72,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { private float mBurnInOffsetY; private float mBurnInProgress; private float mInterpolatedDarkAmount; - private boolean mAnimatingBetweenAodAndLockscreen; // As opposed to Unlocked => AOD + private int mAnimationType = ANIMATION_NONE; private boolean mFullyInflated; public UdfpsKeyguardView(Context context, @Nullable AttributeSet attrs) { @@ -117,8 +119,10 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { return; } - final float darkAmountForAnimation = mAnimatingBetweenAodAndLockscreen - ? mInterpolatedDarkAmount : 1f /* animating from unlocked to AOD */; + // if we're animating from screen off, we can immediately place the icon in the + // AoD-burn in location, else we need to translate the icon from LS => AoD. + final float darkAmountForAnimation = mAnimationType == ANIMATION_UNLOCKED_SCREEN_OFF + ? 1f : mInterpolatedDarkAmount; mBurnInOffsetX = MathUtils.lerp(0f, getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */) - mMaxBurnInOffsetX, darkAmountForAnimation); @@ -127,12 +131,12 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { - mMaxBurnInOffsetY, darkAmountForAnimation); mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), darkAmountForAnimation); - if (mAnimatingBetweenAodAndLockscreen && !mPauseAuth) { + if (mAnimationType == ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN && !mPauseAuth) { mLockScreenFp.setTranslationX(mBurnInOffsetX); mLockScreenFp.setTranslationY(mBurnInOffsetY); mBgProtection.setAlpha(1f - mInterpolatedDarkAmount); mLockScreenFp.setAlpha(1f - mInterpolatedDarkAmount); - } else if (mInterpolatedDarkAmount == 0f) { + } else if (darkAmountForAnimation == 0f) { mLockScreenFp.setTranslationX(0); mLockScreenFp.setTranslationY(0); mBgProtection.setAlpha(mAlpha / 255f); @@ -148,9 +152,15 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { mAodFp.setProgress(mBurnInProgress); mAodFp.setAlpha(mInterpolatedDarkAmount); - // done animating between AoD & LS - if (mInterpolatedDarkAmount == 1f || mInterpolatedDarkAmount == 0f) { - mAnimatingBetweenAodAndLockscreen = false; + // done animating + final boolean doneAnimatingBetweenAodAndLS = + mAnimationType == ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN + && (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f); + final boolean doneAnimatingUnlockedScreenOff = + mAnimationType == ANIMATION_UNLOCKED_SCREEN_OFF + && (mInterpolatedDarkAmount == 1f); + if (doneAnimatingBetweenAodAndLS || doneAnimatingUnlockedScreenOff) { + mAnimationType = ANIMATION_NONE; } } @@ -158,10 +168,6 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { mUdfpsRequested = request; } - void setStatusBarState(int statusBarState) { - mStatusBarState = statusBarState; - } - void updateColor() { if (!mFullyInflated) { return; @@ -219,8 +225,16 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { return mAlpha; } - void onDozeAmountChanged(float linear, float eased, boolean animatingBetweenAodAndLockscreen) { - mAnimatingBetweenAodAndLockscreen = animatingBetweenAodAndLockscreen; + static final int ANIMATION_NONE = 0; + static final int ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN = 1; + static final int ANIMATION_UNLOCKED_SCREEN_OFF = 2; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ANIMATION_NONE, ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN, ANIMATION_UNLOCKED_SCREEN_OFF}) + private @interface AnimationType {} + + void onDozeAmountChanged(float linear, float eased, @AnimationType int animationType) { + mAnimationType = animationType; mInterpolatedDarkAmount = eased; updateAlpha(); } @@ -262,7 +276,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView { pw.println(" mUnpausedAlpha=" + getUnpausedAlpha()); pw.println(" mUdfpsRequested=" + mUdfpsRequested); pw.println(" mInterpolatedDarkAmount=" + mInterpolatedDarkAmount); - pw.println(" mAnimatingBetweenAodAndLockscreen=" + mAnimatingBetweenAodAndLockscreen); + pw.println(" mAnimationType=" + mAnimationType); } private final AsyncLayoutInflater.OnInflateFinishedListener mLayoutInflaterFinishListener = diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java index 8b0f36fe1245..ec4cf2fd8bd4 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java @@ -121,7 +121,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud mView.onDozeAmountChanged( animation.getAnimatedFraction(), (float) animation.getAnimatedValue(), - /* animatingBetweenAodAndLockScreen */ false); + UdfpsKeyguardView.ANIMATION_UNLOCKED_SCREEN_OFF); } }); } @@ -394,7 +394,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud mUnlockedScreenOffDozeAnimator.start(); } else { mView.onDozeAmountChanged(linear, eased, - /* animatingBetweenAodAndLockScreen */ true); + UdfpsKeyguardView.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN); } mLastDozeAmount = linear; @@ -404,7 +404,6 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud @Override public void onStateChanged(int statusBarState) { mStatusBarState = statusBarState; - mView.setStatusBarState(statusBarState); updateAlpha(); updatePauseAuth(); } diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java index 6a9317f2b543..f526277a0a37 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java @@ -20,10 +20,14 @@ import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBO import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_ENTERED; import static com.android.systemui.clipboardoverlay.ClipboardOverlayEvent.CLIPBOARD_OVERLAY_UPDATED; +import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.os.SystemProperties; import android.provider.DeviceConfig; +import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.systemui.CoreStartable; import com.android.systemui.dagger.SysUISingleton; @@ -37,6 +41,13 @@ import javax.inject.Inject; @SysUISingleton public class ClipboardListener extends CoreStartable implements ClipboardManager.OnPrimaryClipChangedListener { + private static final String TAG = "ClipboardListener"; + + @VisibleForTesting + static final String SHELL_PACKAGE = "com.android.shell"; + @VisibleForTesting + static final String EXTRA_SUPPRESS_OVERLAY = + "com.android.systemui.SUPPRESS_CLIPBOARD_OVERLAY"; private final DeviceConfigProxy mDeviceConfig; private final ClipboardOverlayControllerFactory mOverlayFactory; @@ -68,18 +79,44 @@ public class ClipboardListener extends CoreStartable if (!mClipboardManager.hasPrimaryClip()) { return; } + String clipSource = mClipboardManager.getPrimaryClipSource(); + ClipData clipData = mClipboardManager.getPrimaryClip(); + + if (shouldSuppressOverlay(clipData, clipSource, isEmulator())) { + Log.i(TAG, "Clipboard overlay suppressed."); + return; + } + if (mClipboardOverlayController == null) { mClipboardOverlayController = mOverlayFactory.create(mContext); mUiEventLogger.log(CLIPBOARD_OVERLAY_ENTERED, 0, clipSource); } else { mUiEventLogger.log(CLIPBOARD_OVERLAY_UPDATED, 0, clipSource); } - mClipboardOverlayController.setClipData( - mClipboardManager.getPrimaryClip(), clipSource); + mClipboardOverlayController.setClipData(clipData, clipSource); mClipboardOverlayController.setOnSessionCompleteListener(() -> { // Session is complete, free memory until it's needed again. mClipboardOverlayController = null; }); } + + // The overlay is suppressed if EXTRA_SUPPRESS_OVERLAY is true and the device is an emulator or + // the source package is SHELL_PACKAGE. This is meant to suppress the overlay when the emulator + // or a mirrored device is syncing the clipboard. + @VisibleForTesting + static boolean shouldSuppressOverlay(ClipData clipData, String clipSource, + boolean isEmulator) { + if (!(isEmulator || SHELL_PACKAGE.equals(clipSource))) { + return false; + } + if (clipData == null || clipData.getDescription().getExtras() == null) { + return false; + } + return clipData.getDescription().getExtras().getBoolean(EXTRA_SUPPRESS_OVERLAY, false); + } + + private static boolean isEmulator() { + return SystemProperties.getBoolean("ro.boot.qemu", false); + } } diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java index ee8363fe50d4..50550567ac16 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java @@ -35,6 +35,7 @@ import android.animation.AnimatorSet; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.MainThread; +import android.app.ICompatCameraControlCallback; import android.app.RemoteAction; import android.content.BroadcastReceiver; import android.content.ClipData; @@ -44,7 +45,9 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Insets; import android.graphics.Rect; @@ -68,6 +71,7 @@ import android.view.InputMonitor; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; +import android.view.ViewRootImpl; import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.WindowManager; @@ -85,6 +89,7 @@ import android.widget.TextView; import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.PhoneWindow; +import com.android.settingslib.applications.InterestingConfigChanges; import com.android.systemui.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.broadcast.BroadcastSender; @@ -150,6 +155,10 @@ public class ClipboardOverlayController { private boolean mBlockAttach = false; private Animator mExitAnimator; + /** Tracks config changes that require updating insets */ + private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges( + ActivityInfo.CONFIG_KEYBOARD_HIDDEN); + public ClipboardOverlayController(Context context, BroadcastDispatcher broadcastDispatcher, BroadcastSender broadcastSender, @@ -232,6 +241,24 @@ public class ClipboardOverlayController { mWindow.setContentView(mView); updateInsets(mWindowManager.getCurrentWindowMetrics().getWindowInsets()); mView.requestLayout(); + mWindow.peekDecorView().getViewRootImpl().setActivityConfigCallback( + new ViewRootImpl.ActivityConfigCallback() { + @Override + public void onConfigurationChanged(Configuration overrideConfig, + int newDisplayId) { + if (mConfigChanges.applyNewConfig(mContext.getResources())) { + updateInsets( + mWindowManager.getCurrentWindowMetrics().getWindowInsets()); + } + } + + @Override + public void requestCompatCameraControl( + boolean showControl, boolean transformationApplied, + ICompatCameraControlCallback callback) { + Log.w(TAG, "unexpected requestCompatCameraControl call"); + } + }); }); mTimeoutHandler.setOnTimeoutRunnable(() -> { diff --git a/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt b/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt index d775ad39a5c3..3c0748e02552 100644 --- a/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt +++ b/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt @@ -16,11 +16,13 @@ package com.android.systemui.decor import android.annotation.IdRes +import android.annotation.NonNull import android.content.Context import android.view.Surface import android.view.View import android.view.ViewGroup import com.android.systemui.RegionInterceptingFrameLayout +import java.io.PrintWriter class OverlayWindow(private val context: Context) { @@ -100,4 +102,13 @@ class OverlayWindow(private val context: Context) { } } } + + fun dump(@NonNull pw: PrintWriter, name: String) { + pw.println(" $name=") + pw.println(" rootView=$rootView") + for (i in 0 until rootView.childCount) { + val child = rootView.getChildAt(i) + pw.println(" child[$i]=$child") + } + } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java index c1dff248818f..cd23f149cf7d 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java @@ -17,10 +17,14 @@ package com.android.systemui.dreams.dagger; import android.content.Context; +import android.content.res.Resources; import com.android.settingslib.dream.DreamBackend; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule; +import javax.inject.Named; + import dagger.Module; import dagger.Provides; @@ -34,6 +38,10 @@ import dagger.Provides; DreamOverlayComponent.class, }) public interface DreamModule { + String DREAM_ONLY_ENABLED_FOR_SYSTEM_USER = "dream_only_enabled_for_system_user"; + + String DREAM_SUPPORTED = "dream_supported"; + /** * Provides an instance of the dream backend. */ @@ -41,4 +49,19 @@ public interface DreamModule { static DreamBackend providesDreamBackend(Context context) { return DreamBackend.getInstance(context); } + + /** */ + @Provides + @Named(DREAM_ONLY_ENABLED_FOR_SYSTEM_USER) + static boolean providesDreamOnlyEnabledForSystemUser(@Main Resources resources) { + return resources.getBoolean( + com.android.internal.R.bool.config_dreamsOnlyEnabledForSystemUser); + } + + /** */ + @Provides + @Named(DREAM_SUPPORTED) + static boolean providesDreamSupported(@Main Resources resources) { + return resources.getBoolean(com.android.internal.R.bool.config_dreamsSupported); + } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java index c62c0bf06e3f..94418f498d3b 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java @@ -151,7 +151,7 @@ public class Flags { /***************************************/ // 900 - media public static final BooleanFlag MEDIA_TAP_TO_TRANSFER = new BooleanFlag(900, true); - public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, true); + public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, false); public static final BooleanFlag MEDIA_NEARBY_DEVICES = new BooleanFlag(903, true); public static final BooleanFlag MEDIA_MUTE_AWAIT = new BooleanFlag(904, true); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 14a7e3c7f013..404e5311961b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -857,6 +857,13 @@ class KeyguardUnlockAnimationController @Inject constructor( } /** + * Whether the RemoteAnimation on the app/launcher surface behind the keyguard is 'running'. + */ + fun isAnimatingBetweenKeyguardAndSurfaceBehind(): Boolean { + return keyguardViewMediator.get().isAnimatingBetweenKeyguardAndSurfaceBehind + } + + /** * Whether we are playing a canned unlock animation, vs. unlocking from a touch gesture such as * a swipe. */ diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 4d59f1a8e363..e379d766f0ca 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -2625,6 +2625,9 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, // The remote animation is over, so we're not going away anymore. mKeyguardStateController.notifyKeyguardGoingAway(false); + + // Dispatch the callback on animation finishes. + mUpdateMonitor.dispatchKeyguardDismissAnimationFinished(); }); mKeyguardUnlockAnimationControllerLazy.get().notifyFinishedKeyguardExitAnimation( diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt index e16da89d6ec8..25effec42f1a 100644 --- a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt +++ b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt @@ -89,7 +89,7 @@ class LogBuffer @JvmOverloads constructor( init { if (logcatEchoTracker.logInBackgroundThread && echoMessageQueue != null) { - thread(start = true, priority = Thread.NORM_PRIORITY) { + thread(start = true, name = "LogBuffer-$name", priority = Thread.NORM_PRIORITY) { try { while (true) { echoToDesiredEndpoints(echoMessageQueue.take()) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index 3483bc39b943..8002fb88c41a 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -845,7 +845,8 @@ class MediaCarouselController @Inject constructor( uid, interactedSubcardRank, interactedSubcardCardinality, - receivedLatencyMillis + receivedLatencyMillis, + null // Media cards cannot have subcards. ) /* ktlint-disable max-line-length */ if (DEBUG) { diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index d65940172b17..b9601420bb26 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -97,7 +97,7 @@ import kotlin.Unit; * A view controller used for Media Playback. */ public class MediaControlPanel { - private static final String TAG = "MediaControlPanel"; + protected static final String TAG = "MediaControlPanel"; private static final float DISABLED_ALPHA = 0.38f; private static final String EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME = "com.google" @@ -106,7 +106,7 @@ public class MediaControlPanel { "com.google.android.apps.gsa.smartspace.extra.SMARTSPACE_INTENT"; private static final String KEY_SMARTSPACE_ARTIST_NAME = "artist_name"; private static final String KEY_SMARTSPACE_OPEN_IN_FOREGROUND = "KEY_OPEN_IN_FOREGROUND"; - private static final String KEY_SMARTSPACE_APP_NAME = "KEY_SMARTSPACE_APP_NAME"; + protected static final String KEY_SMARTSPACE_APP_NAME = "KEY_SMARTSPACE_APP_NAME"; // Event types logged by smartspace private static final int SMARTSPACE_CARD_CLICK_EVENT = 760; @@ -149,6 +149,7 @@ public class MediaControlPanel { private RecommendationViewHolder mRecommendationViewHolder; private String mKey; private MediaData mMediaData; + private SmartspaceMediaData mRecommendationData; private MediaViewController mMediaViewController; private MediaSession.Token mToken; private MediaController mController; @@ -448,6 +449,7 @@ public class MediaControlPanel { bindOutputSwitcherChip(data); bindGutsMenuForPlayer(data); + bindPlayerContentDescription(data); bindScrubbingTime(data); bindActionButtons(data); @@ -541,12 +543,6 @@ public class MediaControlPanel { } private boolean bindSongMetadata(MediaData data) { - // Accessibility label - mMediaViewHolder.getPlayer().setContentDescription( - mContext.getString( - R.string.controls_media_playing_item_description, - data.getSong(), data.getArtist(), data.getApp())); - TextView titleText = mMediaViewHolder.getTitleText(); TextView artistText = mMediaViewHolder.getArtistText(); return mMetadataAnimationHandler.setNext( @@ -568,6 +564,48 @@ public class MediaControlPanel { }); } + // We may want to look into unifying this with bindRecommendationContentDescription if/when we + // do a refactor of this class. + private void bindPlayerContentDescription(MediaData data) { + if (mMediaViewHolder == null) { + return; + } + + CharSequence contentDescription; + if (mMediaViewController.isGutsVisible()) { + contentDescription = mMediaViewHolder.getGutsViewHolder().getGutsText().getText(); + } else if (data != null) { + contentDescription = mContext.getString( + R.string.controls_media_playing_item_description, + data.getSong(), + data.getArtist(), + data.getApp()); + } else { + contentDescription = null; + } + mMediaViewHolder.getPlayer().setContentDescription(contentDescription); + } + + private void bindRecommendationContentDescription(SmartspaceMediaData data) { + if (mRecommendationViewHolder == null) { + return; + } + + CharSequence contentDescription; + if (mMediaViewController.isGutsVisible()) { + contentDescription = + mRecommendationViewHolder.getGutsViewHolder().getGutsText().getText(); + } else if (data != null) { + contentDescription = mContext.getString( + R.string.controls_media_smartspace_rec_description, + data.getAppName(mContext)); + } else { + contentDescription = null; + } + + mRecommendationViewHolder.getRecommendations().setContentDescription(contentDescription); + } + private void bindArtworkAndColors(MediaData data, boolean updateBackground) { final int reqId = mArtworkNextBindRequestId++; if (updateBackground) { @@ -636,10 +674,6 @@ public class MediaControlPanel { mIsArtworkBound = isArtworkBound; } - // Scrim bounds are set manually so it scales as expected - albumView.getForeground().setBounds(0, 0, - Math.max(width, height), Math.max(width, height)); - // Transition Colors to current color scheme mColorSchemeTransition.updateColorScheme(colorScheme, mIsArtworkBound); @@ -954,6 +988,7 @@ public class MediaControlPanel { return; } + mRecommendationData = data; mSmartspaceId = SmallHash.hash(data.getTargetId()); mPackageName = data.getPackageName(); mInstanceId = data.getInstanceId(); @@ -969,6 +1004,12 @@ public class MediaControlPanel { return; } + CharSequence appName = data.getAppName(mContext); + if (appName == null) { + Log.w(TAG, "Fail to get media recommendation's app name"); + return; + } + PackageManager packageManager = mContext.getPackageManager(); // Set up media source app's logo. Drawable icon = packageManager.getApplicationIcon(applicationInfo); @@ -976,28 +1017,11 @@ public class MediaControlPanel { headerLogoImageView.setImageDrawable(icon); fetchAndUpdateRecommendationColors(icon); - // Set up media source app's label text. - CharSequence appName = getAppName(data.getCardAction()); - if (TextUtils.isEmpty(appName)) { - Intent launchIntent = - packageManager.getLaunchIntentForPackage(data.getPackageName()); - if (launchIntent != null) { - ActivityInfo launchActivity = launchIntent.resolveActivityInfo(packageManager, 0); - appName = launchActivity.loadLabel(packageManager); - } else { - Log.w(TAG, "Package " + data.getPackageName() - + " does not have a main launcher activity. Fallback to full app name"); - appName = packageManager.getApplicationLabel(applicationInfo); - } - } - // Set up media rec card's tap action if applicable. TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations(); setSmartspaceRecItemOnClickListener(recommendationCard, data.getCardAction(), /* interactedSubcardRank */ -1); - // Set up media rec card's accessibility label. - recommendationCard.setContentDescription( - mContext.getString(R.string.controls_media_smartspace_rec_description, appName)); + bindRecommendationContentDescription(data); List<ImageView> mediaCoverItems = mRecommendationViewHolder.getMediaCoverItems(); List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers(); @@ -1179,6 +1203,11 @@ public class MediaControlPanel { mRecommendationViewHolder.marquee(false, mMediaViewController.GUTS_ANIMATION_DURATION); } mMediaViewController.closeGuts(immediate); + if (mMediaViewHolder != null) { + bindPlayerContentDescription(mMediaData); + } else if (mRecommendationViewHolder != null) { + bindRecommendationContentDescription(mRecommendationData); + } } private void closeGuts() { @@ -1192,6 +1221,11 @@ public class MediaControlPanel { mRecommendationViewHolder.marquee(true, mMediaViewController.GUTS_ANIMATION_DURATION); } mMediaViewController.openGuts(); + if (mMediaViewHolder != null) { + bindPlayerContentDescription(mMediaData); + } else if (mRecommendationViewHolder != null) { + bindRecommendationContentDescription(mRecommendationData); + } mLogger.logLongPressOpen(mUid, mPackageName, mInstanceId); } @@ -1306,17 +1340,6 @@ public class MediaControlPanel { }); } - /** Returns the upstream app name if available. */ - @Nullable - private String getAppName(SmartspaceAction action) { - if (action == null || action.getIntent() == null - || action.getIntent().getExtras() == null) { - return null; - } - - return action.getIntent().getExtras().getString(KEY_SMARTSPACE_APP_NAME); - } - /** Returns if the Smartspace action will open the activity in foreground. */ private boolean shouldSmartspaceRecItemOpenInForeground(SmartspaceAction action) { if (action == null || action.getIntent() == null diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt index f85078c24603..11ee6578e27d 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt @@ -30,6 +30,7 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManager import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManagerFactory +import com.android.systemui.statusbar.policy.ConfigurationController import java.io.PrintWriter import java.util.concurrent.Executor import javax.inject.Inject @@ -44,6 +45,7 @@ class MediaDeviceManager @Inject constructor( private val localMediaManagerFactory: LocalMediaManagerFactory, private val mr2manager: MediaRouter2Manager, private val muteAwaitConnectionManagerFactory: MediaMuteAwaitConnectionManagerFactory, + private val configurationController: ConfigurationController, @Main private val fgExecutor: Executor, @Background private val bgExecutor: Executor, dumpManager: DumpManager @@ -79,7 +81,7 @@ class MediaDeviceManager @Inject constructor( oldEntry?.stop() } var entry = entries[key] - if (entry == null || entry?.token != data.token) { + if (entry == null || entry.token != data.token) { entry?.stop() if (data.device != null) { // If we were already provided device info (e.g. from RCN), keep that and don't @@ -118,10 +120,9 @@ class MediaDeviceManager @Inject constructor( override fun dump(pw: PrintWriter, args: Array<String>) { with(pw) { println("MediaDeviceManager state:") - entries.forEach { - key, entry -> + entries.forEach { (key, entry) -> println(" key=$key") - entry.dump(pw, args) + entry.dump(pw) } } } @@ -165,6 +166,12 @@ class MediaDeviceManager @Inject constructor( // expected to connect imminently, it should be displayed as the current device. private var aboutToConnectDeviceOverride: AboutToConnectDevice? = null + private val configListener = object : ConfigurationController.ConfigurationListener { + override fun onLocaleListChanged() { + updateCurrent() + } + } + @AnyThread fun start() = bgExecutor.execute { localMediaManager.registerCallback(this) @@ -174,6 +181,7 @@ class MediaDeviceManager @Inject constructor( controller?.registerCallback(this) updateCurrent() started = true + configurationController.addCallback(configListener) } @AnyThread @@ -183,9 +191,10 @@ class MediaDeviceManager @Inject constructor( localMediaManager.stopScan() localMediaManager.unregisterCallback(this) muteAwaitConnectionManager?.stopListening() + configurationController.removeCallback(configListener) } - fun dump(pw: PrintWriter, args: Array<String>) { + fun dump(pw: PrintWriter) { val routingSession = controller?.let { mr2manager.getRoutingSessionForMediaController(it) } diff --git a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java index 4f598ff797d0..40a5653a15a0 100644 --- a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java +++ b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java @@ -52,8 +52,10 @@ public class ResumeMediaBrowser { private final MediaBrowserFactory mBrowserFactory; private final ResumeMediaBrowserLogger mLogger; private final ComponentName mComponentName; + private final MediaController.Callback mMediaControllerCallback = new SessionDestroyCallback(); private MediaBrowser mMediaBrowser; + @Nullable private MediaController mMediaController; /** * Initialize a new media browser @@ -90,6 +92,7 @@ public class ResumeMediaBrowser { mComponentName, mConnectionCallback, rootHints); + updateMediaController(); mLogger.logConnection(mComponentName, "findRecentMedia"); mMediaBrowser.connect(); } @@ -154,7 +157,8 @@ public class ResumeMediaBrowser { @Override public void onConnected() { Log.d(TAG, "Service connected for " + mComponentName); - if (mMediaBrowser != null && mMediaBrowser.isConnected()) { + updateMediaController(); + if (isBrowserConnected()) { String root = mMediaBrowser.getRoot(); if (!TextUtils.isEmpty(root)) { if (mCallback != null) { @@ -207,6 +211,7 @@ public class ResumeMediaBrowser { mMediaBrowser.disconnect(); } mMediaBrowser = null; + updateMediaController(); } /** @@ -225,7 +230,8 @@ public class ResumeMediaBrowser { @Override public void onConnected() { Log.d(TAG, "Connected for restart " + mMediaBrowser.isConnected()); - if (mMediaBrowser == null || !mMediaBrowser.isConnected()) { + updateMediaController(); + if (!isBrowserConnected()) { if (mCallback != null) { mCallback.onError(); } @@ -259,6 +265,7 @@ public class ResumeMediaBrowser { disconnect(); } }, rootHints); + updateMediaController(); mLogger.logConnection(mComponentName, "restart"); mMediaBrowser.connect(); } @@ -273,7 +280,7 @@ public class ResumeMediaBrowser { * @return the token, or null if the MediaBrowser is null or disconnected */ public MediaSession.Token getToken() { - if (mMediaBrowser == null || !mMediaBrowser.isConnected()) { + if (!isBrowserConnected()) { return null; } return mMediaBrowser.getSessionToken(); @@ -305,10 +312,39 @@ public class ResumeMediaBrowser { mComponentName, mConnectionCallback, rootHints); + updateMediaController(); mLogger.logConnection(mComponentName, "testConnection"); mMediaBrowser.connect(); } + /** Updates mMediaController based on our current browser values. */ + private void updateMediaController() { + MediaSession.Token controllerToken = + mMediaController != null ? mMediaController.getSessionToken() : null; + MediaSession.Token currentToken = getToken(); + boolean areEqual = (controllerToken == null && currentToken == null) + || (controllerToken != null && controllerToken.equals(currentToken)); + if (areEqual) { + return; + } + + // Whenever the token changes, un-register the callback on the old controller (if we have + // one) and create a new controller with the callback attached. + if (mMediaController != null) { + mMediaController.unregisterCallback(mMediaControllerCallback); + } + if (currentToken != null) { + mMediaController = createMediaController(currentToken); + mMediaController.registerCallback(mMediaControllerCallback); + } else { + mMediaController = null; + } + } + + private boolean isBrowserConnected() { + return mMediaBrowser != null && mMediaBrowser.isConnected(); + } + /** * Interface to handle results from ResumeMediaBrowser */ @@ -335,4 +371,12 @@ public class ResumeMediaBrowser { ResumeMediaBrowser browser) { } } + + private class SessionDestroyCallback extends MediaController.Callback { + @Override + public void onSessionDestroyed() { + mLogger.logSessionDestroyed(isBrowserConnected(), mComponentName); + disconnect(); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt index ccc5edc1123a..41f735486c7e 100644 --- a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt @@ -48,6 +48,27 @@ class ResumeMediaBrowserLogger @Inject constructor( }, { "Disconnecting browser for component $str1" } ) + + /** + * Logs that we received a [android.media.session.MediaController.Callback.onSessionDestroyed] + * event. + * + * @param isBrowserConnected true if there's a currently connected + * [android.media.browse.MediaBrowser] and false otherwise. + * @param componentName the component name for the [ResumeMediaBrowser] that triggered this log. + */ + fun logSessionDestroyed( + isBrowserConnected: Boolean, + componentName: ComponentName + ) = buffer.log( + TAG, + LogLevel.DEBUG, + { + bool1 = isBrowserConnected + str1 = componentName.toShortString() + }, + { "Session destroyed. Active browser = $bool1. Browser component = $str1." } + ) } private const val TAG = "MediaBrowser" diff --git a/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt b/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt index 50a96f601443..c8f17d93bcc8 100644 --- a/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt +++ b/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt @@ -17,8 +17,13 @@ package com.android.systemui.media import android.app.smartspace.SmartspaceAction +import android.content.Context import android.content.Intent +import android.content.pm.PackageManager +import android.text.TextUtils +import android.util.Log import com.android.internal.logging.InstanceId +import com.android.systemui.media.MediaControlPanel.KEY_SMARTSPACE_APP_NAME /** State of a Smartspace media recommendations view. */ data class SmartspaceMediaData( @@ -67,6 +72,32 @@ data class SmartspaceMediaData( * Returns the list of [recommendations] that have valid data. */ fun getValidRecommendations() = recommendations.filter { it.icon != null } + + /** Returns the upstream app name if available. */ + fun getAppName(context: Context): CharSequence? { + val nameFromAction = cardAction?.intent?.extras?.getString(KEY_SMARTSPACE_APP_NAME) + if (!TextUtils.isEmpty(nameFromAction)) { + return nameFromAction + } + + val packageManager = context.packageManager + packageManager.getLaunchIntentForPackage(packageName)?.let { + val launchActivity = it.resolveActivityInfo(packageManager, 0) + return launchActivity.loadLabel(packageManager) + } + + Log.w( + TAG, + "Package $packageName does not have a main launcher activity. " + + "Fallback to full app name") + return try { + val applicationInfo = packageManager.getApplicationInfo(packageName, /* flags= */ 0) + packageManager.getApplicationLabel(applicationInfo) + } catch (e: PackageManager.NameNotFoundException) { + null + } + } } const val NUM_REQUIRED_RECOMMENDATIONS = 3 +private val TAG = SmartspaceMediaData::class.simpleName!! 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 a397f32dcbbf..ec472c655b43 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -143,6 +143,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { if (mController.isTransferring()) { if (device.getState() == MediaDeviceState.STATE_CONNECTING && !mController.hasAdjustVolumeUserRestriction()) { + setUpDeviceIcon(device); mProgressBar.getIndeterminateDrawable().setColorFilter( new PorterDuffColorFilter( mController.getColorItemContent(), @@ -151,11 +152,13 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { false /* showSeekBar*/, true /* showProgressBar */, false /* showStatus */); } else { + setUpDeviceIcon(device); setSingleLineLayout(getItemTitle(device), false /* bFocused */); } } else { // Set different layout for each device if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) { + setUpDeviceIcon(device); mTitleText.setAlpha(DEVICE_CONNECTED_ALPHA); mTitleIcon.setAlpha(DEVICE_CONNECTED_ALPHA); mStatusIcon.setImageDrawable( @@ -167,6 +170,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { mSubTitleText.setText(R.string.media_output_dialog_connect_failed); mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); } else if (device.getState() == MediaDeviceState.STATE_GROUPING) { + setUpDeviceIcon(device); mProgressBar.getIndeterminateDrawable().setColorFilter( new PorterDuffColorFilter( mController.getColorItemContent(), @@ -176,7 +180,12 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { true /* showProgressBar */, false /* showStatus */); } else if (mController.getSelectedMediaDevice().size() > 1 && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) { + boolean isDeviceDeselectable = isDeviceIncluded( + mController.getDeselectableMediaDevice(), device); mTitleText.setTextColor(mController.getColorItemContent()); + mTitleIcon.setImageDrawable( + mContext.getDrawable(R.drawable.media_output_icon_volume)); + mTitleIcon.setColorFilter(mController.getColorItemContent()); setSingleLineLayout(getItemTitle(device), true /* bFocused */, true /* showSeekBar */, false /* showProgressBar */, false /* showStatus */); @@ -184,28 +193,36 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { mCheckBox.setOnCheckedChangeListener(null); mCheckBox.setVisibility(View.VISIBLE); mCheckBox.setChecked(true); - mCheckBox.setOnCheckedChangeListener( - (buttonView, isChecked) -> onGroupActionTriggered(false, device)); + mCheckBox.setOnCheckedChangeListener(isDeviceDeselectable + ? (buttonView, isChecked) -> onGroupActionTriggered(false, device) + : null); + mCheckBox.setEnabled(isDeviceDeselectable); + mCheckBox.setAlpha( + isDeviceDeselectable ? DEVICE_CONNECTED_ALPHA + : DEVICE_DISCONNECTED_ALPHA + ); setCheckBoxColor(mCheckBox, mController.getColorItemContent()); initSeekbar(device, isCurrentSeekbarInvisible); mEndTouchArea.setVisibility(View.VISIBLE); mEndTouchArea.setOnClickListener(null); - mEndTouchArea.setOnClickListener((v) -> mCheckBox.performClick()); + mEndTouchArea.setOnClickListener( + isDeviceDeselectable ? (v) -> mCheckBox.performClick() : null); mEndTouchArea.setImportantForAccessibility( View.IMPORTANT_FOR_ACCESSIBILITY_YES); setUpContentDescriptionForView(mEndTouchArea, true, device); } else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) { - mStatusIcon.setImageDrawable( - mContext.getDrawable(R.drawable.media_output_status_check)); - mStatusIcon.setColorFilter(mController.getColorItemContent()); + 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 */, true /* showStatus */); + false /* showProgressBar */, false /* showStatus */); initSeekbar(device, isCurrentSeekbarInvisible); setUpContentDescriptionForView(mContainerLayout, false, device); mCurrentActivePosition = position; } else if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) { + setUpDeviceIcon(device); mCheckBox.setOnCheckedChangeListener(null); mCheckBox.setVisibility(View.VISIBLE); mCheckBox.setChecked(false); @@ -218,6 +235,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { false /* showSeekBar */, false /* showProgressBar */, false /* showStatus */); } else { + setUpDeviceIcon(device); setSingleLineLayout(getItemTitle(device), false /* bFocused */); mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); } 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 5c2cc0b6af35..b407e76f1b11 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -166,15 +166,6 @@ public abstract class MediaOutputBaseAdapter extends void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) { mDeviceId = device.getId(); - ThreadUtils.postOnBackgroundThread(() -> { - Icon icon = mController.getDeviceIconCompat(device).toIcon(mContext); - ThreadUtils.postOnMainThread(() -> { - if (!TextUtils.equals(mDeviceId, device.getId())) { - return; - } - mTitleIcon.setImageIcon(icon); - }); - }); } abstract void onBind(int customizedItem, boolean topMargin, boolean bottomMargin); @@ -414,5 +405,17 @@ public abstract class MediaOutputBaseAdapter extends mSeekBar.setEnabled(false); mSeekBar.setOnTouchListener((v, event) -> true); } + + protected void setUpDeviceIcon(MediaDevice device) { + ThreadUtils.postOnBackgroundThread(() -> { + Icon icon = mController.getDeviceIconCompat(device).toIcon(mContext); + ThreadUtils.postOnMainThread(() -> { + if (!TextUtils.equals(mDeviceId, device.getId())) { + return; + } + mTitleIcon.setImageIcon(icon); + }); + }); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java index 5bb6557c3fe7..7e2610f8b135 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java @@ -76,6 +76,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements private static final String PREF_NAME = "MediaOutputDialog"; private static final String PREF_IS_LE_BROADCAST_FIRST_LAUNCH = "PrefIsLeBroadcastFirstLaunch"; private static final boolean DEBUG = true; + private static final int HANDLE_BROADCAST_FAILED_DELAY = 3000; private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper()); private final RecyclerView.LayoutManager mLayoutManager; @@ -119,7 +120,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements Log.d(TAG, "onBroadcastStarted(), reason = " + reason + ", broadcastId = " + broadcastId); } - mMainThreadHandler.post(() -> startLeBroadcastDialog()); + mMainThreadHandler.post(() -> handleLeBroadcastStarted()); } @Override @@ -127,7 +128,8 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements if (DEBUG) { Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason); } - handleLeBroadcastStartFailed(); + mMainThreadHandler.postDelayed(() -> handleLeBroadcastStartFailed(), + HANDLE_BROADCAST_FAILED_DELAY); } @Override @@ -137,7 +139,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = " + broadcastId + ", metadata = " + metadata); } - mMainThreadHandler.post(() -> refresh()); + mMainThreadHandler.post(() -> handleLeBroadcastMetadataChanged()); } @Override @@ -146,7 +148,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements Log.d(TAG, "onBroadcastStopped(), reason = " + reason + ", broadcastId = " + broadcastId); } - mMainThreadHandler.post(() -> refresh()); + mMainThreadHandler.post(() -> handleLeBroadcastStopped()); } @Override @@ -154,7 +156,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements if (DEBUG) { Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason); } - mMainThreadHandler.post(() -> refresh()); + mMainThreadHandler.post(() -> handleLeBroadcastStopFailed()); } @Override @@ -163,7 +165,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements Log.d(TAG, "onBroadcastUpdated(), reason = " + reason + ", broadcastId = " + broadcastId); } - mMainThreadHandler.post(() -> refresh()); + mMainThreadHandler.post(() -> handleLeBroadcastUpdated()); } @Override @@ -172,7 +174,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements Log.d(TAG, "onBroadcastUpdateFailed(), reason = " + reason + ", broadcastId = " + broadcastId); } - mMainThreadHandler.post(() -> refresh()); + mMainThreadHandler.post(() -> handleLeBroadcastUpdateFailed()); } @Override @@ -384,10 +386,34 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements Bitmap.createScaledBitmap(bitmap, size, size, false)); } - protected void handleLeBroadcastStartFailed() { + public void handleLeBroadcastStarted() { + startLeBroadcastDialog(); + } + + public void handleLeBroadcastStartFailed() { mStopButton.setText(R.string.media_output_broadcast_start_failed); mStopButton.setEnabled(false); - mMainThreadHandler.postDelayed(() -> refresh(), 3000); + refresh(); + } + + public void handleLeBroadcastMetadataChanged() { + refresh(); + } + + public void handleLeBroadcastStopped() { + refresh(); + } + + public void handleLeBroadcastStopFailed() { + refresh(); + } + + public void handleLeBroadcastUpdated() { + refresh(); + } + + public void handleLeBroadcastUpdateFailed() { + refresh(); } protected void startLeBroadcast() { diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java index dd4f1d6c9015..8f065461c22d 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java @@ -61,6 +61,10 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog { private ImageView mBroadcastCodeEdit; private AlertDialog mAlertDialog; private TextView mBroadcastErrorMessage; + private int mRetryCount = 0; + private String mCurrentBroadcastName; + private String mCurrentBroadcastCode; + private boolean mIsStopbyUpdateBroadcastCode = false; static final int METADATA_BROADCAST_NAME = 0; static final int METADATA_BROADCAST_CODE = 1; @@ -144,8 +148,6 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog { //init UI component mBroadcastQrCodeView = getDialogView().requireViewById(R.id.qrcode_view); - //Set the QR code view - setQrCodeView(); mBroadcastNotify = getDialogView().requireViewById(R.id.broadcast_info); mBroadcastNotify.setOnClickListener(v -> { @@ -171,8 +173,16 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog { launchBroadcastUpdatedDialog(true, mBroadcastCode.getText().toString()); }); - mBroadcastName.setText(getBroadcastMetadataInfo(METADATA_BROADCAST_NAME)); - mBroadcastCode.setText(getBroadcastMetadataInfo(METADATA_BROADCAST_CODE)); + refreshUi(); + } + + private void refreshUi() { + setQrCodeView(); + + mCurrentBroadcastName = getBroadcastMetadataInfo(METADATA_BROADCAST_NAME); + mCurrentBroadcastCode = getBroadcastMetadataInfo(METADATA_BROADCAST_CODE); + mBroadcastName.setText(mCurrentBroadcastName); + mBroadcastCode.setText(mCurrentBroadcastCode); } private void inflateBroadcastInfoArea() { @@ -239,52 +249,99 @@ public class MediaOutputBroadcastDialog extends MediaOutputBaseDialog { } if (isBroadcastCode) { - handleBroadcastCodeUpdated(updatedString); + /* If the user wants to update the Broadcast Code, the Broadcast session should be + * stopped then used the new Broadcast code to start the Broadcast. + */ + mIsStopbyUpdateBroadcastCode = true; + mMediaOutputController.setBroadcastCode(updatedString); + if (!mMediaOutputController.stopBluetoothLeBroadcast()) { + handleLeBroadcastStopFailed(); + return; + } } else { - handleBroadcastNameUpdated(updatedString); + /* If the user wants to update the Broadcast Name, we don't need to stop the Broadcast + * session. Only use the new Broadcast name to update the broadcast session. + */ + mMediaOutputController.setBroadcastName(updatedString); + if (!mMediaOutputController.updateBluetoothLeBroadcast()) { + handleLeBroadcastUpdateFailed(); + } } } - private void handleBroadcastNameUpdated(String name) { - // TODO(b/230473995) Add the retry mechanism and error handling when update fails - String currentName = mMediaOutputController.getBroadcastName(); - int retryCount = MAX_BROADCAST_INFO_UPDATE; - mMediaOutputController.setBroadcastName(name); - if (!mMediaOutputController.updateBluetoothLeBroadcast()) { - mMediaOutputController.setBroadcastName(currentName); - handleLeUpdateBroadcastFailed(retryCount); + @Override + public void handleLeBroadcastStarted() { + mRetryCount = 0; + if (mAlertDialog != null) { + mAlertDialog.dismiss(); } + refreshUi(); } - private void handleBroadcastCodeUpdated(String newPassword) { - // TODO(b/230473995) Add the retry mechanism and error handling when update fails - String currentPassword = mMediaOutputController.getBroadcastCode(); - int retryCount = MAX_BROADCAST_INFO_UPDATE; - if (!mMediaOutputController.stopBluetoothLeBroadcast()) { - mMediaOutputController.setBroadcastCode(currentPassword); - handleLeUpdateBroadcastFailed(retryCount); - return; + @Override + public void handleLeBroadcastStartFailed() { + mMediaOutputController.setBroadcastCode(mCurrentBroadcastCode); + mRetryCount++; + + handleUpdateFailedUi(); + } + + @Override + public void handleLeBroadcastMetadataChanged() { + refreshUi(); + } + + @Override + public void handleLeBroadcastUpdated() { + mRetryCount = 0; + if (mAlertDialog != null) { + mAlertDialog.dismiss(); } + refreshUi(); + } - mMediaOutputController.setBroadcastCode(newPassword); - if (!mMediaOutputController.startBluetoothLeBroadcast()) { - mMediaOutputController.setBroadcastCode(currentPassword); - handleLeUpdateBroadcastFailed(retryCount); - return; + @Override + public void handleLeBroadcastUpdateFailed() { + //Change the value in shared preferences back to it original value + mMediaOutputController.setBroadcastName(mCurrentBroadcastName); + mRetryCount++; + + handleUpdateFailedUi(); + } + + @Override + public void handleLeBroadcastStopped() { + if (mIsStopbyUpdateBroadcastCode) { + mIsStopbyUpdateBroadcastCode = false; + mRetryCount = 0; + if (!mMediaOutputController.startBluetoothLeBroadcast()) { + handleLeBroadcastStartFailed(); + return; + } + } else { + dismiss(); } + } + + @Override + public void handleLeBroadcastStopFailed() { + //Change the value in shared preferences back to it original value + mMediaOutputController.setBroadcastCode(mCurrentBroadcastCode); + mRetryCount++; - mAlertDialog.dismiss(); + handleUpdateFailedUi(); } - private void handleLeUpdateBroadcastFailed(int retryCount) { + private void handleUpdateFailedUi() { final Button positiveBtn = mAlertDialog.getButton(AlertDialog.BUTTON_POSITIVE); mBroadcastErrorMessage.setVisibility(View.VISIBLE); - if (retryCount < MAX_BROADCAST_INFO_UPDATE) { + if (mRetryCount < MAX_BROADCAST_INFO_UPDATE) { if (positiveBtn != null) { positiveBtn.setEnabled(true); } mBroadcastErrorMessage.setText(R.string.media_output_broadcast_update_error); } else { + mRetryCount = 0; mBroadcastErrorMessage.setText(R.string.media_output_broadcast_last_update_error); } } diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md index 114589119cea..6379960b85e9 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md @@ -1,11 +1,43 @@ # Media Tap-To-Transfer +## Overview This package (and child packages) include code for the media tap-to-transfer feature, which allows users to easily transfer playing media between devices. -In media transfer, there are two devices: the *sender* and the *receiver*. The sender device will -start and stop media casts to the receiver device. On both devices, System UI will display a chip -informing the user about the media cast occurring. +In media transfer, there are two devices: the **sender** and the **receiver**. The sender device +will start and stop media casts to the receiver device. On both devices, System UI will display a +chip informing the user about the media cast occurring. -This package is structured so that the sender code is in the sender package, the receiver code is -in the receiver package, and code that's shared between them is in the common package. +**Important**: System UI is **not responsible** for performing the media transfer. System UI +**only** displays an informational chip; external clients are responsible for performing the media +transfer and informing System UI about the transfer status. + +## Information flow +External clients notify System UI about the transfer status by calling `@SystemApi`s in +`StatusBarManager`. For the sender device, use the `updateMediaTapToTransferSenderDisplay` API; for +the receiver, use the `updateMediaTapToTransferReceiverDisplay` API. The APIs eventually flow into +SystemUI's `CommandQueue`, which then notifies callbacks about the new state. +`MediaTttChipControllerSender` implements the sender callback, and `MediaTttChipControllerReceiver` +implements the receiver callback. These controllers will then show or hide the tap-to-transfer chip +(depending on what information was sent in the API). + +## Architecture +This package is structured so that the sender code is in the `sender` package, the receiver code is +in the `receiver` package, and code that's shared between them is in the `common` package. + +* The `ChipStateSender` and `ChipStateReceiver` classes are enums that describe all the possible + transfer states (transfer started, transfer succeeded, etc.) and include relevant parameters for + each state. +* The `ChipSenderInfo` and `ChipReceiverInfo` classes are simple data classes that contain all the + information needed to display a chip. They include the transfer state, information about the media + being transferred, etc. +* The `MediaTttChipControllerSender` and `MediaTttChipControllerReceiver` classes are responsible + for showing or hiding the chip and updating the chip view based on information from the + `ChipInfo`. `MediaTttChipControllerCommon` has all the common logic for adding and removing the + view to the window and also includes any display logic that can be shared between the sender and + receiver. The sender and receiver controller subclasses have the display logic that's specific to + just the sender or just the receiver. + +## Testing +If you want to test out the tap-to-transfer chip without using the `@SystemApi`s, you can use adb +commands instead. Refer to `MediaTttCommandLineHelper` for information about adb commands. diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 1012efe665e7..47b1bff29a10 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -56,6 +56,7 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARE import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG_WINDOW_STATE; import static com.android.systemui.statusbar.phone.CentralSurfaces.dumpBarTransitions; +import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay; import android.annotation.IdRes; import android.app.ActivityTaskManager; @@ -68,6 +69,7 @@ import android.content.IntentFilter; import android.content.res.Configuration; import android.graphics.Insets; import android.graphics.PixelFormat; +import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; @@ -115,6 +117,7 @@ import com.android.systemui.Gefingerpoken; import com.android.systemui.R; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.model.SysUiState; @@ -130,6 +133,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; import com.android.systemui.settings.UserContextProvider; +import com.android.systemui.shared.navigationbar.RegionSamplingHelper; import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.shared.rotation.RotationButton; import com.android.systemui.shared.rotation.RotationButtonController; @@ -159,6 +163,7 @@ import java.io.PrintWriter; import java.util.Locale; import java.util.Map; import java.util.Optional; +import java.util.concurrent.Executor; import java.util.function.Consumer; import javax.inject.Inject; @@ -212,6 +217,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements private final NotificationShadeDepthController mNotificationShadeDepthController; private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener; private final UserContextProvider mUserContextProvider; + private final RegionSamplingHelper mRegionSamplingHelper; + private final int mNavColorSampleMargin; private NavigationBarFrame mFrame; private @WindowVisibleState int mNavigationBarWindowState = WINDOW_STATE_SHOWING; @@ -273,6 +280,16 @@ public class NavigationBar extends ViewController<NavigationBarView> implements private boolean mShowOrientedHandleForImmersiveMode; private final DeadZone mDeadZone; private boolean mImeVisible; + private final Rect mSamplingBounds = new Rect(); + + /** + * When quickswitching between apps of different orientations, we draw a secondary home handle + * in the position of the first app's orientation. This rect represents the region of that + * home handle so we can apply the correct light/dark luma on that. + * @see {@link NavigationBar#mOrientationHandle} + */ + @android.annotation.Nullable + private Rect mOrientedHandleSamplingRegion; @com.android.internal.annotations.VisibleForTesting public enum NavBarActionEvent implements UiEventLogger.UiEventEnum { @@ -483,7 +500,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements return; } mHasBlurs = hasBlurs; - mView.setWindowHasBlurs(hasBlurs); + mRegionSamplingHelper.setWindowHasBlurs(hasBlurs); } }; @@ -512,6 +529,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements NotificationRemoteInputManager notificationRemoteInputManager, NotificationShadeDepthController notificationShadeDepthController, @Main Handler mainHandler, + @Main Executor mainExecutor, + @Background Executor bgExecutor, UiEventLogger uiEventLogger, NavBarHelper navBarHelper, LightBarController mainLightBarController, @@ -564,6 +583,9 @@ public class NavigationBar extends ViewController<NavigationBarView> implements mInputMethodManager = inputMethodManager; mUserContextProvider = userContextProvider; + mNavColorSampleMargin = getResources() + .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin); + mOnComputeInternalInsetsListener = info -> { // When the nav bar is in 2-button or 3-button mode, or when IME is visible in fully // gestural mode, the entire nav bar should be touchable. @@ -586,6 +608,29 @@ public class NavigationBar extends ViewController<NavigationBarView> implements false /* inScreen */, false /* useNearestRegion */)); }; + mRegionSamplingHelper = new RegionSamplingHelper(mView, + new RegionSamplingHelper.SamplingCallback() { + @Override + public void onRegionDarknessChanged(boolean isRegionDark) { + getBarTransitions().getLightTransitionsController().setIconsDark( + !isRegionDark, true /* animate */); + } + + @Override + public Rect getSampledRegion(View sampledView) { + if (mOrientedHandleSamplingRegion != null) { + return mOrientedHandleSamplingRegion; + } + + return calculateSamplingRect(); + } + + @Override + public boolean isSamplingEnabled() { + return isGesturalModeOnDefaultDisplay(getContext(), mNavBarMode); + } + }, mainExecutor, bgExecutor); + mView.setEdgeBackGestureHandler(mEdgeBackGestureHandler); mNavBarMode = mNavigationModeController.addListener(mModeChangedListener); } @@ -600,8 +645,9 @@ public class NavigationBar extends ViewController<NavigationBarView> implements // It should also has corresponding cleanup in onViewDetached. mView.setBarTransitions(mNavigationBarTransitions); mView.setTouchHandler(mTouchHandler); - mView.setNavBarMode(mNavBarMode); + setNavBarMode(mNavBarMode); mEdgeBackGestureHandler.setStateChangeCallback(mView::updateStates); + mNavigationBarTransitions.addListener(this::onBarTransition); mView.updateRotationButton(); mView.setVisibility( @@ -674,9 +720,9 @@ public class NavigationBar extends ViewController<NavigationBarView> implements getBarTransitions().getLightTransitionsController().restoreState(mSavedState); } setNavigationIconHints(mNavigationIconHints); - mView.setWindowVisible(isNavBarWindowVisible()); + setWindowVisible(isNavBarWindowVisible()); mView.setBehavior(mBehavior); - mView.setNavBarMode(mNavBarMode); + setNavBarMode(mNavBarMode); mView.setUpdateActiveTouchRegionsCallback( () -> mOverviewProxyService.onActiveNavBarRegionChanges( getButtonLocations( @@ -838,7 +884,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements mOrientationHandle.mapRectFromViewToScreenCoords(boundsOnScreen, true); Rect boundsRounded = new Rect(); boundsOnScreen.roundOut(boundsRounded); - mView.setOrientedHandleSamplingRegion(boundsRounded); + setOrientedHandleSamplingRegion(boundsRounded); }; mOrientationHandle.getViewTreeObserver().addOnGlobalLayoutListener( mOrientationHandleGlobalLayoutListener); @@ -899,7 +945,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements mOrientationHandle.setVisibility(View.GONE); } mView.setVisibility(View.VISIBLE); - mView.setOrientedHandleSamplingRegion(null); + setOrientedHandleSamplingRegion(null); } private void reconfigureHomeLongClick() { @@ -937,7 +983,10 @@ public class NavigationBar extends ViewController<NavigationBarView> implements pw.println(" mTransientShownFromGestureOnSystemBar=" + mTransientShownFromGestureOnSystemBar); dumpBarTransitions(pw, "mNavigationBarView", getBarTransitions()); + + pw.println(" mOrientedHandleSamplingRegion: " + mOrientedHandleSamplingRegion); mView.dump(pw); + mRegionSamplingHelper.dump(pw); } // ----- CommandQueue Callbacks ----- @@ -973,7 +1022,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements orientSecondaryHomeHandle(); } if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state)); - mView.setWindowVisible(isNavBarWindowVisible()); + setWindowVisible(isNavBarWindowVisible()); } } @@ -1474,6 +1523,11 @@ public class NavigationBar extends ViewController<NavigationBarView> implements } } + private void setWindowVisible(boolean visible) { + mRegionSamplingHelper.setWindowVisible(visible); + mView.setWindowVisible(visible); + } + /** Sets {@link AutoHideController} to the navigation bar. */ private void setAutoHideController(AutoHideController autoHideController) { mAutoHideController = autoHideController; @@ -1641,7 +1695,15 @@ public class NavigationBar extends ViewController<NavigationBarView> implements if (Intent.ACTION_SCREEN_OFF.equals(action) || Intent.ACTION_SCREEN_ON.equals(action)) { notifyNavigationBarScreenOn(); - mView.onScreenStateChanged(Intent.ACTION_SCREEN_ON.equals(action)); + boolean isScreenOn = Intent.ACTION_SCREEN_ON.equals(action); + mView.onScreenStateChanged(isScreenOn); + if (isScreenOn) { + if (isGesturalModeOnDefaultDisplay(getContext(), mNavBarMode)) { + mRegionSamplingHelper.start(mSamplingBounds); + } + } else { + mRegionSamplingHelper.stop(); + } } if (Intent.ACTION_USER_SWITCHED.equals(action)) { // The accessibility settings may be different for the new user @@ -1750,6 +1812,60 @@ public class NavigationBar extends ViewController<NavigationBarView> implements region.op(bounds, Region.Op.UNION); } + void setOrientedHandleSamplingRegion(Rect orientedHandleSamplingRegion) { + mOrientedHandleSamplingRegion = orientedHandleSamplingRegion; + mRegionSamplingHelper.updateSamplingRect(); + } + + private Rect calculateSamplingRect() { + mSamplingBounds.setEmpty(); + // TODO: Extend this to 2/3 button layout as well + View view = mView.getHomeHandle().getCurrentView(); + + if (view != null) { + int[] pos = new int[2]; + view.getLocationOnScreen(pos); + Point displaySize = new Point(); + view.getContext().getDisplay().getRealSize(displaySize); + final Rect samplingBounds = new Rect(pos[0] - mNavColorSampleMargin, + displaySize.y - mView.getNavBarHeight(), + pos[0] + view.getWidth() + mNavColorSampleMargin, + displaySize.y); + mSamplingBounds.set(samplingBounds); + } + + return mSamplingBounds; + } + + void setNavigationBarLumaSamplingEnabled(boolean enable) { + if (enable) { + mRegionSamplingHelper.start(mSamplingBounds); + } else { + mRegionSamplingHelper.stop(); + } + } + + private void setNavBarMode(int mode) { + mView.setNavBarMode(mode, mNavigationModeController.getImeDrawsImeNavBar()); + if (isGesturalMode(mode)) { + mRegionSamplingHelper.start(mSamplingBounds); + } else { + mRegionSamplingHelper.stop(); + } + } + + void onBarTransition(int newMode) { + if (newMode == MODE_OPAQUE) { + // If the nav bar background is opaque, stop auto tinting since we know the icons are + // showing over a dark background + mRegionSamplingHelper.stop(); + getBarTransitions().getLightTransitionsController().setIconsDark( + false /* dark */, true /* animate */); + } else { + mRegionSamplingHelper.start(mSamplingBounds); + } + } + private final ModeChangedListener mModeChangedListener = new ModeChangedListener() { @Override public void onNavigationModeChanged(int mode) { @@ -1766,10 +1882,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements if (!canShowSecondaryHandle()) { resetSecondaryHandle(); } - if (mView != null) { - mView.setNavBarMode(mode); - mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI()); - } + setNavBarMode(mode); + mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI()); } }; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index 15182c1100ec..d756af77d2a9 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -244,9 +244,9 @@ public class NavigationBarController implements @Override public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) { - final NavigationBarView navigationBarView = getNavigationBarView(displayId); - if (navigationBarView != null) { - navigationBarView.setNavigationBarLumaSamplingEnabled(enable); + final NavigationBar navigationBar = getNavigationBar(displayId); + if (navigationBar != null) { + navigationBar.setNavigationBarLumaSamplingEnabled(enable); } } @@ -404,10 +404,14 @@ public class NavigationBarController implements * {@code null} if no navigation bar on that display. */ public @Nullable NavigationBarView getNavigationBarView(int displayId) { - NavigationBar navBar = mNavigationBars.get(displayId); + NavigationBar navBar = getNavigationBar(displayId); return (navBar == null) ? null : navBar.getView(); } + private @Nullable NavigationBar getNavigationBar(int displayId) { + return mNavigationBars.get(displayId); + } + public void showPinningEnterExitToast(int displayId, boolean entering) { final NavigationBarView navBarView = getNavigationBarView(displayId); if (navBarView != null) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java index 4d9175b8db68..59bb2278edfe 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java @@ -168,6 +168,7 @@ public class NavigationBarInflaterView extends FrameLayout public void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDispatchers) { mButtonDispatchers = buttonDispatchers; + clearDispatcherViews(); for (int i = 0; i < buttonDispatchers.size(); i++) { initiallyFill(buttonDispatchers.valueAt(i)); } @@ -454,12 +455,16 @@ public class NavigationBarInflaterView extends FrameLayout } } - private void clearViews() { + private void clearDispatcherViews() { if (mButtonDispatchers != null) { for (int i = 0; i < mButtonDispatchers.size(); i++) { mButtonDispatchers.valueAt(i).clear(); } } + } + + private void clearViews() { + clearDispatcherViews(); clearAllChildren(mHorizontal.findViewById(R.id.nav_buttons)); clearAllChildren(mVertical.findViewById(R.id.nav_buttons)); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java index 11a4b3bd9274..6793f0163c43 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java @@ -48,6 +48,7 @@ public final class NavigationBarTransitions extends BarTransitions implements public static final int MIN_COLOR_ADAPT_TRANSITION_TIME = 400; public static final int DEFAULT_COLOR_ADAPT_TRANSITION_TIME = 1700; + private List<Listener> mListeners = new ArrayList<>(); /** * Notified when the color of nav bar elements changes. @@ -162,7 +163,9 @@ public final class NavigationBarTransitions extends BarTransitions implements protected void onTransition(int oldMode, int newMode, boolean animate) { super.onTransition(oldMode, newMode, animate); applyLightsOut(animate, false /*force*/); - mView.onBarTransition(newMode); + for (Listener listener : mListeners) { + listener.onTransition(newMode); + } } private void applyLightsOut(boolean animate, boolean force) { @@ -255,4 +258,16 @@ public final class NavigationBarTransitions extends BarTransitions implements pw.println(" bg color: " + mBarBackground.getColor()); pw.println(" bg frame: " + mBarBackground.getFrame()); } + + void addListener(Listener listener) { + mListeners.add(listener); + } + + void removeListener(Listener listener) { + mListeners.remove(listener); + } + + interface Listener { + void onTransition(int newMode); + } } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index a13c199df41e..3fc9afe6ea94 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -24,8 +24,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_O import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SEARCH_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode; -import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE; -import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay; import android.animation.LayoutTransition; import android.animation.LayoutTransition.TransitionListener; @@ -34,7 +32,6 @@ import android.animation.PropertyValuesHolder; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.DrawableRes; -import android.annotation.Nullable; import android.app.StatusBarManager; import android.content.Context; import android.content.res.Configuration; @@ -58,9 +55,10 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.widget.FrameLayout; +import androidx.annotation.Nullable; + import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.Utils; -import com.android.systemui.Dependency; import com.android.systemui.Gefingerpoken; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; @@ -74,7 +72,6 @@ import com.android.systemui.navigationbar.buttons.NearestTouchFrame; import com.android.systemui.navigationbar.buttons.RotationContextButton; import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.recents.Recents; -import com.android.systemui.shared.navigationbar.RegionSamplingHelper; import com.android.systemui.shared.rotation.FloatingRotationButton; import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback; import com.android.systemui.shared.rotation.RotationButtonController; @@ -91,7 +88,6 @@ import com.android.wm.shell.pip.Pip; import java.io.PrintWriter; import java.util.Map; import java.util.Optional; -import java.util.concurrent.Executor; import java.util.function.Consumer; /** */ @@ -100,8 +96,6 @@ public class NavigationBarView extends FrameLayout { final static String TAG = "NavBarView"; final static boolean ALTERNATE_CAR_MODE_UI = false; - private final RegionSamplingHelper mRegionSamplingHelper; - private final int mNavColorSampleMargin; // The current view is one of mHorizontal or mVertical depending on the current configuration View mCurrentView = null; @@ -161,15 +155,6 @@ public class NavigationBarView extends FrameLayout { * fully locked mode we only show that unlocking is blocked. */ private ScreenPinningNotify mScreenPinningNotify; - private Rect mSamplingBounds = new Rect(); - /** - * When quickswitching between apps of different orientations, we draw a secondary home handle - * in the position of the first app's orientation. This rect represents the region of that - * home handle so we can apply the correct light/dark luma on that. - * @see {@link NavigationBar#mOrientationHandle} - */ - @Nullable - private Rect mOrientedHandleSamplingRegion; /** * {@code true} if the IME can render the back button and the IME switcher button. @@ -289,7 +274,6 @@ public class NavigationBarView extends FrameLayout { mDarkIconColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor); mIsVertical = false; mLongClickableAccessibilityButton = false; - mImeDrawsImeNavBar = Dependency.get(NavigationModeController.class).getImeDrawsImeNavBar(); // Set up the context group of buttons mContextualButtonGroup = new ContextualButtonGroup(R.id.menu_container); @@ -317,7 +301,7 @@ public class NavigationBarView extends FrameLayout { R.drawable.ic_sysbar_rotate_button_ccw_start_90, R.drawable.ic_sysbar_rotate_button_cw_start_0, R.drawable.ic_sysbar_rotate_button_cw_start_90, - () -> getDisplay().getRotation()); + () -> mCurrentRotation); mConfiguration = new Configuration(); mTmpLastConfiguration = new Configuration(); @@ -333,33 +317,6 @@ public class NavigationBarView extends FrameLayout { mButtonDispatchers.put(R.id.accessibility_button, accessibilityButton); mButtonDispatchers.put(R.id.menu_container, mContextualButtonGroup); mDeadZone = new DeadZone(this); - - mNavColorSampleMargin = getResources() - .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin); - Executor backgroundExecutor = Dependency.get(Dependency.BACKGROUND_EXECUTOR); - mRegionSamplingHelper = new RegionSamplingHelper(this, - new RegionSamplingHelper.SamplingCallback() { - @Override - public void onRegionDarknessChanged(boolean isRegionDark) { - getLightTransitionsController().setIconsDark(!isRegionDark , - true /* animate */); - } - - @Override - public Rect getSampledRegion(View sampledView) { - if (mOrientedHandleSamplingRegion != null) { - return mOrientedHandleSamplingRegion; - } - - updateSamplingRect(); - return mSamplingBounds; - } - - @Override - public boolean isSamplingEnabled() { - return isGesturalModeOnDefaultDisplay(getContext(), mNavBarMode); - } - }, backgroundExecutor); } public void setEdgeBackGestureHandler(EdgeBackGestureHandler edgeBackGestureHandler) { @@ -407,28 +364,6 @@ public class NavigationBarView extends FrameLayout { return super.onTouchEvent(event); } - /** - * If we're blurring the shade window. - */ - public void setWindowHasBlurs(boolean hasBlurs) { - mRegionSamplingHelper.setWindowHasBlurs(hasBlurs); - } - - void onTransientStateChanged(boolean isTransient, boolean isGestureOnSystemBar) { - mEdgeBackGestureHandler.onNavBarTransientStateChanged(isTransient); - } - - void onBarTransition(int newMode) { - if (newMode == MODE_OPAQUE) { - // If the nav bar background is opaque, stop auto tinting since we know the icons are - // showing over a dark background - mRegionSamplingHelper.stop(); - getLightTransitionsController().setIconsDark(false /* dark */, true /* animate */); - } else { - mRegionSamplingHelper.start(mSamplingBounds); - } - } - public void abortCurrentGesture() { getHomeButton().abortCurrentGesture(); } @@ -538,6 +473,7 @@ public class NavigationBarView extends FrameLayout { mRotationButtonController.setRotationButton(mRotationContextButton, mRotationButtonListener); } + mNavigationInflaterView.setButtonDispatchers(mButtonDispatchers); } public KeyButtonDrawable getBackDrawable() { @@ -603,17 +539,9 @@ public class NavigationBarView extends FrameLayout { /** To be called when screen lock/unlock state changes */ public void onScreenStateChanged(boolean isScreenOn) { mScreenOn = isScreenOn; - if (isScreenOn) { - if (isGesturalModeOnDefaultDisplay(getContext(), mNavBarMode)) { - mRegionSamplingHelper.start(mSamplingBounds); - } - } else { - mRegionSamplingHelper.stop(); - } } public void setWindowVisible(boolean visible) { - mRegionSamplingHelper.setWindowVisible(visible); mRotationButtonController.onNavigationBarWindowVisibilityChange(visible); } @@ -879,18 +807,12 @@ public class NavigationBarView extends FrameLayout { wm.updateViewLayout(navbarView, lp); } - void setNavBarMode(int mode) { + void setNavBarMode(int mode, boolean imeDrawsImeNavBar) { mNavBarMode = mode; - mImeDrawsImeNavBar = Dependency.get(NavigationModeController.class).getImeDrawsImeNavBar(); + mImeDrawsImeNavBar = imeDrawsImeNavBar; mBarTransitions.onNavigationModeChanged(mNavBarMode); mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode); updateRotationButton(); - - if (isGesturalMode(mNavBarMode)) { - mRegionSamplingHelper.start(mSamplingBounds); - } else { - mRegionSamplingHelper.stop(); - } } public void setAccessibilityButtonState(final boolean visible, final boolean longClickable) { @@ -915,29 +837,6 @@ public class NavigationBarView extends FrameLayout { super.onDraw(canvas); } - private void updateSamplingRect() { - mSamplingBounds.setEmpty(); - // TODO: Extend this to 2/3 button layout as well - View view = getHomeHandle().getCurrentView(); - - if (view != null) { - int[] pos = new int[2]; - view.getLocationOnScreen(pos); - Point displaySize = new Point(); - view.getContext().getDisplay().getRealSize(displaySize); - final Rect samplingBounds = new Rect(pos[0] - mNavColorSampleMargin, - displaySize.y - getNavBarHeight(), - pos[0] + view.getWidth() + mNavColorSampleMargin, - displaySize.y); - mSamplingBounds.set(samplingBounds); - } - } - - void setOrientedHandleSamplingRegion(Rect orientedHandleSamplingRegion) { - mOrientedHandleSamplingRegion = orientedHandleSamplingRegion; - mRegionSamplingHelper.updateSamplingRect(); - } - @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); @@ -978,15 +877,27 @@ public class NavigationBarView extends FrameLayout { return mCurrentRotation != rotation; } + private void updateCurrentRotation() { + final int rotation = mConfiguration.windowConfiguration.getDisplayRotation(); + if (mCurrentRotation == rotation) { + return; + } + mCurrentRotation = rotation; + mNavigationInflaterView.setAlternativeOrder(mCurrentRotation == Surface.ROTATION_90); + mDeadZone.onConfigurationChanged(mCurrentRotation); + if (DEBUG) { + Log.d(TAG, "updateCurrentRotation(): rot=" + mCurrentRotation); + } + } + private void updateCurrentView() { resetViews(); mCurrentView = mIsVertical ? mVertical : mHorizontal; mCurrentView.setVisibility(View.VISIBLE); mNavigationInflaterView.setVertical(mIsVertical); - mCurrentRotation = getContextDisplay().getRotation(); - mNavigationInflaterView.setAlternativeOrder(mCurrentRotation == Surface.ROTATION_90); mNavigationInflaterView.updateButtonDispatchersCurrentView(); updateLayoutTransitionsEnabled(); + updateCurrentRotation(); } private void resetViews() { @@ -1019,17 +930,11 @@ public class NavigationBarView extends FrameLayout { public void reorient() { updateCurrentView(); - ((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone); - mDeadZone.onConfigurationChanged(mCurrentRotation); // force the low profile & disabled states into compliance mBarTransitions.init(); - if (DEBUG) { - Log.d(TAG, "reorient(): rot=" + mCurrentRotation); - } - // Resolve layout direction if not resolved since components changing layout direction such // as changing languages will recreate this view and the direction will be resolved later if (!isLayoutDirectionResolved()) { @@ -1076,7 +981,7 @@ public class NavigationBarView extends FrameLayout { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } - private int getNavBarHeight() { + int getNavBarHeight() { return mIsVertical ? getResources().getDimensionPixelSize( com.android.internal.R.dimen.navigation_bar_height_landscape) @@ -1100,6 +1005,7 @@ public class NavigationBarView extends FrameLayout { boolean uiCarModeChanged = updateCarMode(); updateIcons(mTmpLastConfiguration); updateRecentsIcon(); + updateCurrentRotation(); mEdgeBackGestureHandler.onConfigurationChanged(mConfiguration); if (uiCarModeChanged || mTmpLastConfiguration.densityDpi != mConfiguration.densityDpi || mTmpLastConfiguration.getLayoutDirection() != mConfiguration.getLayoutDirection()) { @@ -1184,7 +1090,7 @@ public class NavigationBarView extends FrameLayout { mEdgeBackGestureHandler.onNavBarDetached(); } - public void dump(PrintWriter pw) { + void dump(PrintWriter pw) { final Rect r = new Rect(); final Point size = new Point(); getContextDisplay().getRealSize(size); @@ -1211,7 +1117,6 @@ public class NavigationBarView extends FrameLayout { mIsVertical ? "true" : "false", getLightTransitionsController().getCurrentDarkIntensity())); - pw.println(" mOrientedHandleSamplingRegion: " + mOrientedHandleSamplingRegion); pw.println(" mScreenOn: " + mScreenOn); @@ -1228,7 +1133,6 @@ public class NavigationBarView extends FrameLayout { } mBarTransitions.dump(pw); mContextualButtonGroup.dump(pw); - mRegionSamplingHelper.dump(pw); mEdgeBackGestureHandler.dump(pw); } @@ -1289,13 +1193,6 @@ public class NavigationBarView extends FrameLayout { mEdgeBackGestureHandler.setPipStashExclusionBounds(bounds); }); - void setNavigationBarLumaSamplingEnabled(boolean enable) { - if (enable) { - mRegionSamplingHelper.start(mSamplingBounds); - } else { - mRegionSamplingHelper.stop(); - } - } interface UpdateActiveTouchRegionsCallback { void update(); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java index 001a4628916f..ea41fe74f798 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java @@ -105,8 +105,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker private static final int MAX_NUM_LOGGED_PREDICTIONS = 10; private static final int MAX_NUM_LOGGED_GESTURES = 10; - // Temporary log until b/202433017 is resolved - static final boolean DEBUG_MISSING_GESTURE = true; + static final boolean DEBUG_MISSING_GESTURE = false; static final String DEBUG_MISSING_GESTURE_TAG = "NoBackGesture"; private ISystemGestureExclusionListener mGestureExclusionListener = diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java index e5dc0ec54676..a74c59618c95 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java @@ -363,6 +363,7 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl initializeBackAnimation(); setVisibility(GONE); + Executor backgroundExecutor = Dependency.get(Dependency.BACKGROUND_EXECUTOR); boolean isPrimaryDisplay = mContext.getDisplayId() == DEFAULT_DISPLAY; mRegionSamplingHelper = new RegionSamplingHelper(this, diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt index dbdb9d268aab..cd6eb99e259e 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -58,7 +58,8 @@ class PrivacyItemController @Inject constructor( internal companion object { val OPS_MIC_CAMERA = intArrayOf(AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO, - AppOpsManager.OP_PHONE_CALL_MICROPHONE) + AppOpsManager.OP_PHONE_CALL_MICROPHONE, + AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO) val OPS_LOCATION = intArrayOf( AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION) @@ -315,6 +316,7 @@ class PrivacyItemController @Inject constructor( AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION AppOpsManager.OP_PHONE_CALL_MICROPHONE, + AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE else -> return null } diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java b/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java index 8000bdccfa68..2c20feb19342 100644 --- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java +++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java @@ -29,7 +29,6 @@ import android.provider.Settings; import android.util.Log; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; -import com.android.systemui.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.settings.UserTracker; @@ -119,7 +118,6 @@ public class QRCodeScannerController implements mSecureSettings = secureSettings; mDeviceConfigProxy = proxy; mUserTracker = userTracker; - mConfigEnableLockScreenButton = mContext.getResources().getBoolean( android.R.bool.config_enableQrCodeScannerOnLockScreen); } @@ -258,16 +256,20 @@ public class QRCodeScannerController implements } } + private String getDefaultScannerActivity() { + return mContext.getResources().getString( + com.android.internal.R.string.config_defaultQrCodeComponent); + } + private void updateQRCodeScannerActivityDetails() { String qrCodeScannerActivity = mDeviceConfigProxy.getString( DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.DEFAULT_QR_CODE_SCANNER, ""); // "" means either the flags is not available or is set to "", and in both the cases we - // want to use R.string.def_qr_code_component + // want to use R.string.config_defaultQrCodeComponent if (Objects.equals(qrCodeScannerActivity, "")) { - qrCodeScannerActivity = - mContext.getResources().getString(R.string.def_qr_code_component); + qrCodeScannerActivity = getDefaultScannerActivity(); } String prevQrCodeScannerActivity = mQRCodeScannerActivity; diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java index 311ee56477de..3d00dd49cb1c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java @@ -47,7 +47,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout { private int mMaxColumns = NO_MAX_COLUMNS; protected int mResourceColumns; private float mSquishinessFraction = 1f; - private int mLastTileBottom; + protected int mLastTileBottom; public TileLayout(Context context) { this(context, null); @@ -243,12 +243,11 @@ public class TileLayout extends ViewGroup implements QSTileLayout { record.tileView.setLeftTopRightBottom(left, top, right, bottom); } record.tileView.setPosition(i); - if (forLayout) { - mLastTileBottom = record.tileView.getBottom(); - } else { - float scale = QSTileViewImplKt.constrainSquishiness(mSquishinessFraction); - mLastTileBottom = top + (int) (record.tileView.getMeasuredHeight() * scale); - } + + // Set the bottom to the unoverriden squished bottom. This is to avoid fake bottoms that + // are only used for QQS -> QS expansion animations + float scale = QSTileViewImplKt.constrainSquishiness(mSquishinessFraction); + mLastTileBottom = top + (int) (record.tileView.getMeasuredHeight() * scale); } } @@ -258,7 +257,8 @@ public class TileLayout extends ViewGroup implements QSTileLayout { } protected int getRowTop(int row) { - return (int) (row * (mCellHeight * mSquishinessFraction + mCellMarginVertical)); + float scale = QSTileViewImplKt.constrainSquishiness(mSquishinessFraction); + return (int) (row * (mCellHeight * scale + mCellMarginVertical)); } protected int getColumnStart(int column) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java index f24773a5da1d..22e725b41a64 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java @@ -42,6 +42,7 @@ import com.android.systemui.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.dreams.dagger.DreamModule; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.QSTile; @@ -50,19 +51,24 @@ import com.android.systemui.qs.QSHost; import com.android.systemui.qs.SettingObserver; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.android.systemui.settings.UserTracker; import com.android.systemui.util.settings.SecureSettings; import javax.inject.Inject; +import javax.inject.Named; /** Quick settings tile: Screensaver (dream) **/ public class DreamTile extends QSTileImpl<QSTile.BooleanState> { private static final String LOG_TAG = "QSDream"; + private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_screen_saver); private final IDreamManager mDreamManager; - private final SecureSettings mSecureSettings; private final BroadcastDispatcher mBroadcastDispatcher; private final SettingObserver mEnabledSettingObserver; private final SettingObserver mDreamSettingObserver; + private final UserTracker mUserTracker; + private final boolean mDreamSupported; + private final boolean mDreamOnlyEnabledForSystemUser; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -83,12 +89,15 @@ public class DreamTile extends QSTileImpl<QSTile.BooleanState> { QSLogger qsLogger, IDreamManager dreamManager, SecureSettings secureSettings, - BroadcastDispatcher broadcastDispatcher + BroadcastDispatcher broadcastDispatcher, + UserTracker userTracker, + @Named(DreamModule.DREAM_SUPPORTED) boolean dreamSupported, + @Named(DreamModule.DREAM_ONLY_ENABLED_FOR_SYSTEM_USER) + boolean dreamOnlyEnabledForSystemUser ) { super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger, statusBarStateController, activityStarter, qsLogger); mDreamManager = dreamManager; - mSecureSettings = secureSettings; mBroadcastDispatcher = broadcastDispatcher; mEnabledSettingObserver = new SettingObserver(secureSettings, mHandler, Settings.Secure.SCREENSAVER_ENABLED) { @@ -104,6 +113,9 @@ public class DreamTile extends QSTileImpl<QSTile.BooleanState> { refreshState(); } }; + mUserTracker = userTracker; + mDreamSupported = dreamSupported; + mDreamOnlyEnabledForSystemUser = dreamOnlyEnabledForSystemUser; } @Override @@ -156,6 +168,7 @@ public class DreamTile extends QSTileImpl<QSTile.BooleanState> { state.label = getTileLabel(); state.secondaryLabel = getActiveDreamName(); state.contentDescription = getContentDescription(state.secondaryLabel); + state.icon = mIcon; if (getActiveDream() == null || !isScreensaverEnabled()) { state.state = Tile.STATE_UNAVAILABLE; @@ -177,8 +190,11 @@ public class DreamTile extends QSTileImpl<QSTile.BooleanState> { @Override public boolean isAvailable() { - // For now, only present on userdebug devices. - return Build.isDebuggable(); + // Only enable for devices that have dreams for the user(s) that can dream. + // For now, restrict to debug users. + return Build.isDebuggable() + && mDreamSupported + && (!mDreamOnlyEnabledForSystemUser || mUserTracker.getUserHandle().isSystem()); } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 4728c678f96c..6d9455e80adc 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -484,6 +484,7 @@ public class ScreenshotController { setWindowFocusable(false); } }); + mScreenshotView.setDefaultTimeoutMillis(mScreenshotHandler.getDefaultTimeoutMillis()); mScreenshotView.setOnKeyListener((v, keyCode, event) -> { if (keyCode == KeyEvent.KEYCODE_BACK) { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java index 6af6e36a75f7..48bb2af2ab8d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java @@ -18,6 +18,7 @@ package com.android.systemui.screenshot; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_TAKE_SCREENSHOT; import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM; import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS; import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT; @@ -83,6 +84,7 @@ import android.widget.LinearLayout; import androidx.constraintlayout.widget.ConstraintLayout; +import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; @@ -149,7 +151,6 @@ public class ScreenshotView extends FrameLayout implements private ImageView mActionsContainerBackground; private HorizontalScrollView mActionsContainer; private LinearLayout mActionsView; - private ImageView mBackgroundProtection; private FrameLayout mDismissButton; private OverlayActionChip mShareChip; private OverlayActionChip mEditChip; @@ -167,6 +168,9 @@ public class ScreenshotView extends FrameLayout implements private final ArrayList<OverlayActionChip> mSmartChips = new ArrayList<>(); private PendingInteraction mPendingInteraction; + private final InteractionJankMonitor mInteractionJankMonitor; + private long mDefaultTimeoutOfTimeoutHandler; + private enum PendingInteraction { PREVIEW, EDIT, @@ -190,6 +194,7 @@ public class ScreenshotView extends FrameLayout implements Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mResources = mContext.getResources(); + mInteractionJankMonitor = getInteractionJankMonitorInstance(); mFixedSize = mResources.getDimensionPixelSize(R.dimen.overlay_x_scale); @@ -230,6 +235,14 @@ public class ScreenshotView extends FrameLayout implements }); } + private InteractionJankMonitor getInteractionJankMonitorInstance() { + return InteractionJankMonitor.getInstance(); + } + + void setDefaultTimeoutMillis(long timeout) { + mDefaultTimeoutOfTimeoutHandler = timeout; + } + public void hideScrollChip() { mScrollChip.setVisibility(View.GONE); } @@ -345,8 +358,6 @@ public class ScreenshotView extends FrameLayout implements R.id.actions_container_background)); mActionsContainer = requireNonNull(findViewById(R.id.actions_container)); mActionsView = requireNonNull(findViewById(R.id.screenshot_actions)); - mBackgroundProtection = requireNonNull( - findViewById(R.id.screenshot_actions_background)); mDismissButton = requireNonNull(findViewById(R.id.screenshot_dismiss_button)); mScrollablePreview = requireNonNull(findViewById(R.id.screenshot_scrollable_preview)); mScreenshotFlash = requireNonNull(findViewById(R.id.screenshot_flash)); @@ -394,18 +405,13 @@ public class ScreenshotView extends FrameLayout implements } mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SWIPE_DISMISSED, 0, mPackageName); - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - super.onAnimationStart(animation); - mBackgroundProtection.animate() - .alpha(0).setDuration(animation.getDuration()).start(); - } - }); } @Override public void onDismissComplete() { + if (mInteractionJankMonitor.isInstrumenting(CUJ_TAKE_SCREENSHOT)) { + mInteractionJankMonitor.end(CUJ_TAKE_SCREENSHOT); + } mCallbacks.onDismiss(); } }); @@ -606,6 +612,20 @@ public class ScreenshotView extends FrameLayout implements dropInAnimation.addListener(new AnimatorListenerAdapter() { @Override + public void onAnimationCancel(Animator animation) { + mInteractionJankMonitor.cancel(CUJ_TAKE_SCREENSHOT); + } + + @Override + public void onAnimationStart(Animator animation) { + InteractionJankMonitor.Configuration.Builder builder = + InteractionJankMonitor.Configuration.Builder.withView( + CUJ_TAKE_SCREENSHOT, mScreenshotPreview) + .setTag("DropIn"); + mInteractionJankMonitor.begin(builder); + } + + @Override public void onAnimationEnd(Animator animation) { if (DEBUG_ANIM) { Log.d(TAG, "drop-in animation ended"); @@ -631,7 +651,7 @@ public class ScreenshotView extends FrameLayout implements mScreenshotPreview.setX(finalPos.x - mScreenshotPreview.getWidth() / 2f); mScreenshotPreview.setY(finalPos.y - mScreenshotPreview.getHeight() / 2f); requestLayout(); - + mInteractionJankMonitor.end(CUJ_TAKE_SCREENSHOT); createScreenshotActionsShadeAnimation().start(); } }); @@ -702,9 +722,30 @@ public class ScreenshotView extends FrameLayout implements mActionsContainer.setVisibility(View.VISIBLE); mActionsContainerBackground.setVisibility(View.VISIBLE); + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationCancel(Animator animation) { + mInteractionJankMonitor.cancel(CUJ_TAKE_SCREENSHOT); + } + + @Override + public void onAnimationEnd(Animator animation) { + mInteractionJankMonitor.end(CUJ_TAKE_SCREENSHOT); + } + + @Override + public void onAnimationStart(Animator animation) { + InteractionJankMonitor.Configuration.Builder builder = + InteractionJankMonitor.Configuration.Builder.withView( + CUJ_TAKE_SCREENSHOT, mScreenshotStatic) + .setTag("Actions") + .setTimeout(mDefaultTimeoutOfTimeoutHandler); + mInteractionJankMonitor.begin(builder); + } + }); + animator.addUpdateListener(animation -> { float t = animation.getAnimatedFraction(); - mBackgroundProtection.setAlpha(t); float containerAlpha = t < alphaFraction ? t / alphaFraction : 1; mActionsContainer.setAlpha(containerAlpha); mActionsContainerBackground.setAlpha(containerAlpha); @@ -910,7 +951,6 @@ public class ScreenshotView extends FrameLayout implements } mDismissButton.setVisibility(View.GONE); mActionsContainer.setVisibility(View.GONE); - mBackgroundProtection.setVisibility(View.GONE); // set these invisible, but not gone, so that the views are laid out correctly mActionsContainerBackground.setVisibility(View.INVISIBLE); mScreenshotPreviewBorder.setVisibility(View.INVISIBLE); @@ -932,7 +972,6 @@ public class ScreenshotView extends FrameLayout implements mDismissButton.setVisibility(View.VISIBLE); } mActionsContainer.setVisibility(View.VISIBLE); - mBackgroundProtection.setVisibility(View.VISIBLE); mActionsContainerBackground.setVisibility(View.VISIBLE); mScreenshotPreviewBorder.setVisibility(View.VISIBLE); mScreenshotPreview.setVisibility(View.VISIBLE); @@ -969,7 +1008,6 @@ public class ScreenshotView extends FrameLayout implements mPendingSharedTransition = false; mActionsContainerBackground.setVisibility(View.GONE); mActionsContainer.setVisibility(View.GONE); - mBackgroundProtection.setAlpha(0f); mDismissButton.setVisibility(View.GONE); mScrollingScrim.setVisibility(View.GONE); mScrollablePreview.setVisibility(View.GONE); @@ -1016,7 +1054,6 @@ public class ScreenshotView extends FrameLayout implements mDismissButton.setAlpha(alpha); mActionsContainerBackground.setAlpha(alpha); mActionsContainer.setAlpha(alpha); - mBackgroundProtection.setAlpha(alpha); mScreenshotPreviewBorder.setAlpha(alpha); }); alphaAnim.setDuration(600); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TimeoutHandler.java b/packages/SystemUI/src/com/android/systemui/screenshot/TimeoutHandler.java index 9156601e6638..71c2cb4a5cb9 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TimeoutHandler.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TimeoutHandler.java @@ -72,6 +72,10 @@ public class TimeoutHandler extends Handler { mDefaultTimeout = timeout; } + int getDefaultTimeoutMillis() { + return mDefaultTimeout; + } + /** * Cancel the current timeout, if any. To reset the delayed runnable use resetTimeout instead. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java index 4d933d9ad21e..e44d334c776d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java @@ -29,7 +29,6 @@ import com.android.keyguard.AlphaOptimizedLinearLayout; import com.android.systemui.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.NotificationEntry.OnSensitivityChangedListener; import java.util.ArrayList; @@ -49,6 +48,7 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout { private TextView mTextView; private NotificationEntry mShowingEntry; private Runnable mOnDrawingRectChangedListener; + private boolean mRedactSensitiveContent; public HeadsUpStatusBarView(Context context) { this(context, null); @@ -111,29 +111,28 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout { } public void setEntry(NotificationEntry entry) { - if (mShowingEntry != null) { - mShowingEntry.removeOnSensitivityChangedListener(mOnSensitivityChangedListener); - } mShowingEntry = entry; - if (mShowingEntry != null) { CharSequence text = entry.headsUpStatusBarText; - if (entry.isSensitive()) { + if (mRedactSensitiveContent && entry.hasSensitiveContents()) { text = entry.headsUpStatusBarTextPublic; } mTextView.setText(text); - mShowingEntry.addOnSensitivityChangedListener(mOnSensitivityChangedListener); } } - private final OnSensitivityChangedListener mOnSensitivityChangedListener = entry -> { - if (entry != mShowingEntry) { - throw new IllegalStateException("Got a sensitivity change for " + entry - + " but mShowingEntry is " + mShowingEntry); + public void setRedactSensitiveContent(boolean redactSensitiveContent) { + if (mRedactSensitiveContent == redactSensitiveContent) { + return; + } + mRedactSensitiveContent = redactSensitiveContent; + if (mShowingEntry != null && mShowingEntry.hasSensitiveContents()) { + mTextView.setText( + mRedactSensitiveContent + ? mShowingEntry.headsUpStatusBarTextPublic + : mShowingEntry.headsUpStatusBarText); } - // Update the text - setEntry(entry); - }; + } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index c1ea6bf7cec8..cbe722b6f82f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -386,7 +386,7 @@ class LockscreenShadeTransitionController @Inject constructor( } if (view is ExpandableNotificationRow) { // Only drag down on sensitive views, otherwise the ExpandHelper will take this - return view.entry.isSensitive + return lockScreenUserManager.notifNeedsRedactionInPublic(view.entry) } } return false @@ -552,7 +552,8 @@ class LockscreenShadeTransitionController @Inject constructor( logger.logShadeDisabledOnGoToLockedShade() return } - var userId: Int = lockScreenUserManager.getCurrentUserId() + val currentUser = lockScreenUserManager.currentUserId + var userId: Int = currentUser var entry: NotificationEntry? = null if (expandView is ExpandableNotificationRow) { entry = expandView.entry @@ -562,12 +563,18 @@ class LockscreenShadeTransitionController @Inject constructor( entry.setGroupExpansionChanging(true) userId = entry.sbn.userId } - var fullShadeNeedsBouncer = (!lockScreenUserManager.userAllowsPrivateNotificationsInPublic( - lockScreenUserManager.getCurrentUserId()) || - !lockScreenUserManager.shouldShowLockscreenNotifications() || - falsingCollector.shouldEnforceBouncer()) - if (keyguardBypassController.bypassEnabled) { - fullShadeNeedsBouncer = false + val fullShadeNeedsBouncer = when { + // No bouncer necessary if we're bypassing + keyguardBypassController.bypassEnabled -> false + // Redacted notificationss are present, bouncer should be shown before un-redacting in + // the full shade + lockScreenUserManager.sensitiveNotifsNeedRedactionInPublic(currentUser) -> true + // Notifications are hidden in public, bouncer should be shown before showing them in + // the full shade + !lockScreenUserManager.shouldShowLockscreenNotifications() -> true + // Bouncer is being enforced, so we need to show it + falsingCollector.shouldEnforceBouncer() -> true + else -> false } if (lockScreenUserManager.isLockscreenPublicMode(userId) && fullShadeNeedsBouncer) { statusBarStateController.setLeaveOpenOnKeyguardHide(true) @@ -911,4 +918,4 @@ class DragDownHelper( host.getLocationOnScreen(temp2) return expandCallback.getChildAtRawPosition(x + temp2[0], y + temp2[1]) } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java index 9a1a144924e2..5fd9671bda01 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java @@ -71,17 +71,22 @@ public interface NotificationLockscreenUserManager { boolean shouldHideNotifications(String key); boolean shouldShowOnKeyguard(NotificationEntry entry); + void addOnNeedsRedactionInPublicChangedListener(Runnable listener); + + void removeOnNeedsRedactionInPublicChangedListener(Runnable listener); + boolean isAnyProfilePublicMode(); void updatePublicMode(); - boolean needsRedaction(NotificationEntry entry); + /** Does this notification require redaction if it is displayed when the device is public? */ + boolean notifNeedsRedactionInPublic(NotificationEntry entry); /** - * Has the given user chosen to allow their private (full) notifications to be shown even - * when the lockscreen is in "public" (secure & locked) mode? + * Do all sensitive notifications belonging to the given user require redaction when they are + * displayed in public? */ - boolean userAllowsPrivateNotificationsInPublic(int currentUserId); + boolean sensitiveNotifsNeedRedactionInPublic(int userId); /** * Has the given user chosen to allow notifications to be shown even when the lockscreen is in diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index 56e09f03aa6b..334cfe5f4c41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -24,7 +24,6 @@ import static com.android.systemui.statusbar.notification.stack.NotificationPrio import android.app.ActivityManager; import android.app.KeyguardManager; -import android.app.Notification; import android.app.NotificationManager; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; @@ -45,7 +44,6 @@ import android.util.SparseBooleanArray; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; @@ -60,6 +58,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.Co import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.util.ListenerSet; import com.android.systemui.util.settings.SecureSettings; import java.io.PrintWriter; @@ -85,13 +84,12 @@ public class NotificationLockscreenUserManagerImpl implements private final DeviceProvisionedController mDeviceProvisionedController; private final KeyguardStateController mKeyguardStateController; private final SecureSettings mSecureSettings; + private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final Lazy<OverviewProxyService> mOverviewProxyService; private final Object mLock = new Object(); - - // Lazy - private NotificationEntryManager mEntryManager; - private final Lazy<NotificationVisibilityProvider> mVisibilityProviderLazy; private final Lazy<CommonNotifCollection> mCommonNotifCollectionLazy; + private final Lazy<NotificationEntryManager> mEntryManagerLazy; private final DevicePolicyManager mDevicePolicyManager; private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray(); private final SparseBooleanArray mUsersWithSeparateWorkChallenge = new SparseBooleanArray(); @@ -103,13 +101,14 @@ public class NotificationLockscreenUserManagerImpl implements private final List<UserChangedListener> mListeners = new ArrayList<>(); private final BroadcastDispatcher mBroadcastDispatcher; private final NotificationClickNotifier mClickNotifier; - - private boolean mShowLockscreenNotifications; - private boolean mAllowLockscreenRemoteInput; - private LockPatternUtils mLockPatternUtils; - protected KeyguardManager mKeyguardManager; - private int mState = StatusBarState.SHADE; - private List<KeyguardNotificationSuppressor> mKeyguardSuppressors = new ArrayList<>(); + private final LockPatternUtils mLockPatternUtils; + private final List<KeyguardNotificationSuppressor> mKeyguardSuppressors = new ArrayList<>(); + protected final Context mContext; + private final Handler mMainHandler; + protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>(); + protected final SparseArray<UserInfo> mCurrentManagedProfiles = new SparseArray<>(); + private final ListenerSet<Runnable> mOnSensitiveContentRedactionChangeListeners = + new ListenerSet<>(); protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() { @Override @@ -120,7 +119,11 @@ public class NotificationLockscreenUserManagerImpl implements isCurrentProfile(getSendingUserId())) { mUsersAllowingPrivateNotifications.clear(); updateLockscreenNotificationSetting(); - getEntryManager().updateNotifications("ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED"); + for (Runnable listener : mOnSensitiveContentRedactionChangeListeners) { + listener.run(); + } + mEntryManagerLazy.get() + .updateNotifications("ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED"); } } }; @@ -142,7 +145,7 @@ public class NotificationLockscreenUserManagerImpl implements // The filtering needs to happen before the update call below in order to // make sure // the presenter has the updated notifications from the new user - getEntryManager().reapplyFilterAndSort("user switched"); + mEntryManagerLazy.get().reapplyFilterAndSort("user switched"); mPresenter.onUserSwitched(mCurrentUserId); for (UserChangedListener listener : mListeners) { @@ -156,7 +159,7 @@ public class NotificationLockscreenUserManagerImpl implements break; case Intent.ACTION_USER_UNLOCKED: // Start the overview connection to the launcher service - Dependency.get(OverviewProxyService.class).startConnectionToCurrentUser(); + mOverviewProxyService.get().startConnectionToCurrentUser(); break; case NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION: final IntentSender intentSender = intent.getParcelableExtra( @@ -179,28 +182,26 @@ public class NotificationLockscreenUserManagerImpl implements } }; - protected final Context mContext; - private final Handler mMainHandler; - protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>(); - protected final SparseArray<UserInfo> mCurrentManagedProfiles = new SparseArray<>(); - - protected int mCurrentUserId = 0; + // Late-init protected NotificationPresenter mPresenter; protected ContentObserver mLockscreenSettingsObserver; protected ContentObserver mSettingsObserver; - private boolean mHideSilentNotificationsOnLockscreen; + protected KeyguardManager mKeyguardManager; - private NotificationEntryManager getEntryManager() { - if (mEntryManager == null) { - mEntryManager = Dependency.get(NotificationEntryManager.class); - } - return mEntryManager; - } + protected int mCurrentUserId = 0; + private int mState = StatusBarState.SHADE; + private boolean mHideSilentNotificationsOnLockscreen; + private boolean mShowLockscreenNotifications; + private boolean mAllowLockscreenRemoteInput; @Inject - public NotificationLockscreenUserManagerImpl(Context context, + public NotificationLockscreenUserManagerImpl( + Context context, BroadcastDispatcher broadcastDispatcher, DevicePolicyManager devicePolicyManager, + KeyguardUpdateMonitor keyguardUpdateMonitor, + Lazy<NotificationEntryManager> notificationEntryManagerLazy, + Lazy<OverviewProxyService> overviewProxyServiceLazy, UserManager userManager, Lazy<NotificationVisibilityProvider> visibilityProviderLazy, Lazy<CommonNotifCollection> commonNotifCollectionLazy, @@ -216,9 +217,11 @@ public class NotificationLockscreenUserManagerImpl implements mMainHandler = mainHandler; mDevicePolicyManager = devicePolicyManager; mUserManager = userManager; + mOverviewProxyService = overviewProxyServiceLazy; mCurrentUserId = ActivityManager.getCurrentUser(); mVisibilityProviderLazy = visibilityProviderLazy; mCommonNotifCollectionLazy = commonNotifCollectionLazy; + mEntryManagerLazy = notificationEntryManagerLazy; mClickNotifier = clickNotifier; statusBarStateController.addCallback(this); mLockPatternUtils = new LockPatternUtils(context); @@ -227,10 +230,12 @@ public class NotificationLockscreenUserManagerImpl implements mDeviceProvisionedController = deviceProvisionedController; mSecureSettings = secureSettings; mKeyguardStateController = keyguardStateController; + mKeyguardUpdateMonitor = keyguardUpdateMonitor; dumpManager.registerDumpable(this); } + @Override public void setUpWithPresenter(NotificationPresenter presenter) { mPresenter = presenter; @@ -243,7 +248,10 @@ public class NotificationLockscreenUserManagerImpl implements mUsersAllowingNotifications.clear(); // ... and refresh all the notifications updateLockscreenNotificationSetting(); - getEntryManager().updateNotifications("LOCK_SCREEN_SHOW_NOTIFICATIONS," + for (Runnable listener : mOnSensitiveContentRedactionChangeListeners) { + listener.run(); + } + mEntryManagerLazy.get().updateNotifications("LOCK_SCREEN_SHOW_NOTIFICATIONS," + " or LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS change"); } }; @@ -253,7 +261,7 @@ public class NotificationLockscreenUserManagerImpl implements public void onChange(boolean selfChange) { updateLockscreenNotificationSetting(); if (mDeviceProvisionedController.isDeviceProvisioned()) { - getEntryManager().updateNotifications("LOCK_SCREEN_ALLOW_REMOTE_INPUT" + mEntryManagerLazy.get().updateNotifications("LOCK_SCREEN_ALLOW_REMOTE_INPUT" + " or ZEN_MODE change"); } } @@ -312,14 +320,17 @@ public class NotificationLockscreenUserManagerImpl implements mSettingsObserver.onChange(false); // set up } + @Override public boolean shouldShowLockscreenNotifications() { return mShowLockscreenNotifications; } + @Override public boolean shouldAllowLockscreenRemoteInput() { return mAllowLockscreenRemoteInput; } + @Override public boolean isCurrentProfile(int userId) { synchronized (mLock) { return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null; @@ -334,7 +345,7 @@ public class NotificationLockscreenUserManagerImpl implements if (userId == UserHandle.USER_ALL) { userId = mCurrentUserId; } - boolean inLockdown = Dependency.get(KeyguardUpdateMonitor.class).isUserInLockdown(userId); + boolean inLockdown = mKeyguardUpdateMonitor.isUserInLockdown(userId); mUsersInLockdownLatestResult.put(userId, inLockdown); return inLockdown; } @@ -343,6 +354,7 @@ public class NotificationLockscreenUserManagerImpl implements * Returns true if we're on a secure lockscreen and the user wants to hide notification data. * If so, notifications should be hidden. */ + @Override public boolean shouldHideNotifications(int userId) { boolean hide = isLockscreenPublicMode(userId) && !userAllowsNotificationsInPublic(userId) || (userId != mCurrentUserId && shouldHideNotifications(mCurrentUserId)) @@ -355,6 +367,7 @@ public class NotificationLockscreenUserManagerImpl implements * Returns true if we're on a secure lockscreen and the user wants to hide notifications via * package-specific override. */ + @Override public boolean shouldHideNotifications(String key) { if (mCommonNotifCollectionLazy.get() == null) { Log.wtf(TAG, "mCommonNotifCollectionLazy was null!", new Throwable()); @@ -365,6 +378,7 @@ public class NotificationLockscreenUserManagerImpl implements && visibleEntry.getRanking().getLockscreenVisibilityOverride() == VISIBILITY_SECRET; } + @Override public boolean shouldShowOnKeyguard(NotificationEntry entry) { if (mCommonNotifCollectionLazy.get() == null) { Log.wtf(TAG, "mCommonNotifCollectionLazy was null!", new Throwable()); @@ -387,14 +401,6 @@ public class NotificationLockscreenUserManagerImpl implements return mShowLockscreenNotifications && exceedsPriorityThreshold; } - private void setShowLockscreenNotifications(boolean show) { - mShowLockscreenNotifications = show; - } - - private void setLockscreenAllowRemoteInput(boolean allowLockscreenRemoteInput) { - mAllowLockscreenRemoteInput = allowLockscreenRemoteInput; - } - protected void updateLockscreenNotificationSetting() { final boolean show = mSecureSettings.getIntForUser( Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, @@ -408,7 +414,7 @@ public class NotificationLockscreenUserManagerImpl implements mHideSilentNotificationsOnLockscreen = mSecureSettings.getIntForUser( Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1, mCurrentUserId) == 0; - setShowLockscreenNotifications(show && allowedByDpm); + mShowLockscreenNotifications = show && allowedByDpm; if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) { final boolean remoteInput = mSecureSettings.getIntForUser( @@ -418,9 +424,9 @@ public class NotificationLockscreenUserManagerImpl implements final boolean remoteInputDpm = (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0; - setLockscreenAllowRemoteInput(remoteInput && remoteInputDpm); + mAllowLockscreenRemoteInput = remoteInput && remoteInputDpm; } else { - setLockscreenAllowRemoteInput(false); + mAllowLockscreenRemoteInput = false; } } @@ -428,7 +434,7 @@ public class NotificationLockscreenUserManagerImpl implements * Has the given user chosen to allow their private (full) notifications to be shown even * when the lockscreen is in "public" (secure & locked) mode? */ - public boolean userAllowsPrivateNotificationsInPublic(int userHandle) { + protected boolean userAllowsPrivateNotificationsInPublic(int userHandle) { if (userHandle == UserHandle.USER_ALL) { return true; } @@ -473,10 +479,12 @@ public class NotificationLockscreenUserManagerImpl implements /** * Save the current "public" (locked and secure) state of the lockscreen. */ + @Override public void setLockscreenPublicMode(boolean publicMode, int userId) { mLockscreenPublicMode.put(userId, publicMode); } + @Override public boolean isLockscreenPublicMode(int userId) { if (userId == UserHandle.USER_ALL) { return mLockscreenPublicMode.get(mCurrentUserId, false); @@ -493,6 +501,7 @@ public class NotificationLockscreenUserManagerImpl implements * Has the given user chosen to allow notifications to be shown even when the lockscreen is in * "public" (secure & locked) mode? */ + @Override public boolean userAllowsNotificationsInPublic(int userHandle) { if (isCurrentProfile(userHandle) && userHandle != mCurrentUserId) { return true; @@ -513,36 +522,37 @@ public class NotificationLockscreenUserManagerImpl implements } /** @return true if the entry needs redaction when on the lockscreen. */ - public boolean needsRedaction(NotificationEntry ent) { + @Override + public boolean notifNeedsRedactionInPublic(NotificationEntry ent) { int userId = ent.getSbn().getUserId(); + return ent.hasSensitiveContents() && sensitiveNotifsNeedRedactionInPublic(userId); + } + @Override + public boolean sensitiveNotifsNeedRedactionInPublic(int userId) { boolean isCurrentUserRedactingNotifs = !userAllowsPrivateNotificationsInPublic(mCurrentUserId); + if (userId == mCurrentUserId) { + return isCurrentUserRedactingNotifs; + } + boolean isNotifForManagedProfile = mCurrentManagedProfiles.contains(userId); boolean isNotifUserRedacted = !userAllowsPrivateNotificationsInPublic(userId); // redact notifications if the current user is redacting notifications; however if the // notification is associated with a managed profile, we rely on the managed profile // setting to determine whether to redact it - boolean isNotifRedacted = (!isNotifForManagedProfile && isCurrentUserRedactingNotifs) - || isNotifUserRedacted; - - boolean notificationRequestsRedaction = - ent.getSbn().getNotification().visibility == Notification.VISIBILITY_PRIVATE; - boolean userForcesRedaction = packageHasVisibilityOverride(ent.getSbn().getKey()); + return (!isNotifForManagedProfile && isCurrentUserRedactingNotifs) || isNotifUserRedacted; + } - return userForcesRedaction || notificationRequestsRedaction && isNotifRedacted; + @Override + public void addOnNeedsRedactionInPublicChangedListener(Runnable listener) { + mOnSensitiveContentRedactionChangeListeners.addIfAbsent(listener); } - private boolean packageHasVisibilityOverride(String key) { - if (mCommonNotifCollectionLazy.get() == null) { - Log.wtf(TAG, "mEntryManager was null!", new Throwable()); - return true; - } - NotificationEntry entry = mCommonNotifCollectionLazy.get().getEntry(key); - return entry != null - && entry.getRanking().getLockscreenVisibilityOverride() - == Notification.VISIBILITY_PRIVATE; + @Override + public void removeOnNeedsRedactionInPublicChangedListener(Runnable listener) { + mOnSensitiveContentRedactionChangeListeners.remove(listener); } private void updateCurrentProfilesCache() { @@ -562,12 +572,16 @@ public class NotificationLockscreenUserManagerImpl implements for (UserChangedListener listener : mListeners) { listener.onCurrentProfilesChanged(mCurrentProfiles); } + for (Runnable listener : mOnSensitiveContentRedactionChangeListeners) { + listener.run(); + } }); } /** * If any of the profiles are in public mode. */ + @Override public boolean isAnyProfilePublicMode() { synchronized (mLock) { for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) { @@ -596,10 +610,12 @@ public class NotificationLockscreenUserManagerImpl implements /** * Returns the current user id. This can change if the user is switched. */ + @Override public int getCurrentUserId() { return mCurrentUserId; } + @Override public SparseArray<UserInfo> getCurrentProfiles() { return mCurrentProfiles; } @@ -640,7 +656,8 @@ public class NotificationLockscreenUserManagerImpl implements setLockscreenPublicMode(isProfilePublic, userId); mUsersWithSeparateWorkChallenge.put(userId, needsSeparateChallenge); } - getEntryManager().updateNotifications("NotificationLockscreenUserManager.updatePublicMode"); + mEntryManagerLazy.get() + .updateNotifications("NotificationLockscreenUserManager.updatePublicMode"); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 734bc48093b2..0d604014e8f1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -326,9 +326,9 @@ public class NotificationShelf extends ActivatableNotificationView implements || child.isPinned(); boolean isLastChild = child == lastChild; final float viewStart = child.getTranslationY(); - - final float inShelfAmount = updateShelfTransformation(i, child, scrollingFast, - expandingAnimated, isLastChild); + final float shelfClipStart = getTranslationY() - mPaddingBetweenElements; + final float inShelfAmount = getAmountInShelf(i, child, scrollingFast, + expandingAnimated, isLastChild, shelfClipStart); // TODO(b/172289889) scale mPaddingBetweenElements with expansion amount if ((isLastChild && !child.isInShelf()) || aboveShelf || backgroundForceHidden) { @@ -609,10 +609,18 @@ public class NotificationShelf extends ActivatableNotificationView implements } /** - * @return the amount how much this notification is in the shelf + * @param i Index of the view in the host layout. + * @param view The current ExpandableView. + * @param scrollingFast Whether we are scrolling fast. + * @param expandingAnimated Whether we are expanding a notification. + * @param isLastChild Whether this is the last view. + * @param shelfClipStart The point at which notifications start getting clipped by the shelf. + * @return The amount how much this notification is in the shelf. + * 0f is not in shelf. 1f is completely in shelf. */ - private float updateShelfTransformation(int i, ExpandableView view, boolean scrollingFast, - boolean expandingAnimated, boolean isLastChild) { + @VisibleForTesting + public float getAmountInShelf(int i, ExpandableView view, boolean scrollingFast, + boolean expandingAnimated, boolean isLastChild, float shelfClipStart) { // Let's calculate how much the view is in the shelf float viewStart = view.getTranslationY(); @@ -635,29 +643,33 @@ public class NotificationShelf extends ActivatableNotificationView implements float viewEnd = viewStart + fullHeight; float fullTransitionAmount = 0.0f; float iconTransitionAmount = 0.0f; - float shelfStart = getTranslationY() - mPaddingBetweenElements; + + // Don't animate shelf icons during shade expansion. if (mAmbientState.isExpansionChanging() && !mAmbientState.isOnKeyguard()) { // TODO(b/172289889) handle icon placement for notification that is clipped by the shelf if (mIndexOfFirstViewInShelf != -1 && i >= mIndexOfFirstViewInShelf) { fullTransitionAmount = 1f; iconTransitionAmount = 1f; } - } else if (viewEnd >= shelfStart + + } else if (viewEnd >= shelfClipStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf()) && (mAmbientState.isShadeExpanded() || (!view.isPinned() && !view.isHeadsUpAnimatingAway()))) { - if (viewStart < shelfStart) { - float fullAmount = (shelfStart - viewStart) / fullHeight; + if (viewStart < shelfClipStart && Math.abs(viewStart - shelfClipStart) > 0.001f) { + // Partially clipped by shelf. + float fullAmount = (shelfClipStart - viewStart) / fullHeight; fullAmount = Math.min(1.0f, fullAmount); fullTransitionAmount = 1.0f - fullAmount; if (isLastChild) { // Reduce icon transform distance to completely fade in shelf icon // by the time the notification icon fades out, and vice versa - iconTransitionAmount = (shelfStart - viewStart) + iconTransitionAmount = (shelfClipStart - viewStart) / (iconTransformStart - viewStart); } else { - iconTransitionAmount = (shelfStart - iconTransformStart) / transformDistance; + iconTransitionAmount = (shelfClipStart - iconTransformStart) + / transformDistance; } iconTransitionAmount = MathUtils.constrain(iconTransitionAmount, 0.0f, 1.0f); iconTransitionAmount = 1.0f - iconTransitionAmount; @@ -772,6 +784,9 @@ public class NotificationShelf extends ActivatableNotificationView implements } private NotificationIconContainer.IconState getIconState(StatusBarIconView icon) { + if (mShelfIcons == null) { + return null; + } return mShelfIcons.getIconState(icon); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index 054543c7d2b1..30cb09d56f17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -53,6 +53,7 @@ import com.android.wm.shell.bubbles.Bubbles; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Stack; @@ -207,12 +208,9 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle || !mLockscreenUserManager.needsSeparateWorkChallenge(userId))) { userPublic = false; } - boolean needsRedaction = mLockscreenUserManager.needsRedaction(ent); + boolean needsRedaction = mLockscreenUserManager.notifNeedsRedactionInPublic(ent); boolean sensitive = userPublic && needsRedaction; - boolean deviceSensitive = devicePublic - && !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic( - currentUserId); - ent.setSensitive(sensitive, deviceSensitive); + ent.getRow().setSensitive(sensitive); ent.getRow().setNeedsRedaction(needsRedaction); mLowPriorityInflationHelper.recheckLowPriorityViewAndInflate(ent, ent.getRow()); boolean isChildInGroup = mGroupManager.isChildInGroup(ent); @@ -365,6 +363,8 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle boolean hasClearableAlertingNotifs = false; boolean hasNonClearableSilentNotifs = false; boolean hasClearableSilentNotifs = false; + HashSet<Integer> clearableAlertingSensitiveNotifUsers = new HashSet<>(); + HashSet<Integer> clearableSilentSensitiveNotifUsers = new HashSet<>(); final int childCount = mListContainer.getContainerChildCount(); int visibleTopLevelEntries = 0; for (int i = 0; i < childCount; i++) { @@ -376,10 +376,11 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle continue; } final ExpandableNotificationRow row = (ExpandableNotificationRow) child; - boolean isSilent = row.getEntry().getBucket() == BUCKET_SILENT; + NotificationEntry entry = row.getEntry(); + boolean isSilent = entry.getBucket() == BUCKET_SILENT; // NOTE: NotificationEntry.isClearable() will internally check group children to ensure // the group itself definitively clearable. - boolean isClearable = row.getEntry().isClearable(); + boolean isClearable = entry.isClearable(); visibleTopLevelEntries++; if (isSilent) { if (isClearable) { @@ -394,13 +395,24 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle hasNonClearableAlertingNotifs = true; } } + if (isClearable && entry.hasSensitiveContents()) { + int userId = entry.getSbn().getUserId(); + if (isSilent) { + clearableSilentSensitiveNotifUsers.add(userId); + } else { + clearableAlertingSensitiveNotifUsers.add(userId); + } + } } mStackController.setNotifStats(new NotifStats( visibleTopLevelEntries /* numActiveNotifs */, hasNonClearableAlertingNotifs /* hasNonClearableAlertingNotifs */, hasClearableAlertingNotifs /* hasClearableAlertingNotifs */, hasNonClearableSilentNotifs /* hasNonClearableSilentNotifs */, - hasClearableSilentNotifs /* hasClearableSilentNotifs */ + hasClearableSilentNotifs /* hasClearableSilentNotifs */, + clearableAlertingSensitiveNotifUsers /* clearableAlertingSensitiveNotifUsers */, + clearableSilentSensitiveNotifUsers /* clearableSilentSensitiveNotifUsers */ + )); Trace.endSection(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java index a0ccd5726c75..d16e9e5d7faf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java @@ -80,7 +80,7 @@ public class DynamicPrivacyController implements KeyguardStateController.Callbac @VisibleForTesting boolean isDynamicPrivacyEnabled() { - return !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic( + return mLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic( mLockscreenUserManager.getCurrentUserId()); } @@ -95,6 +95,10 @@ public class DynamicPrivacyController implements KeyguardStateController.Callbac mListeners.add(listener); } + public void removeListener(Listener listener) { + mListeners.remove(listener); + } + /** * Is the notification shade currently in a locked down mode where it's fully showing but the * contents aren't revealed yet? 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..e3c39ddad145 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 @@ -169,9 +169,6 @@ public final class NotificationEntry extends ListEntry { */ private boolean hasSentReply; - private boolean mSensitive = true; - private List<OnSensitivityChangedListener> mOnSensitivityChangedListeners = new ArrayList<>(); - private boolean mAutoHeadsUp; private boolean mPulseSupressed; private int mBucket = BUCKET_ALERTING; @@ -867,33 +864,29 @@ public final class NotificationEntry extends ListEntry { } /** - * Set this notification to be sensitive. - * - * @param sensitive true if the content of this notification is sensitive right now - * @param deviceSensitive true if the device in general is sensitive right now - */ - public void setSensitive(boolean sensitive, boolean deviceSensitive) { - getRow().setSensitive(sensitive, deviceSensitive); - if (sensitive != mSensitive) { - mSensitive = sensitive; - for (int i = 0; i < mOnSensitivityChangedListeners.size(); i++) { - mOnSensitivityChangedListeners.get(i).onSensitivityChanged(this); - } + * Returns the visibility of this notification on the lockscreen, taking into account both the + * notification's defined visibility, as well as the visibility override as determined by the + * device policy. + */ + public int getLockscreenVisibility() { + int setting = mRanking.getLockscreenVisibilityOverride(); + if (setting == Ranking.VISIBILITY_NO_OVERRIDE) { + setting = mSbn.getNotification().visibility; } + return setting; } - public boolean isSensitive() { - return mSensitive; - } - - /** Add a listener to be notified when the entry's sensitivity changes. */ - public void addOnSensitivityChangedListener(OnSensitivityChangedListener listener) { - mOnSensitivityChangedListeners.add(listener); - } - - /** Remove a listener that was registered above. */ - public void removeOnSensitivityChangedListener(OnSensitivityChangedListener listener) { - mOnSensitivityChangedListeners.remove(listener); + /** + * Does this notification contain sensitive content? If the user's settings specify, then this + * content would need to be redacted when the device this public. + * + * NOTE: If the notification's visibility setting is VISIBILITY_SECRET, then this will return + * false; SECRET notifications are omitted entirely when the device is public, so effectively + * the contents of the notification are not sensitive whenever the notification is actually + * visible. + */ + public boolean hasSensitiveContents() { + return getLockscreenVisibility() == Notification.VISIBILITY_PRIVATE; } public boolean isPulseSuppressed() { @@ -954,12 +947,6 @@ public final class NotificationEntry extends ListEntry { } } - /** Listener interface for {@link #addOnSensitivityChangedListener} */ - public interface OnSensitivityChangedListener { - /** Called when the sensitivity changes */ - void onSensitivityChanged(@NonNull NotificationEntry entry); - } - /** @see #getDismissState() */ public enum DismissState { /** User has not dismissed this notif or its parent */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt index 3516625cc471..b24d2922adfb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt @@ -56,7 +56,6 @@ class NotifCoordinatorsImpl @Inject constructor( smartspaceDedupingCoordinator: SmartspaceDedupingCoordinator, viewConfigCoordinator: ViewConfigCoordinator, visualStabilityCoordinator: VisualStabilityCoordinator, - sensitiveContentCoordinator: SensitiveContentCoordinator, activityLaunchAnimCoordinator: ActivityLaunchAnimCoordinator ) : NotifCoordinators { @@ -94,7 +93,6 @@ class NotifCoordinatorsImpl @Inject constructor( mCoordinators.add(shadeEventCoordinator) mCoordinators.add(viewConfigCoordinator) mCoordinators.add(visualStabilityCoordinator) - mCoordinators.add(sensitiveContentCoordinator) mCoordinators.add(activityLaunchAnimCoordinator) if (notifPipelineFlags.isSmartspaceDedupingEnabled()) { mCoordinators.add(smartspaceDedupingCoordinator) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java index 57fd1975e13a..56484010c213 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.notification.collection.coordinator; -import android.annotation.NonNull; import android.annotation.Nullable; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -29,13 +28,11 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import com.android.systemui.statusbar.notification.collection.render.NodeController; -import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController; import com.android.systemui.statusbar.notification.dagger.AlertingHeader; import com.android.systemui.statusbar.notification.dagger.SilentHeader; import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt; import java.util.Collections; -import java.util.List; import javax.inject.Inject; @@ -53,10 +50,10 @@ public class RankingCoordinator implements Coordinator { private final HighPriorityProvider mHighPriorityProvider; private final SectionClassifier mSectionClassifier; private final NodeController mSilentNodeController; - private final SectionHeaderController mSilentHeaderController; private final NodeController mAlertingHeaderController; - private boolean mHasSilentEntries; - private boolean mHasMinimizedEntries; + private final AlertingNotifSectioner mAlertingNotifSectioner = new AlertingNotifSectioner(); + private final SilentNotifSectioner mSilentNotifSectioner = new SilentNotifSectioner(); + private final MinimizedNotifSectioner mMinimizedNotifSectioner = new MinimizedNotifSectioner(); @Inject public RankingCoordinator( @@ -64,14 +61,12 @@ public class RankingCoordinator implements Coordinator { HighPriorityProvider highPriorityProvider, SectionClassifier sectionClassifier, @AlertingHeader NodeController alertingHeaderController, - @SilentHeader SectionHeaderController silentHeaderController, @SilentHeader NodeController silentNodeController) { mStatusBarStateController = statusBarStateController; mHighPriorityProvider = highPriorityProvider; mSectionClassifier = sectionClassifier; mAlertingHeaderController = alertingHeaderController; mSilentNodeController = silentNodeController; - mSilentHeaderController = silentHeaderController; } @Override @@ -95,8 +90,44 @@ public class RankingCoordinator implements Coordinator { return mMinimizedNotifSectioner; } - private final NotifSectioner mAlertingNotifSectioner = new NotifSectioner("Alerting", - NotificationPriorityBucketKt.BUCKET_ALERTING) { + /** + * Checks whether to filter out the given notification based the notification's Ranking object. + * NotifListBuilder invalidates the notification list each time the ranking is updated, + * so we don't need to explicitly invalidate this filter on ranking update. + */ + private final NotifFilter mSuspendedFilter = new NotifFilter("IsSuspendedFilter") { + @Override + public boolean shouldFilterOut(NotificationEntry entry, long now) { + return entry.getRanking().isSuspended(); + } + }; + + private final NotifFilter mDndVisualEffectsFilter = new NotifFilter( + "DndSuppressingVisualEffects") { + @Override + public boolean shouldFilterOut(NotificationEntry entry, long now) { + if (mStatusBarStateController.isDozing() && entry.shouldSuppressAmbient()) { + return true; + } + + return !mStatusBarStateController.isDozing() && entry.shouldSuppressNotificationList(); + } + }; + + private final StatusBarStateController.StateListener mStatusBarStateCallback = + new StatusBarStateController.StateListener() { + @Override + public void onDozingChanged(boolean isDozing) { + mDndVisualEffectsFilter.invalidateList(); + } + }; + + private class AlertingNotifSectioner extends NotifSectioner { + + AlertingNotifSectioner() { + super("Alerting", NotificationPriorityBucketKt.BUCKET_ALERTING); + } + @Override public boolean isInSection(ListEntry entry) { return mHighPriorityProvider.isHighPriority(entry); @@ -111,10 +142,14 @@ public class RankingCoordinator implements Coordinator { } return null; } - }; + } + + private class SilentNotifSectioner extends NotifSectioner { + + SilentNotifSectioner() { + super("Silent", NotificationPriorityBucketKt.BUCKET_SILENT); + } - private final NotifSectioner mSilentNotifSectioner = new NotifSectioner("Silent", - NotificationPriorityBucketKt.BUCKET_SILENT) { @Override public boolean isInSection(ListEntry entry) { return !mHighPriorityProvider.isHighPriority(entry) @@ -126,24 +161,14 @@ public class RankingCoordinator implements Coordinator { public NodeController getHeaderNodeController() { return mSilentNodeController; } + } - @Nullable - @Override - public void onEntriesUpdated(@NonNull List<ListEntry> entries) { - mHasSilentEntries = false; - for (int i = 0; i < entries.size(); i++) { - if (entries.get(i).getRepresentativeEntry().getSbn().isClearable()) { - mHasSilentEntries = true; - break; - } - } - mSilentHeaderController.setClearSectionEnabled( - mHasSilentEntries | mHasMinimizedEntries); + private class MinimizedNotifSectioner extends NotifSectioner { + + MinimizedNotifSectioner() { + super("Minimized", NotificationPriorityBucketKt.BUCKET_SILENT); } - }; - private final NotifSectioner mMinimizedNotifSectioner = new NotifSectioner("Minimized", - NotificationPriorityBucketKt.BUCKET_SILENT) { @Override public boolean isInSection(ListEntry entry) { return !mHighPriorityProvider.isHighPriority(entry) @@ -155,51 +180,5 @@ public class RankingCoordinator implements Coordinator { public NodeController getHeaderNodeController() { return mSilentNodeController; } - - @Nullable - @Override - public void onEntriesUpdated(@NonNull List<ListEntry> entries) { - mHasMinimizedEntries = false; - for (int i = 0; i < entries.size(); i++) { - if (entries.get(i).getRepresentativeEntry().getSbn().isClearable()) { - mHasMinimizedEntries = true; - break; - } - } - mSilentHeaderController.setClearSectionEnabled( - mHasSilentEntries | mHasMinimizedEntries); - } - }; - - /** - * Checks whether to filter out the given notification based the notification's Ranking object. - * NotifListBuilder invalidates the notification list each time the ranking is updated, - * so we don't need to explicitly invalidate this filter on ranking update. - */ - private final NotifFilter mSuspendedFilter = new NotifFilter("IsSuspendedFilter") { - @Override - public boolean shouldFilterOut(NotificationEntry entry, long now) { - return entry.getRanking().isSuspended(); - } - }; - - private final NotifFilter mDndVisualEffectsFilter = new NotifFilter( - "DndSuppressingVisualEffects") { - @Override - public boolean shouldFilterOut(NotificationEntry entry, long now) { - if (mStatusBarStateController.isDozing() && entry.shouldSuppressAmbient()) { - return true; - } - - return !mStatusBarStateController.isDozing() && entry.shouldSuppressNotificationList(); - } - }; - - private final StatusBarStateController.StateListener mStatusBarStateCallback = - new StatusBarStateController.StateListener() { - @Override - public void onDozingChanged(boolean isDozing) { - mDndVisualEffectsFilter.invalidateList(); - } - }; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt deleted file mode 100644 index 3f8a39f62dfb..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.notification.collection.coordinator - -import android.os.UserHandle -import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.plugins.statusbar.StatusBarStateController -import com.android.systemui.statusbar.NotificationLockscreenUserManager -import com.android.systemui.statusbar.StatusBarState -import com.android.systemui.statusbar.notification.DynamicPrivacyController -import com.android.systemui.statusbar.notification.collection.GroupEntry -import com.android.systemui.statusbar.notification.collection.ListEntry -import com.android.systemui.statusbar.notification.collection.NotifPipeline -import com.android.systemui.statusbar.notification.collection.NotificationEntry -import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope -import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener -import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator -import com.android.systemui.statusbar.policy.KeyguardStateController -import dagger.Binds -import dagger.Module -import javax.inject.Inject - -@Module(includes = [PrivateSensitiveContentCoordinatorModule::class]) -interface SensitiveContentCoordinatorModule - -@Module -private interface PrivateSensitiveContentCoordinatorModule { - @Binds - fun bindCoordinator(impl: SensitiveContentCoordinatorImpl): SensitiveContentCoordinator -} - -/** Coordinates re-inflation and post-processing of sensitive notification content. */ -interface SensitiveContentCoordinator : Coordinator - -@CoordinatorScope -private class SensitiveContentCoordinatorImpl @Inject constructor( - private val dynamicPrivacyController: DynamicPrivacyController, - private val lockscreenUserManager: NotificationLockscreenUserManager, - private val keyguardUpdateMonitor: KeyguardUpdateMonitor, - private val statusBarStateController: StatusBarStateController, - private val keyguardStateController: KeyguardStateController -) : Invalidator("SensitiveContentInvalidator"), - SensitiveContentCoordinator, - DynamicPrivacyController.Listener, - OnBeforeRenderListListener { - - override fun attach(pipeline: NotifPipeline) { - dynamicPrivacyController.addListener(this) - pipeline.addOnBeforeRenderListListener(this) - pipeline.addPreRenderInvalidator(this) - } - - override fun onDynamicPrivacyChanged(): Unit = invalidateList() - - override fun onBeforeRenderList(entries: List<ListEntry>) { - if (keyguardStateController.isKeyguardGoingAway() || - statusBarStateController.getState() == StatusBarState.KEYGUARD && - keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing( - KeyguardUpdateMonitor.getCurrentUser())) { - // don't update yet if: - // - the keyguard is currently going away - // - LS is about to be dismissed by a biometric that bypasses LS (avoid notif flash) - - // TODO(b/206118999): merge this class with KeyguardCoordinator which ensures the - // dependent state changes invalidate the pipeline - return - } - - val currentUserId = lockscreenUserManager.currentUserId - val devicePublic = lockscreenUserManager.isLockscreenPublicMode(currentUserId) - val deviceSensitive = devicePublic && - !lockscreenUserManager.userAllowsPrivateNotificationsInPublic(currentUserId) - val dynamicallyUnlocked = dynamicPrivacyController.isDynamicallyUnlocked - for (entry in extractAllRepresentativeEntries(entries).filter { it.rowExists() }) { - val notifUserId = entry.sbn.user.identifier - val userLockscreen = devicePublic || - lockscreenUserManager.isLockscreenPublicMode(notifUserId) - val userPublic = when { - // if we're not on the lockscreen, we're definitely private - !userLockscreen -> false - // we are on the lockscreen, so unless we're dynamically unlocked, we're - // definitely public - !dynamicallyUnlocked -> true - // we're dynamically unlocked, but check if the notification needs - // a separate challenge if it's from a work profile - else -> when (notifUserId) { - currentUserId -> false - UserHandle.USER_ALL -> false - else -> lockscreenUserManager.needsSeparateWorkChallenge(notifUserId) - } - } - val needsRedaction = lockscreenUserManager.needsRedaction(entry) - val isSensitive = userPublic && needsRedaction - entry.setSensitive(isSensitive, deviceSensitive) - } - } -} - -private fun extractAllRepresentativeEntries( - entries: List<ListEntry> -): Sequence<NotificationEntry> = - entries.asSequence().flatMap(::extractAllRepresentativeEntries) - -private fun extractAllRepresentativeEntries(listEntry: ListEntry): Sequence<NotificationEntry> = - sequence { - listEntry.representativeEntry?.let { yield(it) } - if (listEntry is GroupEntry) { - yieldAll(extractAllRepresentativeEntries(listEntry.children)) - } - } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt index 1c96e8ceb27f..2374e9c58177 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt @@ -50,6 +50,8 @@ class StackCoordinator @Inject internal constructor( var hasClearableAlertingNotifs = false var hasNonClearableSilentNotifs = false var hasClearableSilentNotifs = false + val clearableAlertingSensitiveNotifUsers = mutableSetOf<Int>() + val clearableSilentSensitiveNotifUsers = mutableSetOf<Int>() entries.forEach { val section = checkNotNull(it.section) { "Null section for ${it.key}" } val entry = checkNotNull(it.representativeEntry) { "Null notif entry for ${it.key}" } @@ -63,13 +65,22 @@ class StackCoordinator @Inject internal constructor( !isSilent && isClearable -> hasClearableAlertingNotifs = true !isSilent && !isClearable -> hasNonClearableAlertingNotifs = true } + if (isClearable && entry.hasSensitiveContents()) { + if (isSilent) { + clearableSilentSensitiveNotifUsers.add(entry.sbn.userId) + } else { + clearableAlertingSensitiveNotifUsers.add(entry.sbn.userId) + } + } } return NotifStats( numActiveNotifs = entries.size, hasNonClearableAlertingNotifs = hasNonClearableAlertingNotifs, hasClearableAlertingNotifs = hasClearableAlertingNotifs, hasNonClearableSilentNotifs = hasNonClearableSilentNotifs, - hasClearableSilentNotifs = hasClearableSilentNotifs + hasClearableSilentNotifs = hasClearableSilentNotifs, + clearableAlertingSensitiveNotifUsers = clearableAlertingSensitiveNotifUsers, + clearableSilentSensitiveNotifUsers = clearableSilentSensitiveNotifUsers ) } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt index 274affd9da43..8ecffcb7670a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt @@ -20,7 +20,6 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.collection.coordinator.ActivityLaunchAnimCoordinatorModule import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinatorsImpl -import com.android.systemui.statusbar.notification.collection.coordinator.SensitiveContentCoordinatorModule import dagger.Binds import dagger.Module import dagger.Provides @@ -50,7 +49,6 @@ interface CoordinatorsSubcomponent { @Module(includes = [ ActivityLaunchAnimCoordinatorModule::class, - SensitiveContentCoordinatorModule::class, ]) private abstract class InternalCoordinatorsModule { @Binds diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java index 4c7b2bbfb6d9..6e96aad776d2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.notification.collection.inflation; +import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC; + import static java.util.Objects.requireNonNull; import android.annotation.Nullable; @@ -249,10 +251,13 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { RowContentBindParams params = mRowContentBindStage.getStageParams(entry); params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight); params.setUseLowPriority(isLowPriority); - - // TODO: Replace this API with RowContentBindParams directly. Also move to a separate - // redaction controller. - row.setNeedsRedaction(mNotificationLockscreenUserManager.needsRedaction(entry)); + boolean needsRedaction = + mNotificationLockscreenUserManager.notifNeedsRedactionInPublic(entry); + if (needsRedaction) { + params.requireContentViews(FLAG_CONTENT_VIEW_PUBLIC); + } else { + params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC); + } params.rebindAllContentViews(); mRowContentBindStage.requestRebind(entry, en -> { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifStackController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifStackController.kt index b6278d1d5f01..580d853dc5e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifStackController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifStackController.kt @@ -28,11 +28,21 @@ data class NotifStats( val hasNonClearableAlertingNotifs: Boolean, val hasClearableAlertingNotifs: Boolean, val hasNonClearableSilentNotifs: Boolean, - val hasClearableSilentNotifs: Boolean + val hasClearableSilentNotifs: Boolean, + val clearableAlertingSensitiveNotifUsers: Set<Int>, + val clearableSilentSensitiveNotifUsers: Set<Int> ) { companion object { @JvmStatic - val empty = NotifStats(0, false, false, false, false) + val empty = NotifStats( + numActiveNotifs = 0, + hasNonClearableAlertingNotifs = false, + hasClearableAlertingNotifs = false, + hasNonClearableSilentNotifs = false, + hasClearableSilentNotifs = false, + clearableAlertingSensitiveNotifUsers = emptySet(), + clearableSilentSensitiveNotifUsers = emptySet(), + ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt index 2a9cfd034dce..f58918fe6f80 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt @@ -182,4 +182,4 @@ annotation class HeaderClickAction @Scope @Retention(AnnotationRetention.BINARY) -annotation class SectionHeaderScope
\ No newline at end of file +annotation class SectionHeaderScope diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt index d8965418b4c4..015e3d8cd553 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt @@ -28,6 +28,7 @@ import android.widget.ImageView import com.android.internal.statusbar.StatusBarIcon import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.StatusBarIconView import com.android.systemui.statusbar.notification.InflationException import com.android.systemui.statusbar.notification.collection.NotificationEntry @@ -49,31 +50,29 @@ import javax.inject.Inject class IconManager @Inject constructor( private val notifCollection: CommonNotifCollection, private val launcherApps: LauncherApps, - private val iconBuilder: IconBuilder + private val iconBuilder: IconBuilder, + private val notifLockscreenUserManager: NotificationLockscreenUserManager ) : ConversationIconManager { private var unimportantConversationKeys: Set<String> = emptySet() fun attach() { notifCollection.addCollectionListener(entryListener) + notifLockscreenUserManager.addOnNeedsRedactionInPublicChangedListener(sensitivityListener) } private val entryListener = object : NotifCollectionListener { - override fun onEntryInit(entry: NotificationEntry) { - entry.addOnSensitivityChangedListener(sensitivityListener) - } - - override fun onEntryCleanUp(entry: NotificationEntry) { - entry.removeOnSensitivityChangedListener(sensitivityListener) - } - override fun onRankingApplied() { // rankings affect whether a conversation is important, which can change the icons recalculateForImportantConversationChange() } } - private val sensitivityListener = NotificationEntry.OnSensitivityChangedListener { - entry -> updateIconsSafe(entry) + private val sensitivityListener = Runnable { + for (entry in notifCollection.allNotifs) { + if (entry.hasSensitiveContents()) { + updateIconsSafe(entry) + } + } } private fun recalculateForImportantConversationChange() { @@ -182,12 +181,16 @@ class IconManager @Inject constructor( } } + private inline val NotificationEntry.needsRedactionInPublic: Boolean get() = + hasSensitiveContents() && + notifLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(sbn.userId) + @Throws(InflationException::class) private fun getIconDescriptors( entry: NotificationEntry ): Pair<StatusBarIcon, StatusBarIcon> { val iconDescriptor = getIconDescriptor(entry, false /* redact */) - val sensitiveDescriptor = if (entry.isSensitive) { + val sensitiveDescriptor = if (entry.needsRedactionInPublic) { getIconDescriptor(entry, true /* redact */) } else { iconDescriptor @@ -310,7 +313,7 @@ class IconManager @Inject constructor( iconView === entry.icons.shelfIcon || iconView === entry.icons.aodIcon val isSmallIcon = iconDescriptor.icon.equals(entry.sbn.notification.smallIcon) return isImportantConversation(entry) && !isSmallIcon && - (!usedInSensitiveContext || !entry.isSensitive) + (!usedInSensitiveContext || !entry.needsRedactionInPublic) } private fun isImportantConversation(entry: NotificationEntry): Boolean { @@ -338,4 +341,4 @@ interface ConversationIconManager { * of a group from which the priority notification has been removed. */ fun setUnimportantConversations(keys: Collection<String>) -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt index 6b79680fdb26..f0b221dd4726 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt @@ -160,8 +160,7 @@ class ChannelEditorDialogController @Inject constructor( val channels = groupList .flatMap { group -> group.channels.asSequence().filterNot { channel -> - channel.isImportanceLockedByOEM || - channel.importance == IMPORTANCE_NONE || + channel.importance == IMPORTANCE_NONE || channel.isImportanceLockedByCriticalDeviceFunction } } 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 0ae365352df0..ed69e0609096 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 @@ -93,8 +93,8 @@ import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.notification.AboveShelfChangedListener; -import com.android.systemui.statusbar.notification.LaunchAnimationParameters; import com.android.systemui.statusbar.notification.FeedbackIcon; +import com.android.systemui.statusbar.notification.LaunchAnimationParameters; import com.android.systemui.statusbar.notification.NotificationFadeAware; import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController; import com.android.systemui.statusbar.notification.NotificationUtils; @@ -206,7 +206,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView /** Are we showing the "public" version */ private boolean mShowingPublic; private boolean mSensitive; - private boolean mSensitiveHiddenInGeneral; private boolean mShowingPublicInitialized; private boolean mHideSensitiveForIntrinsicHeight; private float mHeaderVisibleAmount = DEFAULT_HEADER_VISIBLE_AMOUNT; @@ -376,44 +375,24 @@ public class ExpandableNotificationRow extends ActivatableNotificationView * calls. */ private static Boolean isSystemNotification(Context context, StatusBarNotification sbn) { - // TODO (b/194833441): clean up before launch - if (Settings.Secure.getIntForUser(context.getContentResolver(), - Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 0, USER_SYSTEM) == 1) { - INotificationManager iNm = INotificationManager.Stub.asInterface( - ServiceManager.getService(Context.NOTIFICATION_SERVICE)); - - boolean isSystem = false; - try { - isSystem = iNm.isPermissionFixed(sbn.getPackageName(), sbn.getUserId()); - } catch (RemoteException e) { - Log.e(TAG, "cannot reach NMS"); - } - RoleManager rm = context.getSystemService(RoleManager.class); - List<String> fixedRoleHolders = new ArrayList<>(); - fixedRoleHolders.addAll(rm.getRoleHolders(RoleManager.ROLE_DIALER)); - fixedRoleHolders.addAll(rm.getRoleHolders(RoleManager.ROLE_EMERGENCY)); - if (fixedRoleHolders.contains(sbn.getPackageName())) { - isSystem = true; - } - - return isSystem; - } else { - PackageManager packageManager = CentralSurfaces.getPackageManagerForUser( - context, sbn.getUser().getIdentifier()); - Boolean isSystemNotification = null; + INotificationManager iNm = INotificationManager.Stub.asInterface( + ServiceManager.getService(Context.NOTIFICATION_SERVICE)); - try { - PackageInfo packageInfo = packageManager.getPackageInfo( - sbn.getPackageName(), PackageManager.GET_SIGNATURES); - - isSystemNotification = - com.android.settingslib.Utils.isSystemPackage( - context.getResources(), packageManager, packageInfo); - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "cacheIsSystemNotification: Could not find package info"); - } - return isSystemNotification; + boolean isSystem = false; + try { + isSystem = iNm.isPermissionFixed(sbn.getPackageName(), sbn.getUserId()); + } catch (RemoteException e) { + Log.e(TAG, "cannot reach NMS"); } + RoleManager rm = context.getSystemService(RoleManager.class); + List<String> fixedRoleHolders = new ArrayList<>(); + fixedRoleHolders.addAll(rm.getRoleHolders(RoleManager.ROLE_DIALER)); + fixedRoleHolders.addAll(rm.getRoleHolders(RoleManager.ROLE_EMERGENCY)); + if (fixedRoleHolders.contains(sbn.getPackageName())) { + isSystem = true; + } + + return isSystem; } public NotificationContentView[] getLayouts() { @@ -567,9 +546,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mEntry.mIsSystemNotification = isSystemNotification(mContext, mEntry.getSbn()); } - // TODO (b/194833441): remove when we've migrated to permission - boolean isNonblockable = mEntry.getChannel().isImportanceLockedByOEM() - || mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction(); + boolean isNonblockable = mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction(); if (!isNonblockable && mEntry != null && mEntry.mIsSystemNotification != null) { if (mEntry.mIsSystemNotification) { @@ -1560,6 +1537,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mUseIncreasedHeadsUpHeight = use; } + // TODO: remove this method and mNeedsRedaction entirely once the old pipeline is gone public void setNeedsRedaction(boolean needsRedaction) { // TODO: Move inflation logic out of this call and remove this method if (mNeedsRedaction != needsRedaction) { @@ -2644,9 +2622,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView getShowingLayout().requestSelectLayout(needsAnimation || isUserLocked()); } - public void setSensitive(boolean sensitive, boolean hideSensitive) { + public void setSensitive(boolean sensitive) { mSensitive = sensitive; - mSensitiveHiddenInGeneral = hideSensitive; } @Override @@ -2736,7 +2713,15 @@ public class ExpandableNotificationRow extends ActivatableNotificationView * see {@link NotificationEntry#isDismissable()}. */ public boolean canViewBeDismissed() { - return mEntry.isDismissable() && (!shouldShowPublic() || !mSensitiveHiddenInGeneral); + // Entry not dismissable. + if (!mEntry.isDismissable()) { + return false; + } + // Entry shouldn't be showing the public layout, it can be dismissed. + if (!shouldShowPublic()) { + return true; + } + return false; } /** @@ -2745,7 +2730,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView * clearability see {@link NotificationEntry#isClearable()}. */ public boolean canViewBeCleared() { - return mEntry.isClearable() && (!shouldShowPublic() || !mSensitiveHiddenInGeneral); + return mEntry.isClearable() && !shouldShowPublic(); } private boolean shouldShowPublic() { @@ -3509,10 +3494,28 @@ public class ExpandableNotificationRow extends ActivatableNotificationView pw.print(", translation: " + getTranslation()); pw.print(", removed: " + isRemoved()); pw.print(", expandAnimationRunning: " + mExpandAnimationRunning); - NotificationContentView showingLayout = getShowingLayout(); - pw.print(", privateShowing: " + (showingLayout == mPrivateLayout)); - pw.println(); - showingLayout.dump(pw, args); + pw.print(", sensitive: " + mSensitive); + pw.print(", hideSensitiveForIntrinsicHeight: " + mHideSensitiveForIntrinsicHeight); + pw.println(", privateShowing: " + !shouldShowPublic()); + pw.print("privateLayout: "); + if (mPrivateLayout != null) { + pw.println(); + DumpUtilsKt.withIncreasedIndent(pw, () -> { + mPrivateLayout.dump(pw, args); + mPrivateLayout.dumpSmartReplies(pw); + }); + } else { + pw.println("null"); + } + pw.print("publicLayout: "); + if (mPublicLayout != null) { + pw.println(); + DumpUtilsKt.withIncreasedIndent(pw, () -> { + mPublicLayout.dump(pw, args); + }); + } else { + pw.println("null"); + } if (getViewState() != null) { getViewState().dump(pw, args); @@ -3538,8 +3541,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } pw.decreaseIndent(); pw.println("}"); - } else if (mPrivateLayout != null) { - mPrivateLayout.dumpSmartReplies(pw); } }); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index 599039d46556..a60026c7a97b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -35,6 +35,7 @@ import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.plugins.PluginManager; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.notification.FeedbackIcon; @@ -69,6 +70,7 @@ import javax.inject.Named; public class ExpandableNotificationRowController implements NotifViewController { private static final String TAG = "NotifRowController"; private final ExpandableNotificationRow mView; + private final NotificationLockscreenUserManager mLockscreenUserManager; private final NotificationListContainer mListContainer; private final RemoteInputViewSubcomponent.Factory mRemoteInputViewSubcomponentFactory; private final ActivatableNotificationViewController mActivatableNotificationViewController; @@ -86,7 +88,6 @@ public class ExpandableNotificationRowController implements NotifViewController private final ExpandableNotificationRow.OnExpandClickListener mOnExpandClickListener; private final StatusBarStateController mStatusBarStateController; private final MetricsLogger mMetricsLogger; - private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger = this::logNotificationExpansion; private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener; @@ -100,12 +101,12 @@ public class ExpandableNotificationRowController implements NotifViewController private final Optional<BubblesManager> mBubblesManagerOptional; private final SmartReplyConstants mSmartReplyConstants; private final SmartReplyController mSmartReplyController; - private final ExpandableNotificationRowDragController mDragController; @Inject public ExpandableNotificationRowController( ExpandableNotificationRow view, + NotificationLockscreenUserManager lockscreenUserManager, ActivatableNotificationViewController activatableNotificationViewController, RemoteInputViewSubcomponent.Factory rivSubcomponentFactory, MetricsLogger metricsLogger, @@ -135,6 +136,7 @@ public class ExpandableNotificationRowController implements NotifViewController Optional<BubblesManager> bubblesManagerOptional, ExpandableNotificationRowDragController dragController) { mView = view; + mLockscreenUserManager = lockscreenUserManager; mListContainer = listContainer; mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory; mActivatableNotificationViewController = activatableNotificationViewController; @@ -214,6 +216,10 @@ public class ExpandableNotificationRowController implements NotifViewController mView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); } + mLockscreenUserManager + .addOnNeedsRedactionInPublicChangedListener(mNeedsRedactionListener); + mNeedsRedactionListener.run(); + mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) { @@ -232,6 +238,14 @@ public class ExpandableNotificationRowController implements NotifViewController }); } + private final Runnable mNeedsRedactionListener = new Runnable() { + @Override + public void run() { + mView.setSensitive( + mLockscreenUserManager.notifNeedsRedactionInPublic(mView.getEntry())); + } + }; + private final StatusBarStateController.StateListener mStatusBarStateListener = new StatusBarStateController.StateListener() { @Override @@ -333,4 +347,5 @@ public class ExpandableNotificationRowController implements NotifViewController public void setFeedbackIcon(@Nullable FeedbackIcon icon) { mView.setFeedbackIcon(icon); } + } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index ba26cfaa30b4..a7c6bfb0289c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -61,6 +61,7 @@ import com.android.systemui.statusbar.policy.SmartReplyStateInflaterKt; import com.android.systemui.statusbar.policy.SmartReplyView; import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent; import com.android.systemui.util.Compile; +import com.android.systemui.util.DumpUtilsKt; import com.android.systemui.wmshell.BubblesManager; import java.io.PrintWriter; @@ -1994,22 +1995,33 @@ public class NotificationContentView extends FrameLayout implements Notification } } - public void dump(PrintWriter pw, String[] args) { + public void dump(PrintWriter pwOriginal, String[] args) { + IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal); pw.print("contentView visibility: " + getVisibility()); pw.print(", alpha: " + getAlpha()); pw.print(", clipBounds: " + getClipBounds()); pw.print(", contentHeight: " + mContentHeight); - pw.print(", visibleType: " + mVisibleType); - View view = getViewForVisibleType(mVisibleType); - pw.print(", visibleView "); - if (view != null) { - pw.print(" visibility: " + view.getVisibility()); - pw.print(", alpha: " + view.getAlpha()); - pw.print(", clipBounds: " + view.getClipBounds()); - } else { - pw.print("null"); - } - pw.println(); + pw.println(", currentVisibleType: " + mVisibleType); + DumpUtilsKt.withIncreasedIndent(pw, () -> { + int[] visTypes = { + VISIBLE_TYPE_CONTRACTED, + VISIBLE_TYPE_EXPANDED, + VISIBLE_TYPE_HEADSUP, + VISIBLE_TYPE_SINGLELINE + }; + for (int visType : visTypes) { + pw.print("visType: " + visType + " :: "); + View view = getViewForVisibleType(visType); + if (view != null) { + pw.print("visibility: " + view.getVisibility()); + pw.print(", alpha: " + view.getAlpha()); + pw.print(", clipBounds: " + view.getClipBounds()); + } else { + pw.print("null"); + } + pw.println(); + } + }); } /** Add any existing SmartReplyView to the dump */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java index f26ecc32821d..a52f638e7c26 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java @@ -102,8 +102,9 @@ public final class RowContentBindParams { * @see InflationFlag */ public void markContentViewsFreeable(@InflationFlag int contentViews) { + @InflationFlag int existingContentViews = contentViews &= mContentViews; mContentViews &= ~contentViews; - mDirtyContentViews &= ~contentViews; + mDirtyContentViews |= existingContentViews; } public @InflationFlag int getContentViews() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 3ea5e5b753a3..24369e7b860f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -5517,6 +5517,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable */ public void setFractionToShade(float fraction) { mAmbientState.setFractionToShade(fraction); + updateContentHeight(); // Recompute stack height with different section gap. requestChildrenUpdate(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 2493ccbe5a48..6a8f4796813a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -216,6 +216,9 @@ public class NotificationStackScrollLayoutController { mBarState = mStatusBarStateController.getState(); mStatusBarStateController.addCallback( mStateListener, SysuiStatusBarStateController.RANK_STACK_SCROLLER); + mLockscreenUserManager.addOnNeedsRedactionInPublicChangedListener( + mOnNeedsRedactionInPublicChangedListener); + updateClearButtonVisibility(); } @Override @@ -223,6 +226,8 @@ public class NotificationStackScrollLayoutController { mConfigurationController.removeCallback(mConfigurationListener); mZenModeController.removeCallback(mZenModeControllerCallback); mStatusBarStateController.removeCallback(mStateListener); + mLockscreenUserManager.removeOnNeedsRedactionInPublicChangedListener( + mOnNeedsRedactionInPublicChangedListener); } }; @@ -326,6 +331,7 @@ public class NotificationStackScrollLayoutController { mLockscreenUserManager.isAnyProfilePublicMode()); mView.onStatePostChange(mStatusBarStateController.fromShadeLocked()); mNotificationEntryManager.updateNotifications("CentralSurfaces state changed"); + updateClearButtonVisibility(); } }; @@ -338,6 +344,17 @@ public class NotificationStackScrollLayoutController { } }; + private final Runnable mOnNeedsRedactionInPublicChangedListener = new Runnable() { + @Override + public void run() { + // Whether or not the notification needs redaction when in public has changed, but if + // we're not actually in public, then we don't need to update anything. + if (mLockscreenUserManager.isAnyProfilePublicMode()) { + updateClearButtonVisibility(); + } + } + }; + /** * Set the overexpansion of the panel to be applied to the view. */ @@ -1274,12 +1291,44 @@ public class NotificationStackScrollLayoutController { return hasNotifications(selection, true /* clearable */); } + private boolean hasRedactedClearableSilentNotifs() { + if (!mLockscreenUserManager.isAnyProfilePublicMode()) { + return false; + } + for (int userId : mNotifStats.getClearableSilentSensitiveNotifUsers()) { + if (mLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(userId)) { + return true; + } + } + return false; + } + + private boolean hasClearableSilentNotifs() { + return mNotifStats.getHasClearableSilentNotifs() && !hasRedactedClearableSilentNotifs(); + } + + private boolean hasRedactedClearableAlertingNotifs() { + if (!mLockscreenUserManager.isAnyProfilePublicMode()) { + return false; + } + for (int userId : mNotifStats.getClearableAlertingSensitiveNotifUsers()) { + if (mLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(userId)) { + return true; + } + } + return false; + } + + private boolean hasClearableAlertingNotifs() { + return mNotifStats.getHasClearableAlertingNotifs() && !hasRedactedClearableAlertingNotifs(); + } + public boolean hasNotifications(@SelectedRows int selection, boolean isClearable) { boolean hasAlertingMatchingClearable = isClearable - ? mNotifStats.getHasClearableAlertingNotifs() + ? hasClearableAlertingNotifs() : mNotifStats.getHasNonClearableAlertingNotifs(); boolean hasSilentMatchingClearable = isClearable - ? mNotifStats.getHasClearableSilentNotifs() + ? hasClearableSilentNotifs() : mNotifStats.getHasNonClearableSilentNotifs(); switch (selection) { case ROWS_GENTLE: @@ -1579,6 +1628,15 @@ public class NotificationStackScrollLayoutController { mNotificationActivityStarter = activityStarter; } + private void updateClearButtonVisibility() { + updateClearSilentButton(); + updateFooter(); + } + + private void updateClearSilentButton() { + mSilentHeaderController.setClearSectionEnabled(hasClearableSilentNotifs()); + } + /** * Enum for UiEvent logged from this class */ @@ -1904,6 +1962,7 @@ public class NotificationStackScrollLayoutController { @Override public void setNotifStats(@NonNull NotifStats notifStats) { mNotifStats = notifStats; + updateClearSilentButton(); updateFooter(); updateShowEmptyShadeView(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 2b79986662f1..799fee5e865d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -49,9 +49,10 @@ public class StackScrollAlgorithm { public static final float START_FRACTION = 0.5f; - private static final String LOG_TAG = "StackScrollAlgorithm"; - private final ViewGroup mHostView; + private static final String TAG = "StackScrollAlgorithm"; + private static final Boolean DEBUG = false; + private final ViewGroup mHostView; private int mPaddingBetweenElements; private int mGapHeight; private int mGapHeightOnLockscreen; @@ -126,6 +127,37 @@ public class StackScrollAlgorithm { return getExpansionFractionWithoutShelf(mTempAlgorithmState, ambientState); } + private void log(String s) { + if (DEBUG) { + android.util.Log.i(TAG, s); + } + } + + public void logView(View view, String s) { + String viewString = ""; + if (view instanceof ExpandableNotificationRow) { + ExpandableNotificationRow row = ((ExpandableNotificationRow) view); + if (row.getEntry() == null) { + viewString = "ExpandableNotificationRow has null NotificationEntry"; + } else { + viewString = row.getEntry().getSbn().getId() + ""; + } + } else if (view == null) { + viewString = "View is null"; + } else if (view instanceof SectionHeaderView) { + viewString = "SectionHeaderView"; + } else if (view instanceof FooterView) { + viewString = "FooterView"; + } else if (view instanceof MediaContainerView) { + viewString = "MediaContainerView"; + } else if (view instanceof EmptyShadeView) { + viewString = "EmptyShadeView"; + } else { + viewString = view.toString(); + } + log(viewString + " " + s); + } + private void resetChildViewStates() { int numChildren = mHostView.getChildCount(); for (int i = 0; i < numChildren; i++) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java index 9863a0ed1ce0..f386797e322a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -29,6 +29,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.HeadsUpStatusBarView; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -40,8 +41,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.util.ViewController; -import java.util.Optional; import java.util.ArrayList; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -61,17 +62,17 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar private final NotificationIconAreaController mNotificationIconAreaController; private final HeadsUpManagerPhone mHeadsUpManager; private final NotificationStackScrollLayoutController mStackScrollerController; - private final DarkIconDispatcher mDarkIconDispatcher; private final NotificationPanelViewController mNotificationPanelViewController; - private final Consumer<ExpandableNotificationRow> - mSetTrackingHeadsUp = this::setTrackingHeadsUp; + private final Consumer<ExpandableNotificationRow> mSetTrackingHeadsUp = + this::setTrackingHeadsUp; private final BiConsumer<Float, Float> mSetExpandedHeight = this::setAppearFraction; private final KeyguardBypassController mBypassController; private final StatusBarStateController mStatusBarStateController; private final CommandQueue mCommandQueue; private final NotificationWakeUpCoordinator mWakeUpCoordinator; - + private final NotificationLockscreenUserManager mNotifLockscreenUserManager; + private final Runnable mRedactionChanged = this::updateRedaction; private final View mClockView; private final Optional<View> mOperatorNameViewOptional; @@ -90,6 +91,13 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar }; private boolean mAnimationsEnabled = true; private final KeyguardStateController mKeyguardStateController; + private final StatusBarStateController.StateListener mStatusBarStateListener = + new StatusBarStateController.StateListener() { + @Override + public void onStatePostChange() { + updateRedaction(); + } + }; @VisibleForTesting @Inject @@ -98,6 +106,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar HeadsUpManagerPhone headsUpManager, StatusBarStateController stateController, KeyguardBypassController bypassController, + NotificationLockscreenUserManager notifLockscreenUserManager, NotificationWakeUpCoordinator wakeUpCoordinator, DarkIconDispatcher darkIconDispatcher, KeyguardStateController keyguardStateController, @@ -125,6 +134,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar mClockView = clockView; mOperatorNameViewOptional = operatorNameViewOptional; mDarkIconDispatcher = darkIconDispatcher; + mNotifLockscreenUserManager = notifLockscreenUserManager; mView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override @@ -156,6 +166,8 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar mNotificationPanelViewController.setHeadsUpAppearanceController(this); mStackScrollerController.addOnExpandedHeightChangedListener(mSetExpandedHeight); mDarkIconDispatcher.addDarkReceiver(this); + mNotifLockscreenUserManager.addOnNeedsRedactionInPublicChangedListener(mRedactionChanged); + mStatusBarStateController.addCallback(mStatusBarStateListener); } @Override @@ -167,6 +179,9 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar mNotificationPanelViewController.setHeadsUpAppearanceController(null); mStackScrollerController.removeOnExpandedHeightChangedListener(mSetExpandedHeight); mDarkIconDispatcher.removeDarkReceiver(this); + mNotifLockscreenUserManager + .removeOnNeedsRedactionInPublicChangedListener(mRedactionChanged); + mStatusBarStateController.removeCallback(mStatusBarStateListener); } private void updateIsolatedIconLocation(boolean requireStateUpdate) { @@ -180,6 +195,19 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar updateHeader(entry); } + private void updateRedaction() { + NotificationEntry showingEntry = mView.getShowingEntry(); + if (showingEntry == null) { + return; + } + int notifUserId = showingEntry.getSbn().getUserId(); + boolean redactSensitiveContent = + mNotifLockscreenUserManager.isLockscreenPublicMode(notifUserId) + && mNotifLockscreenUserManager + .sensitiveNotifsNeedRedactionInPublic(notifUserId); + mView.setRedactSensitiveContent(redactSensitiveContent); + } + private void updateTopEntry() { NotificationEntry newEntry = null; if (shouldBeVisible()) { 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 74b9c71d2198..f15ea627af47 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -32,7 +32,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.StatusBarState.SHADE; -import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL; import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD; import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED; import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPEN; @@ -1690,7 +1689,17 @@ public class NotificationPanelViewController extends PanelViewController { mQsExpandImmediate = true; setShowShelfOnly(true); } - if (isFullyCollapsed()) { + if (mShouldUseSplitNotificationShade && isOnKeyguard()) { + // It's a special case as this method is likely to not be initiated by finger movement + // but rather called from adb shell or accessibility service. + // We're using LockscreenShadeTransitionController because on lockscreen that's the + // source of truth for all shade motion. Not using it would make part of state to be + // outdated and will cause bugs. Ideally we'd use this controller also for non-split + // case but currently motion in portrait looks worse than when using flingSettings. + // TODO: make below function transitioning smoothly also in portrait with null target + mLockscreenShadeTransitionController.goToLockedShade( + /* expandedView= */null, /* needsQSAnimation= */false); + } else if (isFullyCollapsed()) { expand(true /* animate */); } else { traceQsJank(true /* startTracing */, false /* wasCancelled */); @@ -2355,9 +2364,12 @@ public class NotificationPanelViewController extends PanelViewController { mScrimController.setQsPosition(qsExpansionFraction, qsPanelBottomY); setQSClippingBounds(); - // Only need to notify the notification stack when we're not in split screen mode. If we - // do, then the notification panel starts scrolling along with the QS. - if (!mShouldUseSplitNotificationShade) { + if (mShouldUseSplitNotificationShade) { + // In split shade we want to pretend that QS are always collapsed so their behaviour and + // interactions don't influence notifications as they do in portrait. But we want to set + // 0 explicitly in case we're rotating from non-split shade with QS expansion of 1. + mNotificationStackScrollLayoutController.setQsExpansionFraction(0); + } else { mNotificationStackScrollLayoutController.setQsExpansionFraction(qsExpansionFraction); } @@ -3210,6 +3222,8 @@ public class NotificationPanelViewController extends PanelViewController { updateTrackingHeadsUp(null); mExpandingFromHeadsUp = false; setPanelScrimMinFraction(0.0f); + // Reset status bar alpha so alpha can be calculated upon updating view state. + setKeyguardStatusBarAlpha(-1f); } private void updateTrackingHeadsUp(@Nullable ExpandableNotificationRow pickedChild) { @@ -3929,10 +3943,6 @@ public class NotificationPanelViewController extends PanelViewController { } } - public boolean hasActiveClearableNotifications() { - return mNotificationStackScrollLayoutController.hasActiveClearableNotifications(ROWS_ALL); - } - public RemoteInputController.Delegate createRemoteInputDelegate() { return mNotificationStackScrollLayoutController.createDelegate(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index fb8397ba8f4f..7aeb08dd5ddb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -53,6 +53,8 @@ public class PhoneStatusBarView extends FrameLayout { private View mCutoutSpace; @Nullable private DisplayCutout mDisplayCutout; + @Nullable + private Rect mDisplaySize; private int mStatusBarHeight; @Nullable private TouchEventHandler mTouchEventHandler; @@ -87,7 +89,7 @@ public class PhoneStatusBarView extends FrameLayout { // Always have Battery meters in the status bar observe the dark/light modes. Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mBattery); Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mClock); - if (updateOrientationAndCutout()) { + if (updateDisplayParameters()) { updateLayoutForCutout(); } } @@ -106,7 +108,7 @@ public class PhoneStatusBarView extends FrameLayout { updateResources(); // May trigger cutout space layout-ing - if (updateOrientationAndCutout()) { + if (updateDisplayParameters()) { updateLayoutForCutout(); requestLayout(); } @@ -114,7 +116,7 @@ public class PhoneStatusBarView extends FrameLayout { @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { - if (updateOrientationAndCutout()) { + if (updateDisplayParameters()) { updateLayoutForCutout(); requestLayout(); } @@ -124,7 +126,7 @@ public class PhoneStatusBarView extends FrameLayout { /** * @return boolean indicating if we need to update the cutout location / margins */ - private boolean updateOrientationAndCutout() { + private boolean updateDisplayParameters() { boolean changed = false; int newRotation = RotationUtils.getExactRotation(mContext); if (newRotation != mRotationOrientation) { @@ -137,6 +139,13 @@ public class PhoneStatusBarView extends FrameLayout { mDisplayCutout = getRootWindowInsets().getDisplayCutout(); } + final Rect newSize = mContext.getResources().getConfiguration().windowConfiguration + .getMaxBounds(); + if (!Objects.equals(newSize, mDisplaySize)) { + changed = true; + mDisplaySize = newSize; + } + return changed; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt index 67de4e3b3c39..f5462bc0fba5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt @@ -38,6 +38,7 @@ import com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN import com.android.systemui.util.leak.RotationUtils.Rotation import com.android.systemui.util.leak.RotationUtils.getExactRotation import com.android.systemui.util.leak.RotationUtils.getResourcesForRotation +import com.android.systemui.util.traceSection import java.io.PrintWriter import java.lang.Math.max @@ -133,8 +134,10 @@ class StatusBarContentInsetsProvider @Inject constructor( * (i.e., ROTATION_NONE will always return the same bounds regardless of the context * from which this method is called) */ - fun getBoundingRectForPrivacyChipForRotation(@Rotation rotation: Int): Rect { - var insets = insetsCache[getCacheKey(rotation = rotation)] + fun getBoundingRectForPrivacyChipForRotation(@Rotation rotation: Int, + displayCutout: DisplayCutout?): Rect { + val key = getCacheKey(rotation, displayCutout) + var insets = insetsCache[key] if (insets == null) { insets = getStatusBarContentAreaForRotation(rotation) } @@ -156,20 +159,23 @@ class StatusBarContentInsetsProvider @Inject constructor( * * @param rotation the target rotation for which to calculate insets */ - fun getStatusBarContentInsetsForRotation(@Rotation rotation: Int): Pair<Int, Int> { - val key = getCacheKey(rotation) + fun getStatusBarContentInsetsForRotation(@Rotation rotation: Int): Pair<Int, Int> = + traceSection(tag = "StatusBarContentInsetsProvider.getStatusBarContentInsetsForRotation") { + val displayCutout = context.display.cutout + val key = getCacheKey(rotation, displayCutout) - val point = Point() - context.display.getRealSize(point) - // Target rotation can be a different orientation than the current device rotation - point.orientToRotZero(getExactRotation(context)) - val width = point.logicalWidth(rotation) + val screenBounds = context.resources.configuration.windowConfiguration.maxBounds + val point = Point(screenBounds.width(), screenBounds.height()) - val area = insetsCache[key] ?: getAndSetCalculatedAreaForRotation( - rotation, getResourcesForRotation(rotation, context), key) + // Target rotation can be a different orientation than the current device rotation + point.orientToRotZero(getExactRotation(context)) + val width = point.logicalWidth(rotation) - return Pair(area.left, width - area.right) - } + val area = insetsCache[key] ?: getAndSetCalculatedAreaForRotation( + rotation, displayCutout, getResourcesForRotation(rotation, context), key) + + Pair(area.left, width - area.right) + } /** * Calculate the left and right insets for the status bar content in the device's current @@ -192,9 +198,10 @@ class StatusBarContentInsetsProvider @Inject constructor( fun getStatusBarContentAreaForRotation( @Rotation rotation: Int ): Rect { - val key = getCacheKey(rotation) + val displayCutout = context.display.cutout + val key = getCacheKey(rotation, displayCutout) return insetsCache[key] ?: getAndSetCalculatedAreaForRotation( - rotation, getResourcesForRotation(rotation, context), key) + rotation, displayCutout, getResourcesForRotation(rotation, context), key) } /** @@ -207,20 +214,21 @@ class StatusBarContentInsetsProvider @Inject constructor( private fun getAndSetCalculatedAreaForRotation( @Rotation targetRotation: Int, + displayCutout: DisplayCutout?, rotatedResources: Resources, key: CacheKey ): Rect { - return getCalculatedAreaForRotation(targetRotation, rotatedResources) + return getCalculatedAreaForRotation(displayCutout, targetRotation, rotatedResources) .also { insetsCache.put(key, it) } } private fun getCalculatedAreaForRotation( + displayCutout: DisplayCutout?, @Rotation targetRotation: Int, rotatedResources: Resources ): Rect { - val dc = context.display.cutout val currentRotation = getExactRotation(context) val roundedCornerPadding = rotatedResources @@ -245,7 +253,7 @@ class StatusBarContentInsetsProvider @Inject constructor( return calculateInsetsForRotationWithRotatedResources( currentRotation, targetRotation, - dc, + displayCutout, context.resources.configuration.windowConfiguration.maxBounds, SystemBarUtils.getStatusBarHeightForRotation(context, targetRotation), minLeft, @@ -266,15 +274,19 @@ class StatusBarContentInsetsProvider @Inject constructor( pw.println(insetsCache) } - private fun getCacheKey(@Rotation rotation: Int): CacheKey = + private fun getCacheKey( + @Rotation rotation: Int, + displayCutout: DisplayCutout?): CacheKey = CacheKey( - uniqueDisplayId = context.display.uniqueId, - rotation = rotation + rotation = rotation, + displaySize = Rect(context.resources.configuration.windowConfiguration.maxBounds), + displayCutout = displayCutout ) private data class CacheKey( - val uniqueDisplayId: String, - @Rotation val rotation: Int + @Rotation val rotation: Int, + val displaySize: Rect, + val displayCutout: DisplayCutout? ) } @@ -369,7 +381,7 @@ fun calculateInsetsForRotationWithRotatedResources( /** * Calculate the insets needed from the left and right edges for the given rotation. * - * @param dc Device display cutout + * @param displayCutout Device display cutout * @param sbHeight appropriate status bar height for this rotation * @param width display width calculated for ROTATION_NONE * @param height display height calculated for ROTATION_NONE @@ -386,7 +398,7 @@ fun calculateInsetsForRotationWithRotatedResources( * rotation */ private fun getStatusBarLeftRight( - dc: DisplayCutout?, + displayCutout: DisplayCutout?, sbHeight: Int, width: Int, height: Int, @@ -402,7 +414,7 @@ private fun getStatusBarLeftRight( val logicalDisplayWidth = if (targetRotation.isHorizontal()) height else width - val cutoutRects = dc?.boundingRects + val cutoutRects = displayCutout?.boundingRects if (cutoutRects == null || cutoutRects.isEmpty()) { return Rect(minLeft, 0, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index aa061d74f6c6..037063f4f7b0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -411,8 +411,8 @@ class StatusBarNotificationPresenter implements NotificationPresenter, if (nowExpanded) { if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) { mShadeTransitionController.goToLockedShade(clickedEntry.getRow()); - } else if (clickedEntry.isSensitive() - && mDynamicPrivacyController.isInLockedDownShade()) { + } else if (mDynamicPrivacyController.isInLockedDownShade() + && mLockscreenUserManager.notifNeedsRedactionInPublic(clickedEntry)) { mStatusBarStateController.setLeaveOpenOnKeyguardHide(true); mActivityStarter.dismissKeyguardThenExecute(() -> false /* dismissAction */ , null /* cancelRunnable */, false /* afterKeyguardGone */); @@ -480,7 +480,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, .isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId()); boolean userPublic = devicePublic || mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId()); - boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry); + boolean needsRedaction = mLockscreenUserManager.notifNeedsRedactionInPublic(entry); if (userPublic && needsRedaction) { // TODO(b/135046837): we can probably relax this with dynamic privacy return true; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt index c1d0769eaa44..b11751554db3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt @@ -311,9 +311,9 @@ class UnlockedScreenOffAnimationController @Inject constructor( // We currently draw both the light reveal scrim, and the AOD UI, in the shade. If it's // already expanded and showing notifications/QS, the animation looks really messy. For now, - // disable it if the notification panel is not fully collapsed. + // disable it if the notification panel is expanded. if ((!this::mCentralSurfaces.isInitialized || - !mCentralSurfaces.notificationPanelViewController.isFullyCollapsed) && + mCentralSurfaces.notificationPanelViewController.isExpanded) && // Status bar might be expanded because we have started // playing the animation already !isAnimationPlaying() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java index 15ee553da457..dce24122aa7e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy; import android.app.IActivityTaskManager; +import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.policy.KeyguardStateController.Callback; @@ -94,6 +95,15 @@ public interface KeyguardStateController extends CallbackController<Callback> { boolean isKeyguardGoingAway(); /** + * Whether we're currently animating between the keyguard and the app/launcher surface behind + * it, or will be shortly (which happens if we started a fling to dismiss the keyguard). + * @see {@link KeyguardViewMediator#isAnimatingBetweenKeyguardAndSurfaceBehind()} + */ + default boolean isAnimatingBetweenKeyguardAndSurfaceBehind() { + return false; + }; + + /** * @return a shortened fading away duration similar to * {{@link #getKeyguardFadingAwayDuration()}} which may only span half of the duration, unless * we're bypassing diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java index 77e285d1e15d..2a225b909f90 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java @@ -279,6 +279,11 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum } @Override + public boolean isAnimatingBetweenKeyguardAndSurfaceBehind() { + return mUnlockAnimationControllerLazy.get().isAnimatingBetweenKeyguardAndSurfaceBehind(); + } + + @Override public boolean isBypassFadingAnimation() { return mBypassFadingAnimation; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java index c53d5107afcc..e0d780a5fcd5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java @@ -31,7 +31,9 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Binder; import android.os.RemoteException; +import android.os.Trace; import android.util.Log; +import android.view.DisplayCutout; import android.view.Gravity; import android.view.IWindowManager; import android.view.Surface; @@ -130,7 +132,9 @@ public class StatusBarWindowController { // Now that the status bar window encompasses the sliding panel and its // translucent backdrop, the entire thing is made TRANSLUCENT and is // hardware-accelerated. + Trace.beginSection("StatusBarWindowController.getBarLayoutParams"); mLp = getBarLayoutParams(mContext.getDisplay().getRotation()); + Trace.endSection(); mWindowManager.addView(mStatusBarWindowView, mLp); mLpChanged.copyFrom(mLp); @@ -223,14 +227,15 @@ public class StatusBarWindowController { private void calculateStatusBarLocationsForAllRotations() { Rect[] bounds = new Rect[4]; + final DisplayCutout displayCutout = mContext.getDisplay().getCutout(); bounds[0] = mContentInsetsProvider - .getBoundingRectForPrivacyChipForRotation(ROTATION_NONE); + .getBoundingRectForPrivacyChipForRotation(ROTATION_NONE, displayCutout); bounds[1] = mContentInsetsProvider - .getBoundingRectForPrivacyChipForRotation(ROTATION_LANDSCAPE); + .getBoundingRectForPrivacyChipForRotation(ROTATION_LANDSCAPE, displayCutout); bounds[2] = mContentInsetsProvider - .getBoundingRectForPrivacyChipForRotation(ROTATION_UPSIDE_DOWN); + .getBoundingRectForPrivacyChipForRotation(ROTATION_UPSIDE_DOWN, displayCutout); bounds[3] = mContentInsetsProvider - .getBoundingRectForPrivacyChipForRotation(ROTATION_SEASCAPE); + .getBoundingRectForPrivacyChipForRotation(ROTATION_SEASCAPE, displayCutout); try { mIWindowManager.updateStaticPrivacyIndicatorBounds(mContext.getDisplayId(), bounds); diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java b/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java index 2b7a33260248..90f24347d20d 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java +++ b/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java @@ -18,15 +18,18 @@ package com.android.systemui.tv; import android.app.Activity; import android.graphics.PixelFormat; +import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; +import android.view.View; import android.view.WindowManager; import com.android.systemui.R; +import java.util.Collections; import java.util.function.Consumer; /** @@ -75,6 +78,12 @@ public abstract class TvBottomSheetActivity extends Activity { getWindow().setElevation(getWindow().getElevation() + 5); getWindow().setBackgroundBlurRadius(getResources().getDimensionPixelSize( R.dimen.bottom_sheet_background_blur_radius)); + + final View rootView = findViewById(R.id.bottom_sheet); + rootView.addOnLayoutChangeListener((view, l, t, r, b, oldL, oldT, oldR, oldB) -> { + rootView.setUnrestrictedPreferKeepClearRects( + Collections.singletonList(new Rect(0, 0, r - l, b - t))); + }); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt index 3329eabc80ad..ad734914170b 100644 --- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt @@ -71,6 +71,11 @@ class UserSwitcherActivity @Inject constructor( private var popupMenu: UserSwitcherPopupMenu? = null private lateinit var addButton: View private var addUserRecords = mutableListOf<UserRecord>() + private val userSwitchedCallback: UserTracker.Callback = object : UserTracker.Callback { + override fun onUserChanged(newUser: Int, userContext: Context) { + finish() + } + } // When the add users options become available, insert another option to manage users private val manageUserRecord = UserRecord( null /* info */, @@ -215,11 +220,7 @@ class UserSwitcherActivity @Inject constructor( initBroadcastReceiver() parent.post { buildUserViews() } - userTracker.addCallback(object : UserTracker.Callback { - override fun onUserChanged(newUser: Int, userContext: Context) { - finish() - } - }, mainExecutor) + userTracker.addCallback(userSwitchedCallback, mainExecutor) } private fun showPopupMenu() { @@ -340,6 +341,7 @@ class UserSwitcherActivity @Inject constructor( super.onDestroy() broadcastDispatcher.unregisterReceiver(broadcastReceiver) + userTracker.removeCallback(userSwitchedCallback) } private fun initBroadcastReceiver() { diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java index ebdddbf66091..acff8712e92e 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java @@ -180,7 +180,7 @@ public class QuickAccessWalletController { int iconSizePx = mContext.getResources().getDimensionPixelSize(R.dimen.wallet_icon_size); GetWalletCardsRequest request = new GetWalletCardsRequest(cardWidth, cardHeight, iconSizePx, /* maxCards= */ 1); - mQuickAccessWalletClient.getWalletCards(mCallbackExecutor, request, cardsRetriever); + mQuickAccessWalletClient.getWalletCards(mExecutor, request, cardsRetriever); } /** diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index cddfd4498cfb..a6db2aa48a88 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -200,9 +200,13 @@ public final class WMShell extends CoreStartable mPipKeyguardCallback = new KeyguardUpdateMonitorCallback() { @Override public void onKeyguardVisibilityChanged(boolean showing) { - if (showing) { - pip.hidePipMenu(null, null); - } + pip.onKeyguardVisibilityChanged(showing, + mKeyguardStateController.isAnimatingBetweenKeyguardAndSurfaceBehind()); + } + + @Override + public void onKeyguardDismissAnimationFinished() { + pip.onKeyguardDismissAnimationFinished(); } }; mKeyguardUpdateMonitor.registerCallback(mPipKeyguardCallback); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt new file mode 100644 index 000000000000..a52c4a3978b4 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.biometrics + +import android.app.Instrumentation +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.testing.ViewUtils +import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import com.android.internal.jank.InteractionJankMonitor +import com.android.internal.logging.testing.UiEventLoggerFake +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.broadcast.BroadcastSender +import com.android.systemui.dump.DumpManager +import com.android.systemui.statusbar.StatusBarStateControllerImpl +import com.android.systemui.statusbar.phone.SystemUIDialogManager +import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager +import com.android.systemui.util.mockito.any +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.spy +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.junit.MockitoJUnit + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper +class UdfpsBpViewControllerTest : SysuiTestCase() { + + @JvmField @Rule var rule = MockitoJUnit.rule() + + @Mock lateinit var dumpManager: DumpManager + @Mock lateinit var systemUIDialogManager: SystemUIDialogManager + @Mock lateinit var broadcastSender: BroadcastSender + @Mock lateinit var interactionJankMonitor: InteractionJankMonitor + @Mock lateinit var panelExpansionStateManager: PanelExpansionStateManager + + private lateinit var instrumentation: Instrumentation + private lateinit var uiEventLogger: UiEventLoggerFake + private lateinit var udfpsBpView: UdfpsBpView + private lateinit var statusBarStateController: StatusBarStateControllerImpl + private lateinit var udfpsBpViewController: UdfpsBpViewController + + @Before + fun setup() { + instrumentation = getInstrumentation() + instrumentation.runOnMainSync { createUdfpsView() } + instrumentation.waitForIdleSync() + + uiEventLogger = UiEventLoggerFake() + statusBarStateController = + StatusBarStateControllerImpl(uiEventLogger, dumpManager, interactionJankMonitor) + udfpsBpViewController = UdfpsBpViewController( + udfpsBpView, + statusBarStateController, + panelExpansionStateManager, + systemUIDialogManager, + broadcastSender, + dumpManager) + udfpsBpViewController.init() + } + + @After + fun tearDown() { + if (udfpsBpViewController.isAttachedToWindow) { + instrumentation.runOnMainSync { ViewUtils.detachView(udfpsBpView) } + instrumentation.waitForIdleSync() + } + } + + private fun createUdfpsView() { + context.setTheme(R.style.Theme_AppCompat) + context.orCreateTestableResources.addOverride( + com.android.internal.R.integer.config_udfps_illumination_transition_ms, 0) + udfpsBpView = UdfpsBpView(context, null) + } + + @Test + fun addExpansionListener() { + instrumentation.runOnMainSync { ViewUtils.attachView(udfpsBpView) } + instrumentation.waitForIdleSync() + + // Both UdfpsBpViewController & UdfpsAnimationViewController add listener + verify(panelExpansionStateManager, times(2)).addExpansionListener(any()) + } + + @Test + fun removeExpansionListener() { + instrumentation.runOnMainSync { ViewUtils.attachView(udfpsBpView) } + instrumentation.waitForIdleSync() + instrumentation.runOnMainSync { ViewUtils.detachView(udfpsBpView) } + instrumentation.waitForIdleSync() + + // Both UdfpsBpViewController & UdfpsAnimationViewController remove listener + verify(panelExpansionStateManager, times(2)).removeExpansionListener(any()) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt index fc5ccbcb4a76..6eba2154e46c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt @@ -40,6 +40,7 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityLaunchAnimator +import com.android.systemui.broadcast.BroadcastSender import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.LockscreenShadeTransitionController @@ -102,6 +103,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() { @Mock private lateinit var udfpsView: UdfpsView @Mock private lateinit var udfpsEnrollView: UdfpsEnrollView @Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator + @Mock private lateinit var broadcastSender: BroadcastSender @Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams> private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true } @@ -131,7 +133,8 @@ class UdfpsControllerOverlayTest : SysuiTestCase() { keyguardUpdateMonitor, dialogManager, dumpManager, transitionController, configurationController, systemClock, keyguardStateController, unlockedScreenOffAnimationController, HAL_CONTROLS_ILLUMINATION, hbmProvider, - REQUEST_ID, reason, controllerCallback, onTouch, activityLaunchAnimator) + REQUEST_ID, reason, controllerCallback, onTouch, activityLaunchAnimator, + broadcastSender) block() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index aa548d2ec862..e6832a24833f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -66,6 +66,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.ActivityLaunchAnimator; +import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.FalsingManager; @@ -186,6 +187,8 @@ public class UdfpsControllerTest extends SysuiTestCase { private ActivityLaunchAnimator mActivityLaunchAnimator; @Mock private AlternateUdfpsTouchProvider mAlternateTouchProvider; + @Mock + private BroadcastSender mBroadcastSender; // Capture listeners so that they can be used to send events @Captor private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor; @@ -261,7 +264,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mSystemUIDialogManager, mLatencyTracker, mActivityLaunchAnimator, - Optional.of(mAlternateTouchProvider)); + Optional.of(mAlternateTouchProvider), + mBroadcastSender); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java index b87a7e78f73a..0fdd9054e4bc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java @@ -168,7 +168,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase { mController.onViewAttached(); verify(mView, atLeast(1)).setPauseAuth(true); - verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount, true); + verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount, + UdfpsKeyguardView.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN); } @Test @@ -195,7 +196,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase { final float eased = .65f; mStatusBarStateListener.onDozeAmountChanged(linear, eased); - verify(mView).onDozeAmountChanged(linear, eased, true); + verify(mView).onDozeAmountChanged(linear, eased, + UdfpsKeyguardView.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java index de04d3e9d059..91214a85ddd5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardListenerTest.java @@ -19,6 +19,8 @@ package com.android.systemui.clipboardoverlay; import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.CLIPBOARD_OVERLAY_ENABLED; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -26,7 +28,9 @@ import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import android.content.ClipData; +import android.content.ClipDescription; import android.content.ClipboardManager; +import android.os.PersistableBundle; import android.provider.DeviceConfig; import androidx.test.filters.SmallTest; @@ -139,4 +143,30 @@ public class ClipboardListenerTest extends SysuiTestCase { verify(mClipboardOverlayControllerFactory, times(2)).create(any()); } + + @Test + public void test_shouldSuppressOverlay() { + // Regardless of the package or emulator, nothing should be suppressed without the flag + assertFalse(ClipboardListener.shouldSuppressOverlay(mSampleClipData, mSampleSource, + false)); + assertFalse(ClipboardListener.shouldSuppressOverlay(mSampleClipData, + ClipboardListener.SHELL_PACKAGE, false)); + assertFalse(ClipboardListener.shouldSuppressOverlay(mSampleClipData, mSampleSource, + true)); + + ClipDescription desc = new ClipDescription("Test", new String[]{"text/plain"}); + PersistableBundle bundle = new PersistableBundle(); + bundle.putBoolean(ClipboardListener.EXTRA_SUPPRESS_OVERLAY, true); + desc.setExtras(bundle); + ClipData suppressableClipData = new ClipData(desc, new ClipData.Item("Test Item")); + + // Clip data with the suppression extra is only honored in the emulator or with the shell + // package. + assertFalse(ClipboardListener.shouldSuppressOverlay(suppressableClipData, mSampleSource, + false)); + assertTrue(ClipboardListener.shouldSuppressOverlay(suppressableClipData, mSampleSource, + true)); + assertTrue(ClipboardListener.shouldSuppressOverlay(suppressableClipData, + ClipboardListener.SHELL_PACKAGE, false)); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt index 0ed579f9c10b..241ed2443e6c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt @@ -21,6 +21,7 @@ import android.animation.AnimatorSet import android.app.PendingIntent import android.app.smartspace.SmartspaceAction import android.content.Context +import org.mockito.Mockito.`when` as whenever import android.content.Intent import android.content.pm.ApplicationInfo import android.content.pm.PackageManager @@ -58,6 +59,7 @@ import com.android.systemui.ActivityIntentHelper import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastSender +import com.android.systemui.media.MediaControlPanel.KEY_SMARTSPACE_APP_NAME import com.android.systemui.media.dialog.MediaOutputDialogFactory import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager @@ -66,8 +68,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.animation.TransitionLayout import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.KotlinArgumentCaptor -import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.nullable import com.android.systemui.util.mockito.withArgCaptor @@ -91,7 +93,6 @@ import org.mockito.Mockito.reset import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit -import org.mockito.Mockito.`when` as whenever private const val KEY = "TEST_KEY" private const val PACKAGE = "PKG" @@ -102,6 +103,7 @@ private const val SESSION_KEY = "SESSION_KEY" private const val SESSION_ARTIST = "SESSION_ARTIST" private const val SESSION_TITLE = "SESSION_TITLE" private const val DISABLED_DEVICE_NAME = "DISABLED_DEVICE_NAME" +private const val REC_APP_NAME = "REC APP NAME" @SmallTest @RunWith(AndroidTestingRunner::class) @@ -262,6 +264,7 @@ public class MediaControlPanelTest : SysuiTestCase() { // Set valid recommendation data val extras = Bundle() + extras.putString(KEY_SMARTSPACE_APP_NAME, REC_APP_NAME) val intent = Intent().apply { putExtras(extras) setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) @@ -339,7 +342,6 @@ public class MediaControlPanelTest : SysuiTestCase() { whenever(viewHolder.player).thenReturn(view) whenever(viewHolder.appIcon).thenReturn(appIcon) whenever(viewHolder.albumView).thenReturn(albumView) - whenever(albumView.foreground).thenReturn(mock(Drawable::class.java)) whenever(viewHolder.titleText).thenReturn(titleText) whenever(viewHolder.artistText).thenReturn(artistText) whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java)) @@ -1122,6 +1124,91 @@ public class MediaControlPanelTest : SysuiTestCase() { verify(mediaCarouselController).removePlayer(eq(mediaKey), eq(false), eq(false)) } + @Test + fun player_gutsOpen_contentDescriptionIsForGuts() { + whenever(mediaViewController.isGutsVisible).thenReturn(true) + player.attachPlayer(viewHolder) + + val gutsTextString = "gutsText" + whenever(gutsText.text).thenReturn(gutsTextString) + player.bindPlayer(mediaData, KEY) + + val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java) + verify(viewHolder.player).contentDescription = descriptionCaptor.capture() + val description = descriptionCaptor.value.toString() + + assertThat(description).isEqualTo(gutsTextString) + } + + @Test + fun player_gutsClosed_contentDescriptionIsForPlayer() { + whenever(mediaViewController.isGutsVisible).thenReturn(false) + player.attachPlayer(viewHolder) + + val app = "appName" + player.bindPlayer(mediaData.copy(app = app), KEY) + + val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java) + verify(viewHolder.player).contentDescription = descriptionCaptor.capture() + val description = descriptionCaptor.value.toString() + + assertThat(description).contains(mediaData.song!!) + assertThat(description).contains(mediaData.artist!!) + assertThat(description).contains(app) + } + + @Test + fun player_gutsChangesFromOpenToClosed_contentDescriptionUpdated() { + // Start out open + whenever(mediaViewController.isGutsVisible).thenReturn(true) + whenever(gutsText.text).thenReturn("gutsText") + player.attachPlayer(viewHolder) + val app = "appName" + player.bindPlayer(mediaData.copy(app = app), KEY) + + // Update to closed by long pressing + val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java) + verify(viewHolder.player).onLongClickListener = captor.capture() + reset(viewHolder.player) + + whenever(mediaViewController.isGutsVisible).thenReturn(false) + captor.value.onLongClick(viewHolder.player) + + // Then content description is now the player content description + val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java) + verify(viewHolder.player).contentDescription = descriptionCaptor.capture() + val description = descriptionCaptor.value.toString() + + assertThat(description).contains(mediaData.song!!) + assertThat(description).contains(mediaData.artist!!) + assertThat(description).contains(app) + } + + @Test + fun player_gutsChangesFromClosedToOpen_contentDescriptionUpdated() { + // Start out closed + whenever(mediaViewController.isGutsVisible).thenReturn(false) + val gutsTextString = "gutsText" + whenever(gutsText.text).thenReturn(gutsTextString) + player.attachPlayer(viewHolder) + player.bindPlayer(mediaData.copy(app = "appName"), KEY) + + // Update to open by long pressing + val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java) + verify(viewHolder.player).onLongClickListener = captor.capture() + reset(viewHolder.player) + + whenever(mediaViewController.isGutsVisible).thenReturn(true) + captor.value.onLongClick(viewHolder.player) + + // Then content description is now the guts content description + val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java) + verify(viewHolder.player).contentDescription = descriptionCaptor.capture() + val description = descriptionCaptor.value.toString() + + assertThat(description).isEqualTo(gutsTextString) + } + /* ***** END guts tests for the player ***** */ /* ***** Guts tests for the recommendations ***** */ @@ -1190,6 +1277,85 @@ public class MediaControlPanelTest : SysuiTestCase() { verify(mediaDataManager).dismissSmartspaceRecommendation(eq(mediaKey), anyLong()) } + @Test + fun recommendation_gutsOpen_contentDescriptionIsForGuts() { + whenever(mediaViewController.isGutsVisible).thenReturn(true) + player.attachRecommendation(recommendationViewHolder) + + val gutsTextString = "gutsText" + whenever(gutsText.text).thenReturn(gutsTextString) + player.bindRecommendation(smartspaceData) + + val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java) + verify(viewHolder.player).contentDescription = descriptionCaptor.capture() + val description = descriptionCaptor.value.toString() + + assertThat(description).isEqualTo(gutsTextString) + } + + @Test + fun recommendation_gutsClosed_contentDescriptionIsForPlayer() { + whenever(mediaViewController.isGutsVisible).thenReturn(false) + player.attachRecommendation(recommendationViewHolder) + + player.bindRecommendation(smartspaceData) + + val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java) + verify(viewHolder.player).contentDescription = descriptionCaptor.capture() + val description = descriptionCaptor.value.toString() + + assertThat(description).contains(REC_APP_NAME) + } + + @Test + fun recommendation_gutsChangesFromOpenToClosed_contentDescriptionUpdated() { + // Start out open + whenever(mediaViewController.isGutsVisible).thenReturn(true) + whenever(gutsText.text).thenReturn("gutsText") + player.attachRecommendation(recommendationViewHolder) + player.bindRecommendation(smartspaceData) + + // Update to closed by long pressing + val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java) + verify(viewHolder.player).onLongClickListener = captor.capture() + reset(viewHolder.player) + + whenever(mediaViewController.isGutsVisible).thenReturn(false) + captor.value.onLongClick(viewHolder.player) + + // Then content description is now the player content description + val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java) + verify(viewHolder.player).contentDescription = descriptionCaptor.capture() + val description = descriptionCaptor.value.toString() + + assertThat(description).contains(REC_APP_NAME) + } + + @Test + fun recommendation_gutsChangesFromClosedToOpen_contentDescriptionUpdated() { + // Start out closed + whenever(mediaViewController.isGutsVisible).thenReturn(false) + val gutsTextString = "gutsText" + whenever(gutsText.text).thenReturn(gutsTextString) + player.attachRecommendation(recommendationViewHolder) + player.bindRecommendation(smartspaceData) + + // Update to open by long pressing + val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java) + verify(viewHolder.player).onLongClickListener = captor.capture() + reset(viewHolder.player) + + whenever(mediaViewController.isGutsVisible).thenReturn(true) + captor.value.onLongClick(viewHolder.player) + + // Then content description is now the guts content description + val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java) + verify(viewHolder.player).contentDescription = descriptionCaptor.capture() + val description = descriptionCaptor.value.toString() + + assertThat(description).isEqualTo(gutsTextString) + } + /* ***** END guts tests for the recommendations ***** */ @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt index 10eeb11faa05..18ee79138b52 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt @@ -25,19 +25,17 @@ import android.media.session.MediaSession import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest - import com.android.settingslib.media.LocalMediaManager import com.android.settingslib.media.MediaDevice import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManager import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManagerFactory +import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.eq import com.android.systemui.util.time.FakeSystemClock - import com.google.common.truth.Truth.assertThat - import org.junit.After import org.junit.Before import org.junit.Rule @@ -50,8 +48,8 @@ import org.mockito.Mockito.mock import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` as whenever import org.mockito.junit.MockitoJUnit +import org.mockito.Mockito.`when` as whenever private const val KEY = "TEST_KEY" private const val KEY_OLD = "TEST_KEY_OLD" @@ -81,6 +79,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() { @Mock private lateinit var route: RoutingSessionInfo @Mock private lateinit var controller: MediaController @Mock private lateinit var playbackInfo: PlaybackInfo + @Mock private lateinit var configurationController: ConfigurationController private lateinit var session: MediaSession private lateinit var mediaData: MediaData @JvmField @Rule val mockito = MockitoJUnit.rule() @@ -94,6 +93,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() { lmmFactory, mr2, muteAwaitFactory, + configurationController, fakeFgExecutor, fakeBgExecutor, dumpster diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt index a07447521ab8..dafaa6b93696 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt @@ -35,6 +35,7 @@ import org.mockito.ArgumentCaptor import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito +import org.mockito.Mockito.reset import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations import org.mockito.Mockito.`when` as whenever @@ -73,6 +74,7 @@ public class ResumeMediaBrowserTest : SysuiTestCase() { @Captor lateinit var connectionCallback: ArgumentCaptor<MediaBrowser.ConnectionCallback> @Captor lateinit var subscriptionCallback: ArgumentCaptor<MediaBrowser.SubscriptionCallback> + @Captor lateinit var mediaControllerCallback: ArgumentCaptor<MediaController.Callback> @Before fun setUp() { @@ -82,6 +84,7 @@ public class ResumeMediaBrowserTest : SysuiTestCase() { .thenReturn(browser) whenever(mediaController.transportControls).thenReturn(transportControls) + whenever(mediaController.sessionToken).thenReturn(token) resumeBrowser = TestableResumeMediaBrowser( context, @@ -137,6 +140,22 @@ public class ResumeMediaBrowserTest : SysuiTestCase() { } @Test + fun testConnection_thenSessionDestroyed_disconnects() { + // When testConnection is called and we connect successfully + setupBrowserConnection() + resumeBrowser.testConnection() + verify(mediaController).registerCallback(mediaControllerCallback.capture()) + reset(browser) + + // And a sessionDestroyed event is triggered + mediaControllerCallback.value.onSessionDestroyed() + + // Then we disconnect the browser and unregister the callback + verify(browser).disconnect() + verify(mediaController).unregisterCallback(mediaControllerCallback.value) + } + + @Test fun testConnection_calledTwice_oldBrowserDisconnected() { val oldBrowser = mock<MediaBrowser>() whenever(browserFactory.create(any(), any(), any())).thenReturn(oldBrowser) @@ -188,6 +207,22 @@ public class ResumeMediaBrowserTest : SysuiTestCase() { } @Test + fun testFindRecentMedia_thenSessionDestroyed_disconnects() { + // When findRecentMedia is called and we connect successfully + setupBrowserConnection() + resumeBrowser.findRecentMedia() + verify(mediaController).registerCallback(mediaControllerCallback.capture()) + reset(browser) + + // And a sessionDestroyed event is triggered + mediaControllerCallback.value.onSessionDestroyed() + + // Then we disconnect the browser and unregister the callback + verify(browser).disconnect() + verify(mediaController).unregisterCallback(mediaControllerCallback.value) + } + + @Test fun testFindRecentMedia_calledTwice_oldBrowserDisconnected() { val oldBrowser = mock<MediaBrowser>() whenever(browserFactory.create(any(), any(), any())).thenReturn(oldBrowser) @@ -261,6 +296,22 @@ public class ResumeMediaBrowserTest : SysuiTestCase() { } @Test + fun testRestart_thenSessionDestroyed_disconnects() { + // When restart is called and we connect successfully + setupBrowserConnection() + resumeBrowser.restart() + verify(mediaController).registerCallback(mediaControllerCallback.capture()) + reset(browser) + + // And a sessionDestroyed event is triggered + mediaControllerCallback.value.onSessionDestroyed() + + // Then we disconnect the browser and unregister the callback + verify(browser).disconnect() + verify(mediaController).unregisterCallback(mediaControllerCallback.value) + } + + @Test fun testRestart_calledTwice_oldBrowserDisconnected() { val oldBrowser = mock<MediaBrowser>() whenever(browserFactory.create(any(), any(), any())).thenReturn(oldBrowser) diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java index a52608733ca4..1cfa3b2a08ff 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java @@ -47,6 +47,7 @@ import static org.mockito.Mockito.when; import android.content.BroadcastReceiver; import android.content.Context; import android.content.IntentFilter; +import android.content.res.Resources; import android.hardware.display.DisplayManagerGlobal; import android.os.Handler; import android.os.SystemClock; @@ -102,6 +103,8 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.DeviceConfigProxyFake; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; import com.android.systemui.utils.leaks.LeakCheckedTest; import com.android.wm.shell.back.BackAnimation; import com.android.wm.shell.pip.Pip; @@ -126,10 +129,10 @@ public class NavigationBarTest extends SysuiTestCase { private SysuiTestableContext mSysuiTestableContextExternal; @Mock - NavigationBarFrame mNavigationBarFrame; - @Mock NavigationBarView mNavigationBarView; @Mock + NavigationBarFrame mNavigationBarFrame; + @Mock ButtonDispatcher mHomeButton; @Mock ButtonDispatcher mRecentsButton; @@ -191,6 +194,9 @@ public class NavigationBarTest extends SysuiTestCase { private CentralSurfaces mCentralSurfaces; @Mock private UserContextProvider mUserContextProvider; + @Mock + private Resources mResources; + private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake(); @Rule @@ -215,6 +221,7 @@ public class NavigationBarTest extends SysuiTestCase { when(mNavigationBarView.getViewTreeObserver()).thenReturn(mViewTreeObserver); when(mUserContextProvider.createCurrentUserContext(any(Context.class))) .thenReturn(mContext); + when(mNavigationBarView.getResources()).thenReturn(mResources); setupSysuiDependency(); // This class inflates views that call Dependency.get, thus these injections are still // necessary. @@ -450,6 +457,8 @@ public class NavigationBarTest extends SysuiTestCase { mock(NotificationRemoteInputManager.class), mock(NotificationShadeDepthController.class), mHandler, + mFakeExecutor, + mFakeExecutor, mUiEventLogger, mNavBarHelper, mLightBarController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java index 4a6bbbcf1d6b..346d1e60fcf9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java @@ -24,7 +24,6 @@ import static com.android.systemui.qrcodescanner.controller.QRCodeScannerControl import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -32,6 +31,7 @@ import static org.mockito.Mockito.when; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Resources; import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings; @@ -41,7 +41,6 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; -import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.settings.UserTracker; import com.android.systemui.util.DeviceConfigProxyFake; @@ -90,8 +89,9 @@ public class QRCodeScannerControllerTest extends SysuiTestCase { when(mPackageManager.queryIntentActivities(any(Intent.class), any(Integer.class))).thenReturn(resolveInfoList); when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)).thenReturn(true); - mContext.getOrCreateTestableResources().addOverride(R.string.def_qr_code_component, - defaultActivity); + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.string.config_defaultQrCodeComponent, defaultActivity); + mContext.getOrCreateTestableResources().addOverride( android.R.bool.config_enableQrCodeScannerOnLockScreen, enableOnLockScreen); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java index f4a6df860e22..c2a41d5e41fb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java @@ -17,7 +17,10 @@ package com.android.systemui.qs.tiles; import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertTrue; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -25,6 +28,7 @@ import static org.mockito.Mockito.when; import android.content.ComponentName; import android.os.Handler; import android.os.RemoteException; +import android.os.UserHandle; import android.provider.Settings; import android.service.dreams.IDreamManager; import android.service.quicksettings.Tile; @@ -42,6 +46,7 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.QSTileHost; import com.android.systemui.qs.logging.QSLogger; +import com.android.systemui.settings.UserTracker; import com.android.systemui.util.settings.FakeSettings; import com.android.systemui.util.settings.SecureSettings; @@ -70,6 +75,8 @@ public class DreamTileTest extends SysuiTestCase { private IDreamManager mDreamManager; @Mock private BroadcastDispatcher mBroadcastDispatcher; + @Mock + private UserTracker mUserTracker; private TestableLooper mTestableLooper; @@ -94,18 +101,7 @@ public class DreamTileTest extends SysuiTestCase { when(mHost.getUserId()).thenReturn(DEFAULT_USER); when(mHost.getContext()).thenReturn(mContext); - mTile = spy(new DreamTile( - mHost, - mTestableLooper.getLooper(), - new Handler(mTestableLooper.getLooper()), - new FalsingManagerFake(), - mMetricsLogger, - mStatusBarStateController, - mActivityStarter, - mQSLogger, - mDreamManager, - mSecureSettings, - mBroadcastDispatcher)); + mTile = spy(constructTileForTest(true, false)); mTestableLooper.processAllMessages(); mTile.initialize(); @@ -195,8 +191,51 @@ public class DreamTileTest extends SysuiTestCase { mTile.getContentDescription(testDreamName)); } + @Test + public void testUserAvailability() { + DreamTile unsupportedTile = constructTileForTest(false, true); + assertFalse(unsupportedTile.isAvailable()); + + DreamTile supportedTileAllUsers = constructTileForTest(true, false); + + UserHandle systemUserHandle = mock(UserHandle.class); + when(systemUserHandle.isSystem()).thenReturn(true); + + UserHandle nonSystemUserHandle = mock(UserHandle.class); + when(nonSystemUserHandle.isSystem()).thenReturn(false); + + when(mUserTracker.getUserHandle()).thenReturn(systemUserHandle); + assertTrue(supportedTileAllUsers.isAvailable()); + when(mUserTracker.getUserHandle()).thenReturn(nonSystemUserHandle); + assertTrue(supportedTileAllUsers.isAvailable()); + + DreamTile supportedTileOnlySystemUser = constructTileForTest(true, true); + when(mUserTracker.getUserHandle()).thenReturn(systemUserHandle); + assertTrue(supportedTileOnlySystemUser.isAvailable()); + when(mUserTracker.getUserHandle()).thenReturn(nonSystemUserHandle); + assertFalse(supportedTileOnlySystemUser.isAvailable()); + } + private void setScreensaverEnabled(boolean enabled) { mSecureSettings.putIntForUser(Settings.Secure.SCREENSAVER_ENABLED, enabled ? 1 : 0, DEFAULT_USER); } + + private DreamTile constructTileForTest(boolean dreamSupported, + boolean dreamOnlyEnabledForSystemUser) { + return new DreamTile( + mHost, + mTestableLooper.getLooper(), + new Handler(mTestableLooper.getLooper()), + new FalsingManagerFake(), + mMetricsLogger, + mStatusBarStateController, + mActivityStarter, + mQSLogger, + mDreamManager, + mSecureSettings, + mBroadcastDispatcher, + mUserTracker, + dreamSupported, dreamOnlyEnabledForSystemUser); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index 562c97017862..73e574eddd17 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -130,8 +130,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { whenever(statusbarStateController.state).thenReturn(StatusBarState.KEYGUARD) whenever(nsslController.isInLockedDownShade).thenReturn(false) whenever(qS.isFullyCollapsed).thenReturn(true) - whenever(lockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn( - true) + whenever(lockScreenUserManager.sensitiveNotifsNeedRedactionInPublic(anyInt())) + .thenReturn(false) whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(true) whenever(lockScreenUserManager.isLockscreenPublicMode(anyInt())).thenReturn(true) whenever(falsingCollector.shouldEnforceBouncer()).thenReturn(false) @@ -207,8 +207,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { @Test fun testTriggeringBouncerWhenPrivateNotificationsArentAllowed() { - whenever(lockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn( - false) + whenever(lockScreenUserManager.sensitiveNotifsNeedRedactionInPublic(anyInt())) + .thenReturn(true) transitionController.goToLockedShade(null) verify(statusbarStateController, never()).setState(anyInt()) verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java index 7687d1204541..18937e784ed1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java @@ -53,11 +53,13 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; +import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.statusbar.NotificationLockscreenUserManager.KeyguardNotificationSuppressor; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -106,6 +108,10 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { private BroadcastDispatcher mBroadcastDispatcher; @Mock private KeyguardStateController mKeyguardStateController; + @Mock + private KeyguardUpdateMonitor mKeyguardUpdateMonitor; + @Mock + private OverviewProxyService mOverviewProxyService; private UserInfo mCurrentUser; private UserInfo mSecondaryUser; @@ -119,7 +125,6 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager); int currentUserId = ActivityManager.getCurrentUser(); mSettings = new FakeSettings(); @@ -212,7 +217,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN current user's notification is redacted - assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mCurrentUserNotif)); } @Test @@ -223,7 +228,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN current user's notification isn't redacted - assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mCurrentUserNotif)); } @Test @@ -234,7 +239,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN work profile notification is redacted - assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mWorkProfileNotif)); } @Test @@ -245,7 +250,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN work profile notification isn't redacted - assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mWorkProfileNotif)); } @Test @@ -260,11 +265,11 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN the work profile notification doesn't need to be redacted - assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mWorkProfileNotif)); // THEN the current user and secondary user notifications do need to be redacted - assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); - assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); + assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mCurrentUserNotif)); + assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mSecondaryUserNotif)); } @Test @@ -279,11 +284,11 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN the work profile notification needs to be redacted - assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mWorkProfileNotif)); // THEN the current user and secondary user notifications don't need to be redacted - assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); - assertFalse(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); + assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mCurrentUserNotif)); + assertFalse(mLockscreenUserManager.notifNeedsRedactionInPublic(mSecondaryUserNotif)); } @Test @@ -298,7 +303,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { // THEN the secondary profile notification still needs to be redacted because the current // user's setting takes precedence - assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); + assertTrue(mLockscreenUserManager.notifNeedsRedactionInPublic(mSecondaryUserNotif)); } @Test @@ -418,9 +423,12 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { context, mBroadcastDispatcher, mDevicePolicyManager, + mKeyguardUpdateMonitor, + () -> mEntryManager, + () -> mOverviewProxyService, mUserManager, - (() -> mVisibilityProvider), - (() -> mNotifCollection), + () -> mVisibilityProvider, + () -> mNotifCollection, mClickNotifier, NotificationLockscreenUserManagerTest.this.mKeyguardManager, mStatusBarStateController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java index 7d06abf5cd67..e43ae0d2b22a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java @@ -124,8 +124,8 @@ public class DynamicPrivacyControllerTest extends SysuiTestCase { } private void allowPrivateNotificationsInPublic(boolean allow) { - when(mLockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn( - allow); + when(mLockScreenUserManager.sensitiveNotifsNeedRedactionInPublic(anyInt())).thenReturn( + !allow); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java index 0fff5f5b47e5..16b0376ba1f9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java @@ -294,7 +294,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase { verify(mPresenter).updateNotificationViews(any()); verify(mEntryListener).onEntryRemoved( - eq(mEntry), any(), eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON)); + argThat(matchEntryOnKey()), any(), + eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON)); verify(mRow).setRemoved(); assertNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey())); @@ -319,8 +320,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase { mEntryManager.removeNotification("not_a_real_key", mRankingMap, UNDEFINED_DISMISS_REASON); - verify(mEntryListener, never()).onEntryRemoved( - eq(mEntry), any(), eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON)); + verify(mEntryListener, never()).onEntryRemoved(argThat(matchEntryOnKey()), any(), + eq(false) /* removedByUser */, eq(UNDEFINED_DISMISS_REASON)); } /** Regression test for b/201097913. */ @@ -333,10 +334,10 @@ public class NotificationEntryManagerTest extends SysuiTestCase { // Verify that only the listener for the NEW pipeline is notified. // Old pipeline: verify(mEntryListener, never()).onEntryRemoved( - argThat(matchEntryOnSbn()), any(), anyBoolean(), anyInt()); + argThat(matchEntryOnKey()), any(), anyBoolean(), anyInt()); // New pipeline: verify(mNotifCollectionListener).onEntryRemoved( - argThat(matchEntryOnSbn()), anyInt()); + argThat(matchEntryOnKey()), anyInt()); } @Test @@ -457,7 +458,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { // THEN the notification is retained assertNotNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey())); verify(mEntryListener, never()).onEntryRemoved( - eq(mEntry), any(), eq(false), eq(UNDEFINED_DISMISS_REASON)); + argThat(matchEntryOnKey()), any(), eq(false), eq(UNDEFINED_DISMISS_REASON)); } @Test @@ -476,7 +477,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { // THEN the notification is removed assertNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey())); verify(mEntryListener).onEntryRemoved( - eq(mEntry), any(), eq(false), eq(UNDEFINED_DISMISS_REASON)); + argThat(matchEntryOnKey()), any(), eq(false), eq(UNDEFINED_DISMISS_REASON)); } @Test @@ -541,7 +542,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { // GIVEN interceptor that intercepts that entry when(mRemoveInterceptor.onNotificationRemoveRequested( - eq(mEntry.getKey()), eq(mEntry), anyInt())) + eq(mEntry.getKey()), argThat(matchEntryOnKey()), anyInt())) .thenReturn(true); // WHEN the notification is removed @@ -549,7 +550,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { // THEN the interceptor intercepts & the entry is not removed & no listeners are called assertNotNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey())); - verify(mEntryListener, never()).onEntryRemoved(eq(mEntry), + verify(mEntryListener, never()).onEntryRemoved(argThat(matchEntryOnKey()), any(NotificationVisibility.class), anyBoolean(), eq(UNDEFINED_DISMISS_REASON)); } @@ -560,7 +561,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { // GIVEN interceptor that doesn't intercept when(mRemoveInterceptor.onNotificationRemoveRequested( - eq(mEntry.getKey()), eq(mEntry), anyInt())) + eq(mEntry.getKey()), argThat(matchEntryOnKey()), anyInt())) .thenReturn(false); // WHEN the notification is removed @@ -568,7 +569,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { // THEN the interceptor intercepts & the entry is not removed & no listeners are called assertNull(mEntryManager.getActiveNotificationUnfiltered(mSbn.getKey())); - verify(mEntryListener, atLeastOnce()).onEntryRemoved(eq(mEntry), + verify(mEntryListener, atLeastOnce()).onEntryRemoved(argThat(matchEntryOnKey()), any(NotificationVisibility.class), anyBoolean(), eq(UNDEFINED_DISMISS_REASON)); } @@ -663,9 +664,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase { PendingIntent.FLAG_IMMUTABLE)).build(); } - // TODO(b/201321631): Update more tests to use this function instead of eq(mEntry). - private ArgumentMatcher<NotificationEntry> matchEntryOnSbn() { - return e -> e.getSbn().equals(mSbn); + private ArgumentMatcher<NotificationEntry> matchEntryOnKey() { + return e -> e.getKey().equals(mEntry.getKey()); } private static class FakeNotificationLifetimeExtender implements NotificationLifetimeExtender { 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..5c2f5fa6bc1c 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 @@ -23,7 +23,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -33,7 +32,6 @@ import android.app.Notification; import android.app.NotificationManager; import android.testing.AndroidTestingRunner; -import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; @@ -41,7 +39,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SbnBuilder; import com.android.systemui.statusbar.notification.SectionClassifier; -import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; @@ -49,7 +46,6 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import com.android.systemui.statusbar.notification.collection.render.NodeController; -import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController; import org.junit.Before; import org.junit.Test; @@ -72,7 +68,6 @@ public class RankingCoordinatorTest extends SysuiTestCase { @Mock private NotifPipeline mNotifPipeline; @Mock private NodeController mAlertingHeaderController; @Mock private NodeController mSilentNodeController; - @Mock private SectionHeaderController mSilentHeaderController; @Captor private ArgumentCaptor<NotifFilter> mNotifFilterCaptor; @@ -94,7 +89,6 @@ public class RankingCoordinatorTest extends SysuiTestCase { mHighPriorityProvider, mSectionClassifier, mAlertingHeaderController, - mSilentHeaderController, mSilentNodeController); mEntry = spy(new NotificationEntryBuilder().build()); mEntry.setRanking(getRankingForUnfilteredNotif().build()); @@ -112,25 +106,6 @@ public class RankingCoordinatorTest extends SysuiTestCase { } @Test - public void testSilentHeaderClearableChildrenUpdate() { - ListEntry listEntry = new ListEntry(mEntry.getKey(), 0L) { - @Nullable - @Override - public NotificationEntry getRepresentativeEntry() { - return mEntry; - } - }; - setRankingAmbient(false); - setSbnClearable(true); - mSilentSectioner.onEntriesUpdated(Arrays.asList(listEntry)); - verify(mSilentHeaderController).setClearSectionEnabled(eq(true)); - - setSbnClearable(false); - mSilentSectioner.onEntriesUpdated(Arrays.asList(listEntry)); - verify(mSilentHeaderController).setClearSectionEnabled(eq(false)); - } - - @Test public void testUnfilteredState() { // GIVEN no suppressed visual effects + app not suspended mEntry.setRanking(getRankingForUnfilteredNotif().build()); @@ -225,46 +200,6 @@ public class RankingCoordinatorTest extends SysuiTestCase { assertInSection(mEntry, mSilentSectioner); } - @Test - public void testClearableSilentSection() { - when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false); - setSbnClearable(true); - setRankingAmbient(false); - mSilentSectioner.onEntriesUpdated(Arrays.asList(mEntry)); - verify(mSilentHeaderController).setClearSectionEnabled(eq(true)); - } - - @Test - public void testClearableMinimizedSection() { - when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false); - setSbnClearable(true); - setRankingAmbient(true); - mMinimizedSectioner.onEntriesUpdated(Arrays.asList(mEntry)); - verify(mSilentHeaderController).setClearSectionEnabled(eq(true)); - } - - @Test - public void testNotClearableSilentSection() { - setSbnClearable(false); - when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false); - setRankingAmbient(false); - mSilentSectioner.onEntriesUpdated(Arrays.asList(mEntry)); - mMinimizedSectioner.onEntriesUpdated(Arrays.asList(mEntry)); - mAlertingSectioner.onEntriesUpdated(Arrays.asList(mEntry)); - verify(mSilentHeaderController, times(2)).setClearSectionEnabled(eq(false)); - } - - @Test - public void testNotClearableMinimizedSection() { - setSbnClearable(false); - when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false); - setRankingAmbient(true); - mSilentSectioner.onEntriesUpdated(Arrays.asList(mEntry)); - mMinimizedSectioner.onEntriesUpdated(Arrays.asList(mEntry)); - mAlertingSectioner.onEntriesUpdated(Arrays.asList(mEntry)); - verify(mSilentHeaderController, times(2)).setClearSectionEnabled(eq(false)); - } - private void assertInSection(NotificationEntry entry, NotifSectioner section) { for (NotifSectioner current: mSections) { if (current == section) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt deleted file mode 100644 index a2d8e3ddba24..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.notification.collection.coordinator - -import android.os.UserHandle -import android.service.notification.StatusBarNotification -import androidx.test.filters.SmallTest -import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.SysuiTestCase -import com.android.systemui.plugins.statusbar.StatusBarStateController -import com.android.systemui.statusbar.NotificationLockscreenUserManager -import com.android.systemui.statusbar.StatusBarState -import com.android.systemui.statusbar.notification.DynamicPrivacyController -import com.android.systemui.statusbar.notification.collection.ListEntry -import com.android.systemui.statusbar.notification.collection.NotifPipeline -import com.android.systemui.statusbar.notification.collection.NotificationEntry -import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope -import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener -import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator -import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable -import com.android.systemui.statusbar.policy.KeyguardStateController -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.withArgCaptor -import dagger.BindsInstance -import dagger.Component -import org.junit.Test -import org.mockito.Mockito.never -import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` as whenever - -@SmallTest -class SensitiveContentCoordinatorTest : SysuiTestCase() { - - val dynamicPrivacyController: DynamicPrivacyController = mock() - val lockscreenUserManager: NotificationLockscreenUserManager = mock() - val pipeline: NotifPipeline = mock() - val keyguardUpdateMonitor: KeyguardUpdateMonitor = mock() - val statusBarStateController: StatusBarStateController = mock() - val keyguardStateController: KeyguardStateController = mock() - - val coordinator: SensitiveContentCoordinator = - DaggerTestSensitiveContentCoordinatorComponent - .factory() - .create( - dynamicPrivacyController, - lockscreenUserManager, - keyguardUpdateMonitor, - statusBarStateController, - keyguardStateController) - .coordinator - - @Test - fun onDynamicPrivacyChanged_invokeInvalidationListener() { - coordinator.attach(pipeline) - val invalidator = withArgCaptor<Invalidator> { - verify(pipeline).addPreRenderInvalidator(capture()) - } - val dynamicPrivacyListener = withArgCaptor<DynamicPrivacyController.Listener> { - verify(dynamicPrivacyController).addListener(capture()) - } - - val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>() - invalidator.setInvalidationListener(invalidationListener) - - dynamicPrivacyListener.onDynamicPrivacyChanged() - - verify(invalidationListener).onPluggableInvalidated(invalidator) - } - - @Test - fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction() { - coordinator.attach(pipeline) - val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> { - verify(pipeline).addOnBeforeRenderListListener(capture()) - } - - whenever(lockscreenUserManager.currentUserId).thenReturn(1) - whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false) - whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true) - whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false) - val entry = fakeNotification(1, false) - - onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) - - verify(entry.representativeEntry!!).setSensitive(false, false) - } - - @Test - fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction() { - coordinator.attach(pipeline) - val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> { - verify(pipeline).addOnBeforeRenderListListener(capture()) - } - - whenever(lockscreenUserManager.currentUserId).thenReturn(1) - whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false) - whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true) - whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false) - val entry = fakeNotification(1, true) - - onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) - - verify(entry.representativeEntry!!).setSensitive(false, false) - } - - @Test - fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs() { - coordinator.attach(pipeline) - val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> { - verify(pipeline).addOnBeforeRenderListListener(capture()) - } - - whenever(lockscreenUserManager.currentUserId).thenReturn(1) - whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true) - whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true) - whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false) - val entry = fakeNotification(1, false) - - onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) - - verify(entry.representativeEntry!!).setSensitive(false, false) - } - - @Test - fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction() { - coordinator.attach(pipeline) - val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> { - verify(pipeline).addOnBeforeRenderListListener(capture()) - } - - whenever(lockscreenUserManager.currentUserId).thenReturn(1) - whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true) - whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false) - whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false) - val entry = fakeNotification(1, false) - - onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) - - verify(entry.representativeEntry!!).setSensitive(false, true) - } - - @Test - fun onBeforeRenderList_deviceLocked_notifNeedsRedaction() { - coordinator.attach(pipeline) - val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> { - verify(pipeline).addOnBeforeRenderListListener(capture()) - } - - whenever(lockscreenUserManager.currentUserId).thenReturn(1) - whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true) - whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false) - whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false) - val entry = fakeNotification(1, true) - - onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) - - verify(entry.representativeEntry!!).setSensitive(true, true) - } - - @Test - fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction() { - coordinator.attach(pipeline) - val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> { - verify(pipeline).addOnBeforeRenderListListener(capture()) - } - - whenever(lockscreenUserManager.currentUserId).thenReturn(1) - whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true) - whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false) - whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true) - val entry = fakeNotification(1, true) - - onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) - - verify(entry.representativeEntry!!).setSensitive(false, true) - } - - @Test - fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge() { - coordinator.attach(pipeline) - val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> { - verify(pipeline).addOnBeforeRenderListListener(capture()) - } - - whenever(lockscreenUserManager.currentUserId).thenReturn(1) - whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true) - whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false) - whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true) - whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true) - - val entry = fakeNotification(2, true) - - onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) - - verify(entry.representativeEntry!!).setSensitive(true, true) - } - - @Test - fun onBeforeRenderList_deviceDynamicallyUnlocked_deviceBiometricBypassingLockScreen() { - coordinator.attach(pipeline) - val onBeforeRenderListListener = withArgCaptor<OnBeforeRenderListListener> { - verify(pipeline).addOnBeforeRenderListListener(capture()) - } - - whenever(lockscreenUserManager.currentUserId).thenReturn(1) - whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true) - whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false) - whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true) - whenever(statusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD) - whenever(keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing(any())) - .thenReturn(true) - - val entry = fakeNotification(2, true) - - onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) - - verify(entry.representativeEntry!!, never()).setSensitive(any(), any()) - } - - private fun fakeNotification(notifUserId: Int, needsRedaction: Boolean): ListEntry { - val mockUserHandle = mock<UserHandle>().apply { - whenever(identifier).thenReturn(notifUserId) - } - val mockSbn: StatusBarNotification = mock<StatusBarNotification>().apply { - whenever(user).thenReturn(mockUserHandle) - } - val mockEntry = mock<NotificationEntry>().apply { - whenever(sbn).thenReturn(mockSbn) - } - whenever(lockscreenUserManager.needsRedaction(mockEntry)).thenReturn(needsRedaction) - whenever(mockEntry.rowExists()).thenReturn(true) - return object : ListEntry("key", 0) { - override fun getRepresentativeEntry(): NotificationEntry = mockEntry - } - } -} - -@CoordinatorScope -@Component(modules = [SensitiveContentCoordinatorModule::class]) -interface TestSensitiveContentCoordinatorComponent { - val coordinator: SensitiveContentCoordinator - - @Component.Factory - interface Factory { - fun create( - @BindsInstance dynamicPrivacyController: DynamicPrivacyController, - @BindsInstance lockscreenUserManager: NotificationLockscreenUserManager, - @BindsInstance keyguardUpdateMonitor: KeyguardUpdateMonitor, - @BindsInstance statusBarStateController: StatusBarStateController, - @BindsInstance keyguardStateController: KeyguardStateController - ): TestSensitiveContentCoordinatorComponent - } -}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt index 70266e401f8a..cf2fc7c3a5fe 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt @@ -15,6 +15,7 @@ */ package com.android.systemui.statusbar.notification.collection.coordinator +import android.os.UserHandle import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest @@ -43,6 +44,11 @@ import org.mockito.Mockito.`when` as whenever @RunWith(AndroidTestingRunner::class) @RunWithLooper class StackCoordinatorTest : SysuiTestCase() { + + companion object { + const val NOTIF_USER_ID = 0 + } + private lateinit var coordinator: StackCoordinator private lateinit var afterRenderListListener: OnAfterRenderListListener @@ -61,7 +67,10 @@ class StackCoordinatorTest : SysuiTestCase() { afterRenderListListener = withArgCaptor { verify(pipeline).addOnAfterRenderListListener(capture()) } - entry = NotificationEntryBuilder().setSection(section).build() + entry = NotificationEntryBuilder() + .setSection(section) + .setUser(UserHandle.of(NOTIF_USER_ID)) + .build() } @Test @@ -74,13 +83,31 @@ class StackCoordinatorTest : SysuiTestCase() { fun testSetNotificationStats_clearableAlerting() { whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) - verify(stackController).setNotifStats(NotifStats(1, false, true, false, false)) + verify(stackController) + .setNotifStats( + NotifStats( + 1, + false, + true, + false, + false, + setOf(NOTIF_USER_ID), + emptySet())) } @Test fun testSetNotificationStats_clearableSilent() { whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) - verify(stackController).setNotifStats(NotifStats(1, false, false, false, true)) + verify(stackController) + .setNotifStats( + NotifStats( + 1, + false, + false, + false, + true, + emptySet(), + setOf(NOTIF_USER_ID))) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt index b63e66f1ebe3..c7f7ec213b0c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.android.systemui.statusbar.notification.icon; +package com.android.systemui.statusbar.notification.icon -import android.app.ActivityManager; -import android.app.Notification; +import android.app.ActivityManager +import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager.IMPORTANCE_DEFAULT import android.app.Person @@ -27,11 +27,12 @@ import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.os.SystemClock import android.os.UserHandle -import android.testing.AndroidTestingRunner; +import android.testing.AndroidTestingRunner import androidx.test.InstrumentationRegistry import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapperTest.Companion.any +import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection @@ -40,7 +41,7 @@ import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test -import org.junit.runner.RunWith; +import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.Mockito.anyInt @@ -48,15 +49,14 @@ import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidTestingRunner::class) -class IconManagerTest: SysuiTestCase() { +class IconManagerTest : SysuiTestCase() { companion object { - private const val TEST_PACKAGE_NAME = "test"; - private const val TEST_UID = 0; + private const val TEST_PACKAGE_NAME = "test" + private const val TEST_UID = 0 } - private var id = 0 - private val context = InstrumentationRegistry.getTargetContext(); + private val context = InstrumentationRegistry.getTargetContext() @Mock private lateinit var shortcut: ShortcutInfo @Mock private lateinit var shortcutIc: Icon @Mock private lateinit var messageIc: Icon @@ -65,6 +65,7 @@ class IconManagerTest: SysuiTestCase() { @Mock private lateinit var drawable: Drawable @Mock private lateinit var row: ExpandableNotificationRow + @Mock private lateinit var notifLockscreenUserManager: NotificationLockscreenUserManager @Mock private lateinit var notifCollection: CommonNotifCollection @Mock private lateinit var launcherApps: LauncherApps @@ -83,13 +84,16 @@ class IconManagerTest: SysuiTestCase() { `when`(shortcut.icon).thenReturn(shortcutIc) `when`(launcherApps.getShortcutIcon(shortcut)).thenReturn(shortcutIc) + `when`(notifLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(TEST_UID)) + .thenReturn(true) - iconManager = IconManager(notifCollection, launcherApps, iconBuilder) + iconManager = + IconManager(notifCollection, launcherApps, iconBuilder, notifLockscreenUserManager) } @Test fun testCreateIcons_importantConversation_shortcutIcon() { - val entry = notificationEntry(true, true, true) + val entry = notificationEntry() entry?.channel?.isImportantConversation = true entry?.let { iconManager.createIcons(it) @@ -99,7 +103,7 @@ class IconManagerTest: SysuiTestCase() { @Test fun testCreateIcons_importantConversation_messageIcon() { - val entry = notificationEntry(false, true, true) + val entry = notificationEntry(hasShortcut = false) entry?.channel?.isImportantConversation = true entry?.let { iconManager.createIcons(it) @@ -109,7 +113,7 @@ class IconManagerTest: SysuiTestCase() { @Test fun testCreateIcons_importantConversation_largeIcon() { - val entry = notificationEntry(false, false, true) + val entry = notificationEntry(hasShortcut = false, hasMessage = false) entry?.channel?.isImportantConversation = true entry?.let { iconManager.createIcons(it) @@ -119,7 +123,7 @@ class IconManagerTest: SysuiTestCase() { @Test fun testCreateIcons_importantConversation_smallIcon() { - val entry = notificationEntry(false, false, false) + val entry = notificationEntry(hasShortcut = false, hasMessage = false, hasLargeIcon = false) entry?.channel?.isImportantConversation = true entry?.let { iconManager.createIcons(it) @@ -129,7 +133,7 @@ class IconManagerTest: SysuiTestCase() { @Test fun testCreateIcons_notImportantConversation() { - val entry = notificationEntry(true, true, true) + val entry = notificationEntry() entry?.let { iconManager.createIcons(it) } @@ -138,8 +142,10 @@ class IconManagerTest: SysuiTestCase() { @Test fun testCreateIcons_sensitiveImportantConversation() { - val entry = notificationEntry(true, false, false) - entry?.setSensitive(true, true); + val entry = notificationEntry( + hasMessage = false, + hasLargeIcon = false, + hasSensitiveContent = true) entry?.channel?.isImportantConversation = true entry?.let { iconManager.createIcons(it) @@ -151,14 +157,17 @@ class IconManagerTest: SysuiTestCase() { @Test fun testUpdateIcons_sensitivityChange() { - val entry = notificationEntry(true, false, false) + val entry = notificationEntry( + hasMessage = false, + hasLargeIcon = false, + hasSensitiveContent = true) entry?.channel?.isImportantConversation = true - entry?.setSensitive(true, true); entry?.let { iconManager.createIcons(it) } assertEquals(entry?.icons?.aodIcon?.sourceIcon, smallIc) - entry?.setSensitive(false, false); + `when`(notifLockscreenUserManager.sensitiveNotifsNeedRedactionInPublic(TEST_UID)) + .thenReturn(false) entry?.let { iconManager.updateIcons(it) } @@ -166,14 +175,19 @@ class IconManagerTest: SysuiTestCase() { } private fun notificationEntry( - hasShortcut: Boolean, - hasMessage: Boolean, - hasLargeIcon: Boolean + hasShortcut: Boolean = true, + hasMessage: Boolean = true, + hasLargeIcon: Boolean = true, + hasSensitiveContent: Boolean = false ): NotificationEntry? { val n = Notification.Builder(mContext, "id") .setSmallIcon(smallIc) .setContentTitle("Title") .setContentText("Text") + .setVisibility( + if (hasSensitiveContent) + Notification.VISIBILITY_PRIVATE + else Notification.VISIBILITY_PUBLIC) if (hasMessage) { n.style = Notification.MessagingStyle("") @@ -203,7 +217,6 @@ class IconManagerTest: SysuiTestCase() { val entry = builder.build() entry.row = row - entry.setSensitive(false, true); return entry } } 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 4ea932157457..b3c34c1e4ff4 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 @@ -91,7 +91,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test public void testGroupSummaryNotShowingIconWhenPublic() { - mGroupRow.setSensitive(true, true); + mGroupRow.setSensitive(true); mGroupRow.setHideSensitiveForIntrinsicHeight(true); assertTrue(mGroupRow.isSummaryWithChildren()); assertFalse(mGroupRow.isShowingIcon()); @@ -99,7 +99,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test public void testNotificationHeaderVisibleWhenAnimating() { - mGroupRow.setSensitive(true, true); + mGroupRow.setSensitive(true); mGroupRow.setHideSensitive(true, false, 0, 0); mGroupRow.setHideSensitive(false, true, 0, 0); assertEquals(View.VISIBLE, mGroupRow.getChildrenContainer().getVisibleWrapper() @@ -130,7 +130,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { public void testIconColorShouldBeUpdatedWhenSensitive() throws Exception { ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow( FLAG_CONTENT_VIEW_ALL)); - row.setSensitive(true, true); + row.setSensitive(true); row.setHideSensitive(true, false, 0, 0); verify(row).updateShelfIconColor(); } @@ -214,7 +214,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test public void testFeedback_noHeader() { // public notification is custom layout - no header - mGroupRow.setSensitive(true, true); + mGroupRow.setSensitive(true); mGroupRow.setOnFeedbackClickListener(null); mGroupRow.setFeedbackIcon(null); } @@ -318,15 +318,6 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { } @Test - public void testGetIsNonblockable_oemLocked() throws Exception { - ExpandableNotificationRow row = - mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification()); - row.getEntry().getChannel().setImportanceLockedByOEM(true); - - assertTrue(row.getIsNonblockable()); - } - - @Test public void testGetIsNonblockable_criticalDeviceFunction() throws Exception { ExpandableNotificationRow row = mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java index 251ac7d250fe..a8557050dddb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java @@ -78,7 +78,6 @@ import com.android.systemui.statusbar.notification.collection.legacy.Notificatio import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; import com.android.systemui.statusbar.notification.icon.IconBuilder; import com.android.systemui.statusbar.notification.icon.IconManager; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent; @@ -132,7 +131,6 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { @Mock private NotificationEntryListener mEntryListener; @Mock private NotificationRowBinderImpl.BindRowCallback mBindCallback; @Mock private HeadsUpManager mHeadsUpManager; - @Mock private NotificationInterruptStateProvider mNotificationInterruptionStateProvider; @Mock private NotificationLockscreenUserManager mLockscreenUserManager; @Mock private NotificationGutsManager mGutsManager; @Mock private NotificationRemoteInputManager mRemoteInputManager; @@ -254,6 +252,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { .thenAnswer((Answer<ExpandableNotificationRowController>) invocation -> new ExpandableNotificationRowController( viewCaptor.getValue(), + mLockscreenUserManager, mock(ActivatableNotificationViewController.class), mock(RemoteInputViewSubcomponent.Factory.class), mock(MetricsLogger.class), @@ -300,7 +299,8 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { new IconManager( mEntryManager, mock(LauncherApps.class), - new IconBuilder(mContext)), + new IconBuilder(mContext), + mLockscreenUserManager), mock(LowPriorityInflationHelper.class), mNotifPipelineFlags); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index 1ecb09bc8514..d5ed37a570d2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -52,6 +52,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.media.MediaFeatureFlag; import com.android.systemui.media.dialog.MediaOutputDialogFactory; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeWindowController; @@ -152,7 +153,8 @@ public class NotificationTestHelper { mIconManager = new IconManager( mock(CommonNotifCollection.class), mock(LauncherApps.class), - new IconBuilder(mContext)); + new IconBuilder(mContext), + mock(NotificationLockscreenUserManager.class)); NotificationContentInflater contentBinder = new NotificationContentInflater( mock(NotifRemoteViewCache.class), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt index 4270d72770dc..3f190367f284 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt @@ -5,8 +5,9 @@ import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.NotificationShelf -import junit.framework.Assert.assertFalse -import junit.framework.Assert.assertTrue +import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.notification.row.ExpandableView +import junit.framework.Assert.* import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -143,6 +144,113 @@ class NotificationShelfTest : SysuiTestCase() { assertFalse(isYBelowShelfInView) } + @Test + fun getAmountInShelf_lastViewBelowShelf_completelyInShelf() { + val shelfClipStart = 0f + val viewStart = 1f + + val expandableView = mock(ExpandableView::class.java) + whenever(expandableView.shelfIcon).thenReturn(mock(StatusBarIconView::class.java)) + whenever(expandableView.translationY).thenReturn(viewStart) + whenever(expandableView.actualHeight).thenReturn(20) + + whenever(expandableView.minHeight).thenReturn(20) + whenever(expandableView.shelfTransformationTarget).thenReturn(null) // use translationY + whenever(expandableView.isInShelf).thenReturn(true) + + whenever(ambientState.isOnKeyguard).thenReturn(true) + whenever(ambientState.isExpansionChanging).thenReturn(false) + whenever(ambientState.isShadeExpanded).thenReturn(true) + + val amountInShelf = shelf.getAmountInShelf(/* i= */ 0, + /* view= */ expandableView, + /* scrollingFast= */ false, + /* expandingAnimated= */ false, + /* isLastChild= */ true, + shelfClipStart) + assertEquals(1f, amountInShelf) + } + + @Test + fun getAmountInShelf_lastViewAlmostBelowShelf_completelyInShelf() { + val viewStart = 0f + val shelfClipStart = 0.001f + + val expandableView = mock(ExpandableView::class.java) + whenever(expandableView.shelfIcon).thenReturn(mock(StatusBarIconView::class.java)) + whenever(expandableView.translationY).thenReturn(viewStart) + whenever(expandableView.actualHeight).thenReturn(20) + + whenever(expandableView.minHeight).thenReturn(20) + whenever(expandableView.shelfTransformationTarget).thenReturn(null) // use translationY + whenever(expandableView.isInShelf).thenReturn(true) + + whenever(ambientState.isOnKeyguard).thenReturn(true) + whenever(ambientState.isExpansionChanging).thenReturn(false) + whenever(ambientState.isShadeExpanded).thenReturn(true) + + val amountInShelf = shelf.getAmountInShelf(/* i= */ 0, + /* view= */ expandableView, + /* scrollingFast= */ false, + /* expandingAnimated= */ false, + /* isLastChild= */ true, + shelfClipStart) + assertEquals(1f, amountInShelf) + } + + @Test + fun getAmountInShelf_lastViewHalfClippedByShelf_halfInShelf() { + val viewStart = 0f + val shelfClipStart = 10f + + val expandableView = mock(ExpandableView::class.java) + whenever(expandableView.shelfIcon).thenReturn(mock(StatusBarIconView::class.java)) + whenever(expandableView.translationY).thenReturn(viewStart) + whenever(expandableView.actualHeight).thenReturn(25) + + whenever(expandableView.minHeight).thenReturn(25) + whenever(expandableView.shelfTransformationTarget).thenReturn(null) // use translationY + whenever(expandableView.isInShelf).thenReturn(true) + + whenever(ambientState.isOnKeyguard).thenReturn(true) + whenever(ambientState.isExpansionChanging).thenReturn(false) + whenever(ambientState.isShadeExpanded).thenReturn(true) + + val amountInShelf = shelf.getAmountInShelf(/* i= */ 0, + /* view= */ expandableView, + /* scrollingFast= */ false, + /* expandingAnimated= */ false, + /* isLastChild= */ true, + shelfClipStart) + assertEquals(0.5f, amountInShelf) + } + + @Test + fun getAmountInShelf_lastViewAboveShelf_notInShelf() { + val viewStart = 0f + val shelfClipStart = 15f + + val expandableView = mock(ExpandableView::class.java) + whenever(expandableView.shelfIcon).thenReturn(mock(StatusBarIconView::class.java)) + whenever(expandableView.translationY).thenReturn(viewStart) + whenever(expandableView.actualHeight).thenReturn(10) + + whenever(expandableView.minHeight).thenReturn(10) + whenever(expandableView.shelfTransformationTarget).thenReturn(null) // use translationY + whenever(expandableView.isInShelf).thenReturn(false) + + whenever(ambientState.isExpansionChanging).thenReturn(false) + whenever(ambientState.isOnKeyguard).thenReturn(true) + + val amountInShelf = shelf.getAmountInShelf(/* i= */ 0, + /* view= */ expandableView, + /* scrollingFast= */ false, + /* expandingAnimated= */ false, + /* isLastChild= */ true, + shelfClipStart) + assertEquals(0f, amountInShelf) + } + private fun setFractionToShade(fraction: Float) { whenever(ambientState.fractionToShade).thenReturn(fraction) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index e8608fa76c06..63e0f53e093d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -31,6 +31,8 @@ import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; @@ -612,6 +614,12 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { assertTrue(mStackScroller.isInsideQsHeader(event2)); } + @Test + public void setFractionToShade_recomputesStackHeight() { + mStackScroller.setFractionToShade(1f); + verify(mNotificationStackSizeCalculator).computeHeight(any(), anyInt(), anyFloat()); + } + private void setBarStateForTest(int state) { // Can't inject this through the listener or we end up on the actual implementation // rather than the mock because the spy just coppied the anonymous inner /shruggie. diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java index ed22cd3c55fc..169c04c692e0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java @@ -36,6 +36,7 @@ import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.HeadsUpStatusBarView; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationTestHelper; @@ -57,9 +58,12 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase { private final NotificationStackScrollLayoutController mStackScrollerController = mock(NotificationStackScrollLayoutController.class); - private final NotificationPanelViewController mPanelView = + private final NotificationPanelViewController mPanelViewController = mock(NotificationPanelViewController.class); private final DarkIconDispatcher mDarkIconDispatcher = mock(DarkIconDispatcher.class); + private final NotificationLockscreenUserManager mLockscreenUserManager = + mock(NotificationLockscreenUserManager.class); + private HeadsUpAppearanceController mHeadsUpAppearanceController; private ExpandableNotificationRow mFirst; private HeadsUpStatusBarView mHeadsUpStatusBarView; @@ -93,12 +97,13 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase { mHeadsUpManager, mStatusbarStateController, mBypassController, + mLockscreenUserManager, mWakeUpCoordinator, mDarkIconDispatcher, mKeyguardStateController, mCommandQueue, mStackScrollerController, - mPanelView, + mPanelViewController, mHeadsUpStatusBarView, new Clock(mContext, null), Optional.of(mOperatorNameView)); @@ -175,12 +180,13 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase { mHeadsUpManager, mStatusbarStateController, mBypassController, + mLockscreenUserManager, mWakeUpCoordinator, mDarkIconDispatcher, mKeyguardStateController, mCommandQueue, mStackScrollerController, - mPanelView, + mPanelViewController, mHeadsUpStatusBarView, new Clock(mContext, null), Optional.empty()); @@ -193,15 +199,15 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase { public void testDestroy() { reset(mHeadsUpManager); reset(mDarkIconDispatcher); - reset(mPanelView); + reset(mPanelViewController); reset(mStackScrollerController); mHeadsUpAppearanceController.onViewDetached(); verify(mHeadsUpManager).removeListener(any()); verify(mDarkIconDispatcher).removeDarkReceiver((DarkIconDispatcher.DarkReceiver) any()); - verify(mPanelView).removeTrackingHeadsUpListener(any()); - verify(mPanelView).setHeadsUpAppearanceController(isNull()); + verify(mPanelViewController).removeTrackingHeadsUpListener(any()); + verify(mPanelViewController).setHeadsUpAppearanceController(isNull()); verify(mStackScrollerController).removeOnExpandedHeightChangedListener(any()); } } 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 11f96cec6369..356d002e9da9 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 @@ -1009,6 +1009,17 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { } @Test + public void testExpandWithQsMethodIsUsingLockscreenTransitionController() { + enableSplitShade(/* enabled= */ true); + mStatusBarStateController.setState(KEYGUARD); + + mNotificationPanelViewController.expandWithQs(); + + verify(mLockscreenShadeTransitionController).goToLockedShade( + /* expandedView= */null, /* needsQSAnimation= */false); + } + + @Test public void testUnlockAnimationDoesNotAffectScrim() { mNotificationPanelViewController.onUnlockHintStarted(); verify(mScrimController).setExpansionAffectsAlpha(false); diff --git a/packages/VpnDialogs/res/values-gl/strings.xml b/packages/VpnDialogs/res/values-gl/strings.xml index cd8ee8d89474..08ab9aea93cb 100644 --- a/packages/VpnDialogs/res/values-gl/strings.xml +++ b/packages/VpnDialogs/res/values-gl/strings.xml @@ -33,5 +33,5 @@ <string name="configure" msgid="4905518375574791375">"Configurar"</string> <string name="disconnect" msgid="971412338304200056">"Desconectar"</string> <string name="open_app" msgid="3717639178595958667">"Abrir aplicación"</string> - <string name="dismiss" msgid="6192859333764711227">"Ignorar"</string> + <string name="dismiss" msgid="6192859333764711227">"Pechar"</string> </resources> diff --git a/packages/VpnDialogs/res/values-km/strings.xml b/packages/VpnDialogs/res/values-km/strings.xml index 0ed2e84b80fa..de18abafb9eb 100644 --- a/packages/VpnDialogs/res/values-km/strings.xml +++ b/packages/VpnDialogs/res/values-km/strings.xml @@ -33,5 +33,5 @@ <string name="configure" msgid="4905518375574791375">"កំណត់រចនាសម្ព័ន្ធ"</string> <string name="disconnect" msgid="971412338304200056">"ផ្ដាច់"</string> <string name="open_app" msgid="3717639178595958667">"បើកកម្មវិធី"</string> - <string name="dismiss" msgid="6192859333764711227">"បដិសេធ"</string> + <string name="dismiss" msgid="6192859333764711227">"ច្រានចោល"</string> </resources> diff --git a/packages/VpnDialogs/res/values-sq/strings.xml b/packages/VpnDialogs/res/values-sq/strings.xml index 0b4ce4df9514..eb73baad00b4 100644 --- a/packages/VpnDialogs/res/values-sq/strings.xml +++ b/packages/VpnDialogs/res/values-sq/strings.xml @@ -33,5 +33,5 @@ <string name="configure" msgid="4905518375574791375">"Konfiguro"</string> <string name="disconnect" msgid="971412338304200056">"Shkëputu"</string> <string name="open_app" msgid="3717639178595958667">"Hap aplikacionin"</string> - <string name="dismiss" msgid="6192859333764711227">"Largoje"</string> + <string name="dismiss" msgid="6192859333764711227">"Hiq"</string> </resources> diff --git a/services/Android.bp b/services/Android.bp index 1e4ce19f1541..70692a63ff0f 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -102,7 +102,6 @@ filegroup { ":services.profcollect-sources", ":services.restrictions-sources", ":services.searchui-sources", - ":services.selectiontoolbar-sources", ":services.smartspace-sources", ":services.speech-sources", ":services.systemcaptions-sources", @@ -158,7 +157,6 @@ java_library { "services.profcollect", "services.restrictions", "services.searchui", - "services.selectiontoolbar", "services.smartspace", "services.speech", "services.systemcaptions", diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 62bb9f155c34..9b2554fdbb3c 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -62,7 +62,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageInfo; -import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.UserInfo; @@ -81,7 +80,6 @@ import android.os.ServiceManager; import android.os.ShellCallback; import android.os.UserHandle; import android.os.UserManager; -import android.text.BidiFormatter; import android.util.ArraySet; import android.util.ExceptionUtils; import android.util.Log; @@ -294,14 +292,13 @@ public class CompanionDeviceManagerService extends SystemService { private boolean onCompanionApplicationBindingDiedInternal( @UserIdInt int userId, @NonNull String packageName) { - // Update the current connected devices sets when binderDied, so that application is able - // to call notifyDeviceAppeared after re-launch the application. for (AssociationInfo ai : mAssociationStore.getAssociationsForPackage(userId, packageName)) { - int id = ai.getId(); - Slog.i(TAG, "Removing association id: " + id + " for package: " - + packageName + " due to binderDied."); - mDevicePresenceMonitor.removeDeviceFromMonitoring(id); + final int associationId = ai.getId(); + if (ai.isSelfManaged() + && mDevicePresenceMonitor.isDevicePresent(associationId)) { + mDevicePresenceMonitor.onSelfManagedDeviceReporterBinderDied(associationId); + } } // TODO(b/218613015): implement. return false; @@ -538,20 +535,12 @@ public class CompanionDeviceManagerService extends SystemService { String callingPackage = component.getPackageName(); checkCanCallNotificationApi(callingPackage); // TODO: check userId. - String packageTitle = BidiFormatter.getInstance().unicodeWrap( - getPackageInfo(getContext(), userId, callingPackage) - .applicationInfo - .loadSafeLabel(getContext().getPackageManager(), - PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, - PackageItemInfo.SAFE_LABEL_FLAG_TRIM - | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE) - .toString()); final long identity = Binder.clearCallingIdentity(); try { return PendingIntent.getActivityAsUser(getContext(), 0 /* request code */, NotificationAccessConfirmationActivityContract.launcherIntent( - getContext(), userId, component, packageTitle), + getContext(), userId, component), PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT, null /* options */, @@ -732,9 +721,12 @@ public class CompanionDeviceManagerService extends SystemService { String[] args, ShellCallback callback, ResultReceiver resultReceiver) throws RemoteException { enforceCallerCanManageCompanionDevice(getContext(), "onShellCommand"); - new CompanionDeviceShellCommand( - CompanionDeviceManagerService.this, mAssociationStore) - .exec(this, in, out, err, args, callback, resultReceiver); + + final CompanionDeviceShellCommand cmd = new CompanionDeviceShellCommand( + CompanionDeviceManagerService.this, + mAssociationStore, + mDevicePresenceMonitor); + cmd.exec(this, in, out, err, args, callback, resultReceiver); } @Override diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java index fd130852a43a..6a19a42723c5 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java @@ -21,6 +21,8 @@ import android.os.ShellCommand; import android.util.Log; import android.util.Slog; +import com.android.server.companion.presence.CompanionDevicePresenceMonitor; + import java.io.PrintWriter; import java.util.List; @@ -29,20 +31,24 @@ class CompanionDeviceShellCommand extends ShellCommand { private final CompanionDeviceManagerService mService; private final AssociationStore mAssociationStore; + private final CompanionDevicePresenceMonitor mDevicePresenceMonitor; CompanionDeviceShellCommand(CompanionDeviceManagerService service, - AssociationStore associationStore) { + AssociationStore associationStore, + CompanionDevicePresenceMonitor devicePresenceMonitor) { mService = service; mAssociationStore = associationStore; + mDevicePresenceMonitor = devicePresenceMonitor; } @Override public int onCommand(String cmd) { final PrintWriter out = getOutPrintWriter(); + final int associationId; try { switch (cmd) { case "list": { - final int userId = getNextArgInt(); + final int userId = getNextIntArgRequired(); final List<AssociationInfo> associationsForUser = mAssociationStore.getAssociationsForUser(userId); for (AssociationInfo association : associationsForUser) { @@ -55,7 +61,7 @@ class CompanionDeviceShellCommand extends ShellCommand { break; case "associate": { - int userId = getNextArgInt(); + int userId = getNextIntArgRequired(); String packageName = getNextArgRequired(); String address = getNextArgRequired(); mService.legacyCreateAssociation(userId, address, packageName, null); @@ -63,7 +69,7 @@ class CompanionDeviceShellCommand extends ShellCommand { break; case "disassociate": { - final int userId = getNextArgInt(); + final int userId = getNextIntArgRequired(); final String packageName = getNextArgRequired(); final String address = getNextArgRequired(); final AssociationInfo association = @@ -80,6 +86,16 @@ class CompanionDeviceShellCommand extends ShellCommand { } break; + case "simulate-device-appeared": + associationId = getNextIntArgRequired(); + mDevicePresenceMonitor.simulateDeviceAppeared(associationId); + break; + + case "simulate-device-disappeared": + associationId = getNextIntArgRequired(); + mDevicePresenceMonitor.simulateDeviceDisappeared(associationId); + break; + default: return handleDefaultCommands(cmd); } @@ -91,10 +107,6 @@ class CompanionDeviceShellCommand extends ShellCommand { } } - private int getNextArgInt() { - return Integer.parseInt(getNextArgRequired()); - } - @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); @@ -108,7 +120,31 @@ class CompanionDeviceShellCommand extends ShellCommand { pw.println(" disassociate USER_ID PACKAGE MAC_ADDRESS"); pw.println(" Remove an existing Association."); pw.println(" clear-association-memory-cache"); - pw.println(" Clear the in-memory association cache and reload all association " - + "information from persistent storage. USE FOR DEBUGGING PURPOSES ONLY."); + pw.println(" Clear the in-memory association cache and reload all association "); + pw.println(" information from persistent storage. USE FOR DEBUGGING PURPOSES ONLY."); + pw.println(" USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY."); + + pw.println(" simulate-device-appeared ASSOCIATION_ID"); + pw.println(" Make CDM act as if the given companion device has appeared."); + pw.println(" I.e. bind the associated companion application's"); + pw.println(" CompanionDeviceService(s) and trigger onDeviceAppeared() callback."); + pw.println(" The CDM will consider the devices as present for 60 seconds and then"); + pw.println(" will act as if device disappeared, unless 'simulate-device-disappeared'"); + pw.println(" or 'simulate-device-appeared' is called again before 60 seconds run out" + + "."); + pw.println(" USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY."); + + pw.println(" simulate-device-disappeared ASSOCIATION_ID"); + pw.println(" Make CDM act as if the given companion device has disappeared."); + pw.println(" I.e. unbind the associated companion application's"); + pw.println(" CompanionDeviceService(s) and trigger onDeviceDisappeared() callback."); + pw.println(" NOTE: This will only have effect if 'simulate-device-appeared' was"); + pw.println(" invoked for the same device (same ASSOCIATION_ID) no longer than"); + pw.println(" 60 seconds ago."); + pw.println(" USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY."); + } + + private int getNextIntArgRequired() { + return Integer.parseInt(getNextArgRequired()); } } diff --git a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java index 24be1b6fd701..89ed301eb661 100644 --- a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java +++ b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java @@ -16,11 +16,19 @@ package com.android.server.companion.presence; +import static android.os.Process.ROOT_UID; +import static android.os.Process.SHELL_UID; + import android.annotation.NonNull; import android.annotation.SuppressLint; +import android.annotation.TestApi; import android.bluetooth.BluetoothAdapter; import android.companion.AssociationInfo; import android.content.Context; +import android.os.Binder; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.util.Log; import com.android.server.companion.AssociationStore; @@ -72,6 +80,11 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange private final @NonNull Set<Integer> mNearbyBleDevices = new HashSet<>(); private final @NonNull Set<Integer> mReportedSelfManagedDevices = new HashSet<>(); + // Tracking "simulated" presence. Used for debugging and testing only. + private final @NonNull Set<Integer> mSimulated = new HashSet<>(); + private final SimulatedDevicePresenceSchedulerHelper mSchedulerHelper = + new SimulatedDevicePresenceSchedulerHelper(); + public CompanionDevicePresenceMonitor(@NonNull AssociationStore associationStore, @NonNull Callback callback) { mAssociationStore = associationStore; @@ -106,7 +119,8 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange public boolean isDevicePresent(int associationId) { return mReportedSelfManagedDevices.contains(associationId) || mConnectedBtDevices.contains(associationId) - || mNearbyBleDevices.contains(associationId); + || mNearbyBleDevices.contains(associationId) + || mSimulated.contains(associationId); } /** @@ -135,6 +149,13 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange onDeviceGone(mReportedSelfManagedDevices, associationId, "application-reported"); } + /** + * Marks a "self-managed" device as disconnected when binderDied. + */ + public void onSelfManagedDeviceReporterBinderDied(int associationId) { + onDeviceGone(mReportedSelfManagedDevices, associationId, "application-reported"); + } + @Override public void onBluetoothCompanionDeviceConnected(int associationId) { onDevicePresent(mConnectedBtDevices, associationId, /* sourceLoggingTag */ "bt"); @@ -155,6 +176,45 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange onDeviceGone(mNearbyBleDevices, associationId, /* sourceLoggingTag */ "ble"); } + /** FOR DEBUGGING AND/OR TESTING PURPOSES ONLY. */ + @TestApi + public void simulateDeviceAppeared(int associationId) { + // IMPORTANT: this API should only be invoked via the + // 'companiondevice simulate-device-appeared' Shell command, so the only uid-s allowed to + // make this call are SHELL and ROOT. + // No other caller (including SYSTEM!) should be allowed. + enforceCallerShellOrRoot(); + // Make sure the association exists. + enforceAssociationExists(associationId); + + onDevicePresent(mSimulated, associationId, /* sourceLoggingTag */ "simulated"); + + mSchedulerHelper.scheduleOnDeviceGoneCallForSimulatedDevicePresence(associationId); + } + + /** FOR DEBUGGING AND/OR TESTING PURPOSES ONLY. */ + @TestApi + public void simulateDeviceDisappeared(int associationId) { + // IMPORTANT: this API should only be invoked via the + // 'companiondevice simulate-device-appeared' Shell command, so the only uid-s allowed to + // make this call are SHELL and ROOT. + // No other caller (including SYSTEM!) should be allowed. + enforceCallerShellOrRoot(); + // Make sure the association exists. + enforceAssociationExists(associationId); + + mSchedulerHelper.unscheduleOnDeviceGoneCallForSimulatedDevicePresence(associationId); + + onDeviceGone(mSimulated, associationId, /* sourceLoggingTag */ "simulated"); + } + + private void enforceAssociationExists(int associationId) { + if (mAssociationStore.getAssociationById(associationId) == null) { + throw new IllegalArgumentException( + "Association with id " + associationId + " does not exist."); + } + } + private void onDevicePresent(@NonNull Set<Integer> presentDevicesForSource, int newDeviceAssociationId, @NonNull String sourceLoggingTag) { if (DEBUG) { @@ -206,15 +266,6 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange } /** - * Remove the current connected devices by associationId. - */ - public void removeDeviceFromMonitoring(int associationId) { - mConnectedBtDevices.remove(associationId); - mNearbyBleDevices.remove(associationId); - mReportedSelfManagedDevices.remove(associationId); - } - - /** * Implements * {@link AssociationStore.OnChangeListener#onAssociationRemoved(AssociationInfo)} */ @@ -226,10 +277,44 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange Log.d(TAG, " > association=" + association); } - removeDeviceFromMonitoring(id); + mConnectedBtDevices.remove(id); + mNearbyBleDevices.remove(id); + mReportedSelfManagedDevices.remove(id); // Do NOT call mCallback.onDeviceDisappeared()! // CompanionDeviceManagerService will know that the association is removed, and will do // what's needed. } + + private static void enforceCallerShellOrRoot() { + final int callingUid = Binder.getCallingUid(); + if (callingUid == SHELL_UID || callingUid == ROOT_UID) return; + + throw new SecurityException("Caller is neither Shell nor Root"); + } + + private class SimulatedDevicePresenceSchedulerHelper extends Handler { + SimulatedDevicePresenceSchedulerHelper() { + super(Looper.getMainLooper()); + } + + void scheduleOnDeviceGoneCallForSimulatedDevicePresence(int associationId) { + // First, unschedule if it was scheduled previously. + if (hasMessages(/* what */ associationId)) { + removeMessages(/* what */ associationId); + } + + sendEmptyMessageDelayed(/* what */ associationId, 60 * 1000 /* 60 seconds */); + } + + void unscheduleOnDeviceGoneCallForSimulatedDevicePresence(int associationId) { + removeMessages(/* what */ associationId); + } + + @Override + public void handleMessage(@NonNull Message msg) { + final int associationId = msg.what; + onDeviceGone(mSimulated, associationId, /* sourceLoggingTag */ "simulated"); + } + } } diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index 06f698efde2b..ed6110086089 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -334,10 +334,14 @@ public abstract class PackageManagerInternal { /** * Retrieve all receivers that can handle a broadcast of the given intent. + * @param filterCallingUid The results will be filtered in the context of this UID instead + * of the calling UID. + * @param forSend true if the invocation is intended for sending broadcasts. The value + * of this parameter affects how packages are filtered. */ public abstract List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, - int filterCallingUid, int userId); + int filterCallingUid, int userId, boolean forSend); /** * Retrieve all services that can be performed for the given intent. @@ -371,10 +375,10 @@ public abstract class PackageManagerInternal { int deviceOwnerUserId, String deviceOwner, SparseArray<String> profileOwners); /** - * Called by Owners to set the package names protected by the device owner. + * Marks packages as protected for a given user or all users in case of USER_ALL. */ - public abstract void setDeviceOwnerProtectedPackages( - String deviceOwnerPackageName, List<String> packageNames); + public abstract void setOwnerProtectedPackages( + @UserIdInt int userId, @NonNull List<String> packageNames); /** * Returns {@code true} if a given package can't be wiped. Otherwise, returns {@code false}. diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index bc40170d39b7..5eec6e58e925 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -3880,9 +3880,12 @@ class StorageManagerService extends IStorageManager.Stub match = vol.isVisibleForWrite(userId) || (includeSharedProfile && vol.isVisibleForWrite(userIdSharingMedia)); } else { + // Return both read only and write only volumes. When includeSharedProfile is + // true, all the volumes of userIdSharingMedia should be returned when queried + // from the user it shares media with match = vol.isVisibleForUser(userId) || (!vol.isVisible() && includeInvisible && vol.getPath() != null) - || (includeSharedProfile && vol.isVisibleForRead(userIdSharingMedia)); + || (includeSharedProfile && vol.isVisibleForUser(userIdSharingMedia)); } if (!match) continue; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 40f310947f3d..bbdfb083cd4e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2617,7 +2617,7 @@ public class ActivityManagerService extends IActivityManager.Stub public void batterySendBroadcast(Intent intent) { synchronized (this) { broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null, null, - OP_NONE, null, false, false, -1, SYSTEM_UID, Binder.getCallingUid(), + null, OP_NONE, null, false, false, -1, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); } } @@ -4231,7 +4231,7 @@ public class ActivityManagerService extends IActivityManager.Stub intent.putExtra(Intent.EXTRA_UID, uid); intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); broadcastIntentLocked(null, null, null, intent, - null, null, 0, null, null, null, null, OP_NONE, + null, null, 0, null, null, null, null, null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.getUserId(uid)); } @@ -8112,7 +8112,7 @@ public class ActivityManagerService extends IActivityManager.Stub | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, null, intent, - null, null, 0, null, null, null, null, OP_NONE, + null, null, 0, null, null, null, null, null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, currentUserId); intent = new Intent(Intent.ACTION_USER_STARTING); @@ -8124,8 +8124,8 @@ public class ActivityManagerService extends IActivityManager.Stub public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {} - }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, null, OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, null, null, + OP_NONE, null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, UserHandle.USER_ALL); } catch (Throwable e) { Slog.wtf(TAG, "Failed sending first user broadcasts", e); @@ -13155,8 +13155,8 @@ public class ActivityManagerService extends IActivityManager.Stub Intent intent = allSticky.get(i); BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, null, - null, null, -1, -1, false, null, null, null, OP_NONE, null, receivers, - null, 0, null, null, false, true, true, -1, false, null, + null, null, -1, -1, false, null, null, null, null, OP_NONE, null, + receivers, null, 0, null, null, false, true, true, -1, false, null, false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */); queue.enqueueParallelBroadcastLocked(r); queue.scheduleBroadcastsLocked(); @@ -13238,8 +13238,8 @@ public class ActivityManagerService extends IActivityManager.Stub UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { continue; } - List<ResolveInfo> newReceivers = mPackageManagerInt - .queryIntentReceivers(intent, resolvedType, pmFlags, callingUid, user); + List<ResolveInfo> newReceivers = mPackageManagerInt.queryIntentReceivers( + intent, resolvedType, pmFlags, callingUid, user, true /* forSend */); if (user != UserHandle.USER_SYSTEM && newReceivers != null) { // If this is not the system user, we need to check for // any receivers that should be filtered out. @@ -13255,8 +13255,9 @@ public class ActivityManagerService extends IActivityManager.Stub if (newReceivers != null) { for (int i = newReceivers.size() - 1; i >= 0; i--) { final ResolveInfo ri = newReceivers.get(i); - final Resolution<ResolveInfo> resolution = mComponentAliasResolver - .resolveReceiver(intent, ri, resolvedType, pmFlags, user, callingUid); + final Resolution<ResolveInfo> resolution = + mComponentAliasResolver.resolveReceiver(intent, ri, resolvedType, + pmFlags, user, callingUid, true /* forSend */); if (resolution == null) { // It was an alias, but the target was not found. newReceivers.remove(i); @@ -13411,12 +13412,14 @@ public class ActivityManagerService extends IActivityManager.Stub String callerPackage, String callerFeatureId, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, String[] excludedPermissions, - int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, + String[] excludedPackages, int appOp, Bundle bOptions, boolean ordered, + boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId) { return broadcastIntentLocked(callerApp, callerPackage, callerFeatureId, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, - excludedPermissions, appOp, bOptions, ordered, sticky, callingPid, callingUid, - realCallingUid, realCallingPid, userId, false /* allowBackgroundActivityStarts */, + excludedPermissions, excludedPackages, appOp, bOptions, ordered, sticky, callingPid, + callingUid, realCallingUid, realCallingPid, userId, + false /* allowBackgroundActivityStarts */, null /* tokenNeededForBackgroundActivityStarts */, null /* broadcastAllowList */); } @@ -13425,7 +13428,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Nullable String callerFeatureId, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, - String[] excludedPermissions, int appOp, Bundle bOptions, + String[] excludedPermissions, String[] excludedPackages, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId, boolean allowBackgroundActivityStarts, @@ -14032,10 +14035,10 @@ public class ActivityManagerService extends IActivityManager.Stub final BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, - requiredPermissions, excludedPermissions, appOp, brOptions, registeredReceivers, - resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId, - allowBackgroundActivityStarts, backgroundActivityStartsToken, - timeoutExempt); + requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions, + registeredReceivers, resultTo, resultCode, resultData, resultExtras, ordered, + sticky, false, userId, allowBackgroundActivityStarts, + backgroundActivityStartsToken, timeoutExempt); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r); final boolean replaced = replacePending && (queue.replaceParallelBroadcastLocked(r) != null); @@ -14130,7 +14133,7 @@ public class ActivityManagerService extends IActivityManager.Stub BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, - requiredPermissions, excludedPermissions, appOp, brOptions, + requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions, receivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId, allowBackgroundActivityStarts, backgroundActivityStartsToken, timeoutExempt); @@ -14259,14 +14262,16 @@ public class ActivityManagerService extends IActivityManager.Stub String[] requiredPermissions, int appOp, Bundle bOptions, boolean serialized, boolean sticky, int userId) { return broadcastIntentWithFeature(caller, null, intent, resolvedType, resultTo, resultCode, - resultData, resultExtras, requiredPermissions, null, appOp, bOptions, serialized, - sticky, userId); + resultData, resultExtras, requiredPermissions, null, null, appOp, bOptions, + serialized, sticky, userId); } + @Override public final int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, - String[] requiredPermissions, String[] excludedPermissions, int appOp, Bundle bOptions, + String[] requiredPermissions, String[] excludedPermissions, + String[] excludedPackages, int appOp, Bundle bOptions, boolean serialized, boolean sticky, int userId) { enforceNotIsolatedCaller("broadcastIntent"); synchronized(this) { @@ -14281,8 +14286,8 @@ public class ActivityManagerService extends IActivityManager.Stub return broadcastIntentLocked(callerApp, callerApp != null ? callerApp.info.packageName : null, callingFeatureId, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, - requiredPermissions, excludedPermissions, appOp, bOptions, serialized, - sticky, callingPid, callingUid, callingUid, callingPid, userId); + requiredPermissions, excludedPermissions, excludedPackages, appOp, bOptions, + serialized, sticky, callingPid, callingUid, callingUid, callingPid, userId); } finally { Binder.restoreCallingIdentity(origId); } @@ -14305,7 +14310,7 @@ public class ActivityManagerService extends IActivityManager.Stub try { return broadcastIntentLocked(null, packageName, featureId, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, null, - OP_NONE, bOptions, serialized, sticky, -1, uid, realCallingUid, + null, OP_NONE, bOptions, serialized, sticky, -1, uid, realCallingUid, realCallingPid, userId, allowBackgroundActivityStarts, backgroundActivityStartsToken, broadcastAllowList); } finally { @@ -16824,10 +16829,11 @@ public class ActivityManagerService extends IActivityManager.Stub return ActivityManagerService.this.broadcastIntentLocked(null /*callerApp*/, null /*callerPackage*/, null /*callingFeatureId*/, intent, null /*resolvedType*/, resultTo, 0 /*resultCode*/, null /*resultData*/, - null /*resultExtras*/, requiredPermissions, null, AppOpsManager.OP_NONE, - bOptions /*options*/, serialized, false /*sticky*/, callingPid, - callingUid, callingUid, callingPid, userId, - false /*allowBackgroundStarts*/, + null /*resultExtras*/, requiredPermissions, + null /*excludedPermissions*/, null /*excludedPackages*/, + AppOpsManager.OP_NONE, bOptions /*options*/, serialized, + false /*sticky*/, callingPid, callingUid, callingUid, callingPid, + userId, false /*allowBackgroundStarts*/, null /*tokenNeededForBackgroundActivityStarts*/, appIdAllowList); } finally { Binder.restoreCallingIdentity(origId); @@ -16963,7 +16969,7 @@ public class ActivityManagerService extends IActivityManager.Stub | Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null, - null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, + null, null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) { intent = new Intent(Intent.ACTION_LOCALE_CHANGED); @@ -16978,8 +16984,8 @@ public class ActivityManagerService extends IActivityManager.Stub TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, PowerExemptionManager.REASON_LOCALE_CHANGED, ""); broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null, - null, OP_NONE, bOptions.toBundle(), false, false, MY_PID, SYSTEM_UID, - Binder.getCallingUid(), Binder.getCallingPid(), + null, null, OP_NONE, bOptions.toBundle(), false, false, MY_PID, + SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); } @@ -16994,8 +17000,9 @@ public class ActivityManagerService extends IActivityManager.Stub String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES }; broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, - permissions, null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, - Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); + permissions, null, null, OP_NONE, null, false, false, MY_PID, + SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), + UserHandle.USER_ALL); } } } @@ -17019,8 +17026,8 @@ public class ActivityManagerService extends IActivityManager.Stub } broadcastIntentLocked(null, null, null, intent, null, null, 0, null, null, null, - null, OP_NONE, null, false, false, -1, SYSTEM_UID, Binder.getCallingUid(), - Binder.getCallingPid(), UserHandle.USER_ALL); + null, null, OP_NONE, null, false, false, -1, SYSTEM_UID, + Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); } } @@ -17185,17 +17192,17 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public boolean isUidCurrentlyInstrumented(int uid) { + public int getInstrumentationSourceUid(int uid) { synchronized (mProcLock) { for (int i = mActiveInstrumentation.size() - 1; i >= 0; i--) { ActiveInstrumentation activeInst = mActiveInstrumentation.get(i); if (!activeInst.mFinished && activeInst.mTargetInfo != null && activeInst.mTargetInfo.uid == uid) { - return true; + return activeInst.mSourceUid; } } } - return false; + return INVALID_UID; } @Override diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 402491d8fe80..397a4420700e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -804,8 +804,8 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.flush(); Bundle bundle = mBroadcastOptions == null ? null : mBroadcastOptions.toBundle(); mInterface.broadcastIntentWithFeature(null, null, intent, null, receiver, 0, null, null, - requiredPermissions, null, android.app.AppOpsManager.OP_NONE, bundle, true, false, - mUserId); + requiredPermissions, null, null, android.app.AppOpsManager.OP_NONE, bundle, true, + false, mUserId); if (!mAsync) { receiver.waitForFinish(); } diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java index 5a234f5010dd..c09bb2d4dc28 100644 --- a/services/core/java/com/android/server/am/AppBatteryTracker.java +++ b/services/core/java/com/android/server/am/AppBatteryTracker.java @@ -67,6 +67,7 @@ import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; +import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; @@ -360,6 +361,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> mUidBatteryUsageInWindow.removeAt(i); } } + mInjector.getPolicy().onUserRemovedLocked(userId); } } @@ -368,6 +370,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> synchronized (mLock) { mUidBatteryUsage.delete(uid); mUidBatteryUsageInWindow.delete(uid); + mInjector.getPolicy().onUidRemovedLocked(uid); } } @@ -1208,6 +1211,14 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "current_drain_window"; /** + * The grace period after an interaction event with the app, if the background current + * drain goes beyond the threshold within that period, the system won't apply the + * restrictions. + */ + static final String KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD = + DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "current_drain_interaction_grace_period"; + + /** * Similar to {@link #KEY_BG_CURRENT_DRAIN_THRESHOLD_TO_RESTRICTED_BUCKET}, but a higher * value for the legitimate cases with higher background current drain. */ @@ -1310,6 +1321,11 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> final long mDefaultBgCurrentDrainWindowMs; /** + * Default value to {@link #mBgCurrentDrainInteractionGracePeriodMs}. + */ + final long mDefaultBgCurrentDrainInteractionGracePeriodMs; + + /** * Default value to the {@link #INDEX_HIGH_CURRENT_DRAIN_THRESHOLD} of * the {@link #mBgCurrentDrainRestrictedBucketThreshold}. */ @@ -1394,6 +1410,11 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> volatile long mBgCurrentDrainWindowMs; /** + * @see #KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD. + */ + volatile long mBgCurrentDrainInteractionGracePeriodMs; + + /** * @see #KEY_BG_CURRENT_DRAIN_MEDIA_PLAYBACK_MIN_DURATION. */ volatile long mBgCurrentDrainMediaPlaybackMinDuration; @@ -1455,6 +1476,12 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> private final SparseArray<Pair<long[], ImmutableBatteryUsage[]>> mHighBgBatteryPackages = new SparseArray<>(); + /** + * The timestamp of the last interaction, key is the UID. + */ + @GuardedBy("mLock") + private final SparseLongArray mLastInteractionTime = new SparseLongArray(); + @NonNull private final Object mLock; @@ -1478,6 +1505,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> isLowRamDeviceStatic() ? val[1] : val[0]; mDefaultBgCurrentDrainWindowMs = resources.getInteger( R.integer.config_bg_current_drain_window) * 1_000; + mDefaultBgCurrentDrainInteractionGracePeriodMs = mDefaultBgCurrentDrainWindowMs; val = getFloatArray(resources.obtainTypedArray( R.array.config_bg_current_drain_high_threshold_to_restricted_bucket)); mDefaultBgCurrentDrainRestrictedBucketHighThreshold = @@ -1511,6 +1539,8 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> mBgCurrentDrainBgRestrictedThreshold[1] = mDefaultBgCurrentDrainBgRestrictedHighThreshold; mBgCurrentDrainWindowMs = mDefaultBgCurrentDrainWindowMs; + mBgCurrentDrainInteractionGracePeriodMs = + mDefaultBgCurrentDrainInteractionGracePeriodMs; mBgCurrentDrainMediaPlaybackMinDuration = mDefaultBgCurrentDrainMediaPlaybackMinDuration; mBgCurrentDrainLocationMinDuration = mDefaultBgCurrentDrainLocationMinDuration; @@ -1542,6 +1572,9 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> case KEY_BG_CURRENT_DRAIN_WINDOW: updateCurrentDrainWindow(); break; + case KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD: + updateCurrentDrainInteractionGracePeriod(); + break; case KEY_BG_CURRENT_DRAIN_MEDIA_PLAYBACK_MIN_DURATION: updateCurrentDrainMediaPlaybackMinDuration(); break; @@ -1626,6 +1659,13 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> mDefaultBgCurrentDrainWindowMs); } + private void updateCurrentDrainInteractionGracePeriod() { + mBgCurrentDrainInteractionGracePeriodMs = DeviceConfig.getLong( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD, + mDefaultBgCurrentDrainInteractionGracePeriodMs); + } + private void updateCurrentDrainMediaPlaybackMinDuration() { mBgCurrentDrainMediaPlaybackMinDuration = DeviceConfig.getLong( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, @@ -1668,6 +1708,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> super.onSystemReady(); updateCurrentDrainThreshold(); updateCurrentDrainWindow(); + updateCurrentDrainInteractionGracePeriod(); updateCurrentDrainMediaPlaybackMinDuration(); updateCurrentDrainLocationMinDuration(); updateCurrentDrainEventDurationBasedThresholdEnabled(); @@ -1685,8 +1726,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> synchronized (mLock) { final Pair<long[], ImmutableBatteryUsage[]> pair = mHighBgBatteryPackages.get(uid); if (pair != null) { + final long lastInteractionTime = mLastInteractionTime.get(uid, 0L); final long[] ts = pair.first; - final int restrictedLevel = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] > 0 + final int restrictedLevel = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] + > (lastInteractionTime + mBgCurrentDrainInteractionGracePeriodMs) && mTracker.mAppRestrictionController.isAutoRestrictAbusiveAppEnabled() ? RESTRICTION_LEVEL_RESTRICTED_BUCKET : RESTRICTION_LEVEL_ADAPTIVE_BUCKET; @@ -1777,6 +1820,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> // We're already in the background restricted level, nothing more we could do. return; } + final long lastInteractionTime = mLastInteractionTime.get(uid, 0L); final long now = SystemClock.elapsedRealtime(); final int thresholdIndex = getCurrentDrainThresholdIndex(uid, now, mBgCurrentDrainWindowMs); @@ -1788,13 +1832,17 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> long[] ts = null; ImmutableBatteryUsage[] usages = null; if (rbPercentage >= rbThreshold) { - // New findings to us, track it and let the controller know. - ts = new long[TIME_STAMP_INDEX_LAST]; - ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now; - usages = new ImmutableBatteryUsage[TIME_STAMP_INDEX_LAST]; - usages[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage; - mHighBgBatteryPackages.put(uid, Pair.create(ts, usages)); - notifyController = excessive = true; + if (now > lastInteractionTime + mBgCurrentDrainInteractionGracePeriodMs) { + // New findings to us, track it and let the controller know. + ts = new long[TIME_STAMP_INDEX_LAST]; + ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now; + usages = new ImmutableBatteryUsage[TIME_STAMP_INDEX_LAST]; + usages[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage; + mHighBgBatteryPackages.put(uid, Pair.create(ts, usages)); + // It's beeen long enough since last interaction with this app. + notifyController = true; + } + excessive = true; } if (decoupleThresholds && brPercentage >= brThreshold) { if (ts == null) { @@ -1812,11 +1860,15 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> final long[] ts = pair.first; final long lastRestrictBucketTs = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET]; if (rbPercentage >= rbThreshold) { - if (lastRestrictBucketTs == 0) { - ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now; - pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage; + if (now > lastInteractionTime + mBgCurrentDrainInteractionGracePeriodMs) { + if (lastRestrictBucketTs == 0) { + ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now; + pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage; + } + // It's been long enough since last interaction with this app. + notifyController = true; } - notifyController = excessive = true; + excessive = true; } else { // It's actually back to normal, but we don't untrack it until // explicit user interactions, because the restriction could be the cause @@ -1833,7 +1885,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> && (now > lastRestrictBucketTs + mBgCurrentDrainWindowMs)); if (notifyController) { ts[TIME_STAMP_INDEX_BG_RESTRICTED] = now; - pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage; + pair.second[TIME_STAMP_INDEX_BG_RESTRICTED] = usage; } excessive = true; } else { @@ -1841,7 +1893,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> // user consent to unrestrict it; or if it's in restricted bucket level, // resetting this won't lift it from that level. ts[TIME_STAMP_INDEX_BG_RESTRICTED] = 0; - pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = null; + pair.second[TIME_STAMP_INDEX_BG_RESTRICTED] = null; // Now need to notify the controller. } } @@ -1902,6 +1954,7 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> void onUserInteractionStarted(String packageName, int uid) { boolean changed = false; synchronized (mLock) { + mLastInteractionTime.put(uid, SystemClock.elapsedRealtime()); final int curLevel = mTracker.mAppRestrictionController.getRestrictionLevel( uid, packageName); if (curLevel == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) { @@ -1940,9 +1993,30 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> @VisibleForTesting void reset() { mHighBgBatteryPackages.clear(); + mLastInteractionTime.clear(); mTracker.reset(); } + @GuardedBy("mLock") + void onUserRemovedLocked(final @UserIdInt int userId) { + for (int i = mHighBgBatteryPackages.size() - 1; i >= 0; i--) { + if (UserHandle.getUserId(mHighBgBatteryPackages.keyAt(i)) == userId) { + mHighBgBatteryPackages.removeAt(i); + } + } + for (int i = mLastInteractionTime.size() - 1; i >= 0; i--) { + if (UserHandle.getUserId(mLastInteractionTime.keyAt(i)) == userId) { + mLastInteractionTime.removeAt(i); + } + } + } + + @GuardedBy("mLock") + void onUidRemovedLocked(final int uid) { + mHighBgBatteryPackages.remove(uid); + mLastInteractionTime.delete(uid); + } + @Override void dump(PrintWriter pw, String prefix) { pw.print(prefix); @@ -1976,6 +2050,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> pw.print('='); pw.println(mBgCurrentDrainWindowMs); pw.print(prefix); + pw.print(KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD); + pw.print('='); + pw.println(mBgCurrentDrainInteractionGracePeriodMs); + pw.print(prefix); pw.print(KEY_BG_CURRENT_DRAIN_MEDIA_PLAYBACK_MIN_DURATION); pw.print('='); pw.println(mBgCurrentDrainMediaPlaybackMinDuration); diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index dd7fb84b46bf..d2e40c56c772 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -860,6 +860,21 @@ public final class BroadcastQueue { } } + // Check that the receiver does *not* belong to any of the excluded packages + if (!skip && r.excludedPackages != null && r.excludedPackages.length > 0) { + if (ArrayUtils.contains(r.excludedPackages, filter.packageName)) { + Slog.w(TAG, "Skipping delivery of excluded package " + + r.intent.toString() + + " to " + filter.receiverList.app + + " (pid=" + filter.receiverList.pid + + ", uid=" + filter.receiverList.uid + ")" + + " excludes package " + filter.packageName + + " due to sender " + r.callerPackage + + " (uid " + r.callingUid + ")"); + skip = true; + } + } + // If the broadcast also requires an app op check that as well. if (!skip && r.appOp != AppOpsManager.OP_NONE && mService.getAppOpsManager().noteOpNoThrow(r.appOp, @@ -1721,6 +1736,19 @@ public final class BroadcastQueue { } } + // Check that the receiver does *not* belong to any of the excluded packages + if (!skip && r.excludedPackages != null && r.excludedPackages.length > 0) { + if (ArrayUtils.contains(r.excludedPackages, component.getPackageName())) { + Slog.w(TAG, "Skipping delivery of excluded package " + + r.intent + " to " + + component.flattenToShortString() + + " excludes package " + component.getPackageName() + + " due to sender " + r.callerPackage + + " (uid " + r.callingUid + ")"); + skip = true; + } + } + if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && r.requiredPermissions != null && r.requiredPermissions.length > 0) { for (int i = 0; i < r.requiredPermissions.length; i++) { diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java index 5343af25fd39..19ffc1733f3d 100644 --- a/services/core/java/com/android/server/am/BroadcastRecord.java +++ b/services/core/java/com/android/server/am/BroadcastRecord.java @@ -75,6 +75,7 @@ final class BroadcastRecord extends Binder { final String resolvedType; // the resolved data type final String[] requiredPermissions; // permissions the caller has required final String[] excludedPermissions; // permissions to exclude + final String[] excludedPackages; // packages to exclude final int appOp; // an app op that is associated with this broadcast final BroadcastOptions options; // BroadcastOptions supplied by caller final List receivers; // contains BroadcastFilter and ResolveInfo @@ -162,6 +163,10 @@ final class BroadcastRecord extends Binder { pw.print(prefix); pw.print("excludedPermissions="); pw.print(Arrays.toString(excludedPermissions)); } + if (excludedPackages != null && excludedPackages.length > 0) { + pw.print(prefix); pw.print("excludedPackages="); + pw.print(Arrays.toString(excludedPackages)); + } if (options != null) { pw.print(prefix); pw.print("options="); pw.println(options.toBundle()); } @@ -260,7 +265,8 @@ final class BroadcastRecord extends Binder { Intent _intent, ProcessRecord _callerApp, String _callerPackage, @Nullable String _callerFeatureId, int _callingPid, int _callingUid, boolean _callerInstantApp, String _resolvedType, - String[] _requiredPermissions, String[] _excludedPermissions, int _appOp, + String[] _requiredPermissions, String[] _excludedPermissions, + String[] _excludedPackages, int _appOp, BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo, int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky, boolean _initialSticky, int _userId, boolean allowBackgroundActivityStarts, @@ -280,6 +286,7 @@ final class BroadcastRecord extends Binder { resolvedType = _resolvedType; requiredPermissions = _requiredPermissions; excludedPermissions = _excludedPermissions; + excludedPackages = _excludedPackages; appOp = _appOp; options = _options; receivers = _receivers; @@ -321,6 +328,7 @@ final class BroadcastRecord extends Binder { resolvedType = from.resolvedType; requiredPermissions = from.requiredPermissions; excludedPermissions = from.excludedPermissions; + excludedPackages = from.excludedPackages; appOp = from.appOp; options = from.options; receivers = from.receivers; @@ -381,9 +389,10 @@ final class BroadcastRecord extends Binder { // build a new BroadcastRecord around that single-target list BroadcastRecord split = new BroadcastRecord(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, - requiredPermissions, excludedPermissions, appOp, options, splitReceivers, resultTo, - resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId, - allowBackgroundActivityStarts, mBackgroundActivityStartsToken, timeoutExempt); + requiredPermissions, excludedPermissions, excludedPackages, appOp, options, + splitReceivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, + initialSticky, userId, allowBackgroundActivityStarts, + mBackgroundActivityStartsToken, timeoutExempt); split.enqueueTime = this.enqueueTime; split.enqueueRealTime = this.enqueueRealTime; split.enqueueClockTime = this.enqueueClockTime; @@ -459,7 +468,7 @@ final class BroadcastRecord extends Binder { for (int i = 0; i < uidSize; i++) { final BroadcastRecord br = new BroadcastRecord(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, - requiredPermissions, excludedPermissions, appOp, options, + requiredPermissions, excludedPermissions, excludedPackages, appOp, options, uid2receiverList.valueAt(i), null /* _resultTo */, resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId, allowBackgroundActivityStarts, mBackgroundActivityStartsToken, timeoutExempt); diff --git a/services/core/java/com/android/server/am/ComponentAliasResolver.java b/services/core/java/com/android/server/am/ComponentAliasResolver.java index 2db3b15e719d..01735a754c83 100644 --- a/services/core/java/com/android/server/am/ComponentAliasResolver.java +++ b/services/core/java/com/android/server/am/ComponentAliasResolver.java @@ -483,7 +483,7 @@ public class ComponentAliasResolver { @Nullable public Resolution<ResolveInfo> resolveReceiver(@NonNull Intent intent, @NonNull ResolveInfo receiver, @Nullable String resolvedType, - int packageFlags, int userId, int callingUid) { + int packageFlags, int userId, int callingUid, boolean forSend) { // Resolve this alias. final Resolution<ComponentName> resolution = resolveComponentAlias(() -> receiver.activityInfo.getComponentName()); @@ -506,8 +506,8 @@ public class ComponentAliasResolver { i.setPackage(null); i.setComponent(resolution.getTarget()); - List<ResolveInfo> resolved = pmi.queryIntentReceivers(i, - resolvedType, packageFlags, callingUid, userId); + List<ResolveInfo> resolved = pmi.queryIntentReceivers( + i, resolvedType, packageFlags, callingUid, userId, forSend); if (resolved == null || resolved.size() == 0) { // Target component not found. Slog.w(TAG, "Alias target " + target.flattenToShortString() + " not found"); diff --git a/services/core/java/com/android/server/am/DropboxRateLimiter.java b/services/core/java/com/android/server/am/DropboxRateLimiter.java index 18fb6a480f29..08a6719a016a 100644 --- a/services/core/java/com/android/server/am/DropboxRateLimiter.java +++ b/services/core/java/com/android/server/am/DropboxRateLimiter.java @@ -24,9 +24,14 @@ import com.android.internal.annotations.GuardedBy; /** Rate limiter for adding errors into dropbox. */ public class DropboxRateLimiter { - private static final long RATE_LIMIT_BUFFER_EXPIRY = 15 * DateUtils.SECOND_IN_MILLIS; - private static final long RATE_LIMIT_BUFFER_DURATION = 10 * DateUtils.SECOND_IN_MILLIS; - private static final int RATE_LIMIT_ALLOWED_ENTRIES = 5; + // After RATE_LIMIT_ALLOWED_ENTRIES have been collected (for a single breakdown of + // process/eventType) further entries will be rejected until RATE_LIMIT_BUFFER_DURATION has + // elapsed, after which the current count for this breakdown will be reset. + private static final long RATE_LIMIT_BUFFER_DURATION = 10 * DateUtils.MINUTE_IN_MILLIS; + // The time duration after which the rate limit buffer will be cleared. + private static final long RATE_LIMIT_BUFFER_EXPIRY = 3 * RATE_LIMIT_BUFFER_DURATION; + // The number of entries to keep per breakdown of process/eventType. + private static final int RATE_LIMIT_ALLOWED_ENTRIES = 6; @GuardedBy("mErrorClusterRecords") private final ArrayMap<String, ErrorRecord> mErrorClusterRecords = new ArrayMap<>(); diff --git a/services/core/java/com/android/server/am/PreBootBroadcaster.java b/services/core/java/com/android/server/am/PreBootBroadcaster.java index 756209824614..35f91ba1169b 100644 --- a/services/core/java/com/android/server/am/PreBootBroadcaster.java +++ b/services/core/java/com/android/server/am/PreBootBroadcaster.java @@ -124,7 +124,7 @@ public abstract class PreBootBroadcaster extends IIntentReceiver.Stub { REASON_PRE_BOOT_COMPLETED, ""); synchronized (mService) { mService.broadcastIntentLocked(null, null, null, mIntent, null, this, 0, null, null, - null, null, AppOpsManager.OP_NONE, bOptions.toBundle(), true, + null, null, null, AppOpsManager.OP_NONE, bOptions.toBundle(), true, false, ActivityManagerService.MY_PID, Process.SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), mUserId); } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index cceacd8c6fa3..a2048a347c7c 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2028,8 +2028,10 @@ public final class ProcessList { mService.mProcessList.handlePredecessorProcDied((ProcessRecord) msg.obj); break; case MSG_PROCESS_KILL_TIMEOUT: - mService.handleProcessStartOrKillTimeoutLocked((ProcessRecord) msg.obj, - /* isKillTimeout */ true); + synchronized (mService) { + mService.handleProcessStartOrKillTimeoutLocked((ProcessRecord) msg.obj, + /* isKillTimeout */ true); + } break; } } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index c04377389e8e..7ffea26638f5 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -3203,8 +3203,8 @@ class UserController implements Handler.Callback { synchronized (mService) { return mService.broadcastIntentLocked(null, null, null, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, null, - appOp, bOptions, ordered, sticky, callingPid, callingUid, realCallingUid, - realCallingPid, userId); + null, appOp, bOptions, ordered, sticky, callingPid, callingUid, + realCallingUid, realCallingPid, userId); } } diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java index d239c02d4529..27ce493f717f 100644 --- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java +++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java @@ -501,6 +501,7 @@ public final class AppHibernationService extends SystemService { null /* resultExtras */, requiredPermissions, null /* excludedPermissions */, + null /* excludedPackages */, OP_NONE, null /* bOptions */, false /* serialized */, @@ -519,6 +520,7 @@ public final class AppHibernationService extends SystemService { null /* resultExtras */, requiredPermissions, null /* excludedPermissions */, + null /* excludedPackages */, OP_NONE, null /* bOptions */, false /* serialized */, diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 36afb3677438..b9da144713cd 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -43,6 +43,7 @@ import static android.app.AppOpsManager.OP_FLAG_SELF; import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_PLAY_AUDIO; +import static android.app.AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD; import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_FAILED; @@ -2368,7 +2369,8 @@ public class AppOpsService extends IAppOpsService.Stub { ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class); boolean isSelfRequest = (filter & FILTER_BY_UID) != 0 && uid == Binder.getCallingUid(); if (!isSelfRequest) { - boolean isCallerInstrumented = ami.isUidCurrentlyInstrumented(Binder.getCallingUid()); + boolean isCallerInstrumented = + ami.getInstrumentationSourceUid(Binder.getCallingUid()) != Process.INVALID_UID; boolean isCallerSystem = Binder.getCallingPid() == Process.myPid(); boolean isCallerPermissionController; try { @@ -3848,7 +3850,7 @@ public class AppOpsService extends IAppOpsService.Stub { // the data gated by OP_RECORD_AUDIO. // // TODO: Revert this change before Android 12. - if (code == OP_RECORD_AUDIO_HOTWORD) { + if (code == OP_RECORD_AUDIO_HOTWORD || code == OP_RECEIVE_AMBIENT_TRIGGER_AUDIO) { int result = checkOperation(OP_RECORD_AUDIO, uid, packageName); if (result != AppOpsManager.MODE_ALLOWED) { return new SyncNotedAppOp(result, code, attributionTag, packageName); @@ -6924,7 +6926,8 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public @Nullable RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage() { ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class); - boolean isCallerInstrumented = ami.isUidCurrentlyInstrumented(Binder.getCallingUid()); + boolean isCallerInstrumented = + ami.getInstrumentationSourceUid(Binder.getCallingUid()) != Process.INVALID_UID; boolean isCallerSystem = Binder.getCallingPid() == Process.myPid(); if (!isCallerSystem && !isCallerInstrumented) { return null; diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java index 8de515d4d3e5..158092f33ee3 100644 --- a/services/core/java/com/android/server/appop/DiscreteRegistry.java +++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java @@ -34,6 +34,7 @@ import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXY; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA; import static android.app.AppOpsManager.OP_PHONE_CALL_MICROPHONE; +import static android.app.AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.flagsToString; import static android.app.AppOpsManager.getUidStateName; @@ -133,7 +134,7 @@ final class DiscreteRegistry { private static final String PROPERTY_DISCRETE_OPS_LIST = "discrete_history_ops_cslist"; private static final String DEFAULT_DISCRETE_OPS = OP_FINE_LOCATION + "," + OP_COARSE_LOCATION + "," + OP_CAMERA + "," + OP_RECORD_AUDIO + "," + OP_PHONE_CALL_MICROPHONE + "," - + OP_PHONE_CALL_CAMERA; + + OP_PHONE_CALL_CAMERA + "," + OP_RECEIVE_AMBIENT_TRIGGER_AUDIO; private static final long DEFAULT_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(7).toMillis(); private static final long MAXIMUM_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(30).toMillis(); private static final long DEFAULT_DISCRETE_HISTORY_QUANTIZATION = diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 3b715a218e5d..03dcc8d711d3 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -1289,8 +1289,11 @@ import java.util.concurrent.atomic.AtomicBoolean; break; case MSG_L_SET_BT_ACTIVE_DEVICE: synchronized (mDeviceStateLock) { - mDeviceInventory.onSetBtActiveDevice((BtDeviceInfo) msg.obj, - mAudioService.getBluetoothContextualVolumeStream()); + BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; + mDeviceInventory.onSetBtActiveDevice(btInfo, + (btInfo.mProfile != BluetoothProfile.LE_AUDIO || btInfo.mIsLeOutput) + ? mAudioService.getBluetoothContextualVolumeStream() + : AudioSystem.STREAM_DEFAULT); } break; case MSG_BT_HEADSET_CNCT_FAILED: diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index aed63ce5b2c6..8c0e2ddd8f3c 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -4146,19 +4146,8 @@ public class AudioService extends IAudioService.Stub { streamType = mStreamVolumeAlias[streamType]; - if (streamType == AudioSystem.STREAM_MUSIC) { - flags = updateFlagsForTvPlatform(flags); - synchronized (mHdmiClientLock) { - // Don't display volume UI on a TV Playback device when using absolute volume - if (mHdmiCecVolumeControlEnabled && mHdmiPlaybackClient != null - && (isAbsoluteVolumeDevice(device) - || isA2dpAbsoluteVolumeDevice(device))) { - flags &= ~AudioManager.FLAG_SHOW_UI; - } - } - if (isFullVolumeDevice(device)) { - flags &= ~AudioManager.FLAG_SHOW_UI; - } + if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) { + flags &= ~AudioManager.FLAG_SHOW_UI; } mVolumeController.postVolumeChanged(streamType, flags); } diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java index d8aa9aa6591e..0b9cb1977643 100644 --- a/services/core/java/com/android/server/audio/SpatializerHelper.java +++ b/services/core/java/com/android/server/audio/SpatializerHelper.java @@ -70,12 +70,6 @@ public class SpatializerHelper { private @Nullable SensorManager mSensorManager; //------------------------------------------------------------ - /** head tracker sensor name */ - // TODO: replace with generic head tracker sensor name. - // the current implementation refers to the "google" namespace but will be replaced - // by an android name at the next API level revision, it is not Google-specific. - private static final String HEADTRACKER_SENSOR = - "com.google.hardware.sensor.hid_dynamic.headtracker"; private static final SparseIntArray SPAT_MODE_FOR_DEVICE_TYPE = new SparseIntArray(15) { { @@ -125,6 +119,8 @@ public class SpatializerHelper { private int mCapableSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; private boolean mTransauralSupported = false; private boolean mBinauralSupported = false; + private boolean mIsHeadTrackingSupported = false; + private int[] mSupportedHeadTrackingModes = new int[0]; private int mActualHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED; private int mDesiredHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD; private boolean mHeadTrackerAvailable = false; @@ -137,9 +133,9 @@ public class SpatializerHelper { private int mSpatOutput = 0; private @Nullable ISpatializer mSpat; private @Nullable SpatializerCallback mSpatCallback; - private @Nullable SpatializerHeadTrackingCallback mSpatHeadTrackingCallback; + private @Nullable SpatializerHeadTrackingCallback mSpatHeadTrackingCallback = + new SpatializerHeadTrackingCallback(); private @Nullable HelperDynamicSensorCallback mDynSensorCallback; - private boolean mIsHeadTrackingSupported = false; // default attributes and format that determine basic availability of spatialization private static final AudioAttributes DEFAULT_ATTRIBUTES = new AudioAttributes.Builder() @@ -195,6 +191,8 @@ public class SpatializerHelper { return; } // capabilities of spatializer? + resetCapabilities(); + try { byte[] levels = spat.getSupportedLevels(); if (levels == null @@ -213,6 +211,38 @@ public class SpatializerHelper { break; } } + + // Note: head tracking support must be initialized before spatialization modes as + // addCompatibleAudioDevice() calls onRoutingUpdated() which will initialize the + // sensors according to mIsHeadTrackingSupported. + mIsHeadTrackingSupported = spat.isHeadTrackingSupported(); + if (mIsHeadTrackingSupported) { + final byte[] values = spat.getSupportedHeadTrackingModes(); + ArrayList<Integer> list = new ArrayList<>(0); + for (byte value : values) { + switch (value) { + case SpatializerHeadTrackingMode.OTHER: + case SpatializerHeadTrackingMode.DISABLED: + // not expected here, skip + break; + case SpatializerHeadTrackingMode.RELATIVE_WORLD: + case SpatializerHeadTrackingMode.RELATIVE_SCREEN: + list.add(headTrackingModeTypeToSpatializerInt(value)); + break; + default: + Log.e(TAG, "Unexpected head tracking mode:" + value, + new IllegalArgumentException("invalid mode")); + break; + } + } + mSupportedHeadTrackingModes = new int[list.size()]; + for (int i = 0; i < list.size(); i++) { + mSupportedHeadTrackingModes[i] = list.get(i); + } + mActualHeadTrackingMode = + headTrackingModeTypeToSpatializerInt(spat.getActualHeadTrackingMode()); + } + byte[] spatModes = spat.getSupportedModes(); for (byte mode : spatModes) { switch (mode) { @@ -258,7 +288,7 @@ public class SpatializerHelper { } // TODO read persisted states } catch (RemoteException e) { - /* capable level remains at NONE*/ + resetCapabilities(); } finally { if (spat != null) { try { @@ -285,12 +315,19 @@ public class SpatializerHelper { releaseSpat(); mState = STATE_UNINITIALIZED; mSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; - mCapableSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; mActualHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED; init(true); setSpatializerEnabledInt(featureEnabled); } + private void resetCapabilities() { + mCapableSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; + mBinauralSupported = false; + mTransauralSupported = false; + mIsHeadTrackingSupported = false; + mSupportedHeadTrackingModes = new int[0]; + } + //------------------------------------------------------ // routing monitoring synchronized void onRoutingUpdated() { @@ -852,18 +889,19 @@ public class SpatializerHelper { private void createSpat() { if (mSpat == null) { mSpatCallback = new SpatializerCallback(); - mSpatHeadTrackingCallback = new SpatializerHeadTrackingCallback(); mSpat = AudioSystem.getSpatializer(mSpatCallback); try { - mIsHeadTrackingSupported = mSpat.isHeadTrackingSupported(); //TODO: register heatracking callback only when sensors are registered if (mIsHeadTrackingSupported) { + mActualHeadTrackingMode = + headTrackingModeTypeToSpatializerInt(mSpat.getActualHeadTrackingMode()); mSpat.registerHeadTrackingCallback(mSpatHeadTrackingCallback); } } catch (RemoteException e) { Log.e(TAG, "Can't configure head tracking", e); mState = STATE_NOT_SUPPORTED; mCapableSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; + mActualHeadTrackingMode = Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED; } } } @@ -883,7 +921,6 @@ public class SpatializerHelper { } catch (RemoteException e) { Log.e(TAG, "Can't set release spatializer cleanly", e); } - mIsHeadTrackingSupported = false; mSpat = null; } } @@ -951,76 +988,11 @@ public class SpatializerHelper { } synchronized int[] getSupportedHeadTrackingModes() { - switch (mState) { - case STATE_UNINITIALIZED: - return new int[0]; - case STATE_NOT_SUPPORTED: - // return an empty list when Spatializer functionality is not supported - // because the list of head tracking modes you can set is actually empty - // as defined in {@link Spatializer#getSupportedHeadTrackingModes()} - return new int[0]; - case STATE_ENABLED_UNAVAILABLE: - case STATE_DISABLED_UNAVAILABLE: - case STATE_DISABLED_AVAILABLE: - case STATE_ENABLED_AVAILABLE: - if (mSpat == null) { - return new int[0]; - } - break; - } - // mSpat != null - try { - final byte[] values = mSpat.getSupportedHeadTrackingModes(); - ArrayList<Integer> list = new ArrayList<>(0); - for (byte value : values) { - switch (value) { - case SpatializerHeadTrackingMode.OTHER: - case SpatializerHeadTrackingMode.DISABLED: - // not expected here, skip - break; - case SpatializerHeadTrackingMode.RELATIVE_WORLD: - case SpatializerHeadTrackingMode.RELATIVE_SCREEN: - list.add(headTrackingModeTypeToSpatializerInt(value)); - break; - default: - Log.e(TAG, "Unexpected head tracking mode:" + value, - new IllegalArgumentException("invalid mode")); - break; - } - } - int[] modes = new int[list.size()]; - for (int i = 0; i < list.size(); i++) { - modes[i] = list.get(i); - } - return modes; - } catch (RemoteException e) { - Log.e(TAG, "Error calling getSupportedHeadTrackingModes", e); - return new int[] { Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED }; - } + return mSupportedHeadTrackingModes; } synchronized int getActualHeadTrackingMode() { - switch (mState) { - case STATE_UNINITIALIZED: - return Spatializer.HEAD_TRACKING_MODE_DISABLED; - case STATE_NOT_SUPPORTED: - return Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED; - case STATE_ENABLED_UNAVAILABLE: - case STATE_DISABLED_UNAVAILABLE: - case STATE_DISABLED_AVAILABLE: - case STATE_ENABLED_AVAILABLE: - if (mSpat == null) { - return Spatializer.HEAD_TRACKING_MODE_DISABLED; - } - break; - } - // mSpat != null - try { - return headTrackingModeTypeToSpatializerInt(mSpat.getActualHeadTrackingMode()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling getActualHeadTrackingMode", e); - return Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED; - } + return mActualHeadTrackingMode; } synchronized int getDesiredHeadTrackingMode() { @@ -1465,19 +1437,19 @@ public class SpatializerHelper { pw.println("\tmState:" + mState); pw.println("\tmSpatLevel:" + mSpatLevel); pw.println("\tmCapableSpatLevel:" + mCapableSpatLevel); - pw.println("\tmActualHeadTrackingMode:" - + Spatializer.headtrackingModeToString(mActualHeadTrackingMode)); - pw.println("\tmDesiredHeadTrackingMode:" - + Spatializer.headtrackingModeToString(mDesiredHeadTrackingMode)); - pw.println("\tsupports binaural:" + mBinauralSupported + " / transaural:" - + mTransauralSupported); + pw.println("\tmIsHeadTrackingSupported:" + mIsHeadTrackingSupported); StringBuilder modesString = new StringBuilder(); - int[] modes = getSupportedHeadTrackingModes(); - for (int mode : modes) { + for (int mode : mSupportedHeadTrackingModes) { modesString.append(Spatializer.headtrackingModeToString(mode)).append(" "); } pw.println("\tsupported head tracking modes:" + modesString); + pw.println("\tmDesiredHeadTrackingMode:" + + Spatializer.headtrackingModeToString(mDesiredHeadTrackingMode)); + pw.println("\tmActualHeadTrackingMode:" + + Spatializer.headtrackingModeToString(mActualHeadTrackingMode)); pw.println("\theadtracker available:" + mHeadTrackerAvailable); + pw.println("\tsupports binaural:" + mBinauralSupported + " / transaural:" + + mTransauralSupported); pw.println("\tmSpatOutput:" + mSpatOutput); pw.println("\tdevices:"); for (SADeviceState device : mSADevices) { @@ -1544,24 +1516,24 @@ public class SpatializerHelper { private int getHeadSensorHandleUpdateTracker() { int headHandle = -1; UUID routingDeviceUuid = mAudioService.getDeviceSensorUuid(ROUTING_DEVICES[0]); - List<Sensor> sensors = new ArrayList<Sensor>(0); - sensors.addAll(mSensorManager.getDynamicSensorList(Sensor.TYPE_HEAD_TRACKER)); - sensors.addAll(mSensorManager.getDynamicSensorList(Sensor.TYPE_DEVICE_PRIVATE_BASE)); + // We limit only to Sensor.TYPE_HEAD_TRACKER here to avoid confusion + // with gaming sensors. (Note that Sensor.TYPE_ROTATION_VECTOR + // and Sensor.TYPE_GAME_ROTATION_VECTOR are supported internally by + // SensorPoseProvider). + // Note: this is a dynamic sensor list right now. + List<Sensor> sensors = mSensorManager.getDynamicSensorList(Sensor.TYPE_HEAD_TRACKER); for (Sensor sensor : sensors) { - if (sensor.getType() == Sensor.TYPE_HEAD_TRACKER - || sensor.getStringType().equals(HEADTRACKER_SENSOR)) { - UUID uuid = sensor.getUuid(); - if (uuid.equals(routingDeviceUuid)) { - headHandle = sensor.getHandle(); - if (!setHasHeadTracker(ROUTING_DEVICES[0])) { - headHandle = -1; - } - break; - } - if (uuid.equals(UuidUtils.STANDALONE_UUID)) { - headHandle = sensor.getHandle(); - break; + final UUID uuid = sensor.getUuid(); + if (uuid.equals(routingDeviceUuid)) { + headHandle = sensor.getHandle(); + if (!setHasHeadTracker(ROUTING_DEVICES[0])) { + headHandle = -1; } + break; + } + if (uuid.equals(UuidUtils.STANDALONE_UUID)) { + headHandle = sensor.getHandle(); + // we do not break, perhaps we find a head tracker on device. } } return headHandle; diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java index de0a36a32b66..bf7a62aadc28 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java @@ -88,6 +88,10 @@ public class FaceResetLockoutClient extends HalClientMonitor<AidlSession> implem mCallback.onClientFinished(this, true /* success */); } + public boolean interruptsPrecedingClients() { + return true; + } + /** * Reset the local lockout state and notify any listeners. * diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java index 6e74d3622c1a..f29b9e823109 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java @@ -65,6 +65,10 @@ public class FaceResetLockoutClient extends HalClientMonitor<IBiometricsFace> { startHalOperation(); } + public boolean interruptsPrecedingClients() { + return true; + } + @Override protected void startHalOperation() { try { diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java index f90cba79dac2..c8148df9ea71 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java @@ -82,6 +82,10 @@ class FingerprintResetLockoutClient extends HalClientMonitor<AidlSession> implem } } + public boolean interruptsPrecedingClients() { + return true; + } + void onLockoutCleared() { resetLocalLockoutStateToNone(getSensorId(), getTargetUserId(), mLockoutCache, mLockoutResetDispatcher); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintResetLockoutClient.java index 559ca0633c42..843fcc8ee2a6 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintResetLockoutClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintResetLockoutClient.java @@ -50,6 +50,10 @@ public class FingerprintResetLockoutClient extends BaseClientMonitor { callback.onClientFinished(this, true /* success */); } + public boolean interruptsPrecedingClients() { + return true; + } + @Override public int getProtoEnum() { return BiometricsProto.CM_RESET_LOCKOUT; diff --git a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java index 28c7cad3b184..c37d4c6bcaef 100644 --- a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java +++ b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java @@ -18,6 +18,7 @@ package com.android.server.clipboard; import android.annotation.Nullable; import android.content.ClipData; +import android.os.PersistableBundle; import android.os.SystemProperties; import android.system.ErrnoException; import android.system.Os; @@ -25,6 +26,7 @@ import android.system.OsConstants; import android.system.VmSocketAddress; import android.util.Slog; +import java.io.EOFException; import java.io.FileDescriptor; import java.io.InterruptedIOException; import java.net.SocketException; @@ -93,16 +95,16 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> { } } - private byte[] receiveMessage() throws ErrnoException, InterruptedIOException { + private byte[] receiveMessage() throws ErrnoException, InterruptedIOException, EOFException { final byte[] lengthBits = new byte[4]; - Os.read(mPipe, lengthBits, 0, lengthBits.length); + readFully(mPipe, lengthBits, 0, lengthBits.length); final ByteBuffer bb = ByteBuffer.wrap(lengthBits); bb.order(ByteOrder.LITTLE_ENDIAN); final int msgLen = bb.getInt(); final byte[] msg = new byte[msgLen]; - Os.read(mPipe, msg, 0, msg.length); + readFully(mPipe, msg, 0, msg.length); return msg; } @@ -115,8 +117,8 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> { bb.order(ByteOrder.LITTLE_ENDIAN); bb.putInt(msg.length); - Os.write(fd, lengthBits, 0, lengthBits.length); - Os.write(fd, msg, 0, msg.length); + writeFully(fd, lengthBits, 0, lengthBits.length); + writeFully(fd, msg, 0, msg.length); } EmulatorClipboardMonitor(final Consumer<ClipData> setAndroidClipboard) { @@ -136,12 +138,15 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> { final ClipData clip = new ClipData("host clipboard", new String[]{"text/plain"}, new ClipData.Item(str)); + final PersistableBundle bundle = new PersistableBundle(); + bundle.putBoolean("com.android.systemui.SUPPRESS_CLIPBOARD_OVERLAY", true); + clip.getDescription().setExtras(bundle); if (LOG_CLIBOARD_ACCESS) { Slog.i(TAG, "Setting the guest clipboard to '" + str + "'"); } setAndroidClipboard.accept(clip); - } catch (ErrnoException | InterruptedIOException e) { + } catch (ErrnoException | EOFException | InterruptedIOException e) { closePipe(); } catch (InterruptedException | IllegalArgumentException e) { } @@ -182,4 +187,32 @@ class EmulatorClipboardMonitor implements Consumer<ClipData> { t.start(); } } + + private static void readFully(final FileDescriptor fd, + final byte[] buf, int offset, int size) + throws ErrnoException, InterruptedIOException, EOFException { + while (size > 0) { + final int r = Os.read(fd, buf, offset, size); + if (r > 0) { + offset += r; + size -= r; + } else { + throw new EOFException(); + } + } + } + + private static void writeFully(final FileDescriptor fd, + final byte[] buf, int offset, int size) + throws ErrnoException, InterruptedIOException { + while (size > 0) { + final int r = Os.write(fd, buf, offset, size); + if (r > 0) { + offset += r; + size -= r; + } else { + throw new ErrnoException("write", OsConstants.EIO); + } + } + } } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 9824b4e6c43a..f8a74f4f3f55 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -4176,7 +4176,11 @@ public class HdmiControlService extends SystemService { List<AudioDeviceAttributes> streamMusicDevices = getAudioManager().getDevicesForAttributes(STREAM_MUSIC_ATTRIBUTES); if (streamMusicDevices.contains(getAvcAudioOutputDevice())) { - setStreamMusicVolume(volume, AudioManager.FLAG_ABSOLUTE_VOLUME); + int flags = AudioManager.FLAG_ABSOLUTE_VOLUME; + if (isTvDevice()) { + flags |= AudioManager.FLAG_SHOW_UI; + } + setStreamMusicVolume(volume, flags); } } @@ -4190,8 +4194,11 @@ public class HdmiControlService extends SystemService { getAudioManager().getDevicesForAttributes(STREAM_MUSIC_ATTRIBUTES); if (streamMusicDevices.contains(getAvcAudioOutputDevice())) { int direction = mute ? AudioManager.ADJUST_MUTE : AudioManager.ADJUST_UNMUTE; - getAudioManager().adjustStreamVolume(AudioManager.STREAM_MUSIC, direction, - AudioManager.FLAG_ABSOLUTE_VOLUME); + int flags = AudioManager.FLAG_ABSOLUTE_VOLUME; + if (isTvDevice()) { + flags |= AudioManager.FLAG_SHOW_UI; + } + getAudioManager().adjustStreamVolume(AudioManager.STREAM_MUSIC, direction, flags); } } diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index e4e9d1d49a6e..b624d438a4f7 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -20,6 +20,7 @@ import static android.view.KeyEvent.KEYCODE_UNKNOWN; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityManagerInternal; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -860,6 +861,19 @@ public class InputManagerService extends IInputManager.Stub @Override // Binder call public boolean injectInputEvent(InputEvent event, int mode) { + return injectInputEventToTarget(event, mode, Process.INVALID_UID); + } + + @Override // Binder call + public boolean injectInputEventToTarget(InputEvent event, int mode, int targetUid) { + if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS, + "injectInputEvent()", true /*checkInstrumentationSource*/)) { + throw new SecurityException( + "Injecting input events requires the caller (or the source of the " + + "instrumentation, if any) to have the INJECT_EVENTS permission."); + } + // We are not checking if targetUid matches the callingUid, since having the permission + // already means you can inject into any window. Objects.requireNonNull(event, "event must not be null"); if (mode != InputEventInjectionSync.NONE && mode != InputEventInjectionSync.WAIT_FOR_FINISHED @@ -868,22 +882,39 @@ public class InputManagerService extends IInputManager.Stub } final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); + final boolean injectIntoUid = targetUid != Process.INVALID_UID; final int result; try { - result = mNative.injectInputEvent(event, pid, uid, mode, - INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT); + result = mNative.injectInputEvent(event, injectIntoUid, + targetUid, mode, INJECTION_TIMEOUT_MILLIS, + WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT); } finally { Binder.restoreCallingIdentity(ident); } switch (result) { - case InputEventInjectionResult.PERMISSION_DENIED: - Slog.w(TAG, "Input event injection from pid " + pid + " permission denied."); - throw new SecurityException( - "Injecting to another application requires INJECT_EVENTS permission"); case InputEventInjectionResult.SUCCEEDED: return true; + case InputEventInjectionResult.TARGET_MISMATCH: + if (!injectIntoUid) { + throw new IllegalStateException("Injection should not result in TARGET_MISMATCH" + + " when it is not targeted into to a specific uid."); + } + // TODO(b/228161340): Remove the fallback of targeting injection into all windows + // when the caller has the injection permission. + // Explicitly maintain the same behavior as previous versions of Android, where + // injection is allowed into all windows if the caller has the INJECT_EVENTS + // permission, even if it is targeting a certain uid. + if (checkCallingPermission(android.Manifest.permission.INJECT_EVENTS, + "injectInputEvent-target-mismatch-fallback")) { + Slog.w(TAG, "Targeted input event was not directed at a window owned by uid " + + targetUid + ". Falling back to injecting into all windows."); + return injectInputEventToTarget(event, mode, Process.INVALID_UID); + } + throw new IllegalArgumentException( + "Targeted input event injection from pid " + pid + + " was not directed at a window owned by uid " + + targetUid + "."); case InputEventInjectionResult.TIMED_OUT: Slog.w(TAG, "Input event injection from pid " + pid + " timed out."); return false; @@ -2780,8 +2811,12 @@ public class InputManagerService extends IInputManager.Stub } } } - private boolean checkCallingPermission(String permission, String func) { + return checkCallingPermission(permission, func, false /*checkInstrumentationSource*/); + } + + private boolean checkCallingPermission(String permission, String func, + boolean checkInstrumentationSource) { // Quick check: if the calling permission is me, it's all okay. if (Binder.getCallingPid() == Process.myPid()) { return true; @@ -2790,6 +2825,28 @@ public class InputManagerService extends IInputManager.Stub if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) { return true; } + + if (checkInstrumentationSource) { + final ActivityManagerInternal ami = + LocalServices.getService(ActivityManagerInternal.class); + Objects.requireNonNull(ami, "ActivityManagerInternal should not be null."); + final int instrumentationUid = ami.getInstrumentationSourceUid(Binder.getCallingUid()); + if (instrumentationUid != Process.INVALID_UID) { + // Clear the calling identity when checking if the instrumentation source has + // permission because PackageManager will deny all permissions to some callers, + // such as instant apps. + final long token = Binder.clearCallingIdentity(); + try { + if (mContext.checkPermission(permission, -1 /*pid*/, instrumentationUid) + == PackageManager.PERMISSION_GRANTED) { + return true; + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + } + String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() @@ -3035,13 +3092,6 @@ public class InputManagerService extends IInputManager.Stub // Native callback. @SuppressWarnings("unused") - private boolean checkInjectEventsPermission(int injectorPid, int injectorUid) { - return mContext.checkPermission(android.Manifest.permission.INJECT_EVENTS, - injectorPid, injectorUid) == PackageManager.PERMISSION_GRANTED; - } - - // Native callback. - @SuppressWarnings("unused") private void onPointerDownOutsideFocus(IBinder touchedToken) { mWindowManagerCallbacks.onPointerDownOutsideFocus(touchedToken); } @@ -3501,12 +3551,17 @@ public class InputManagerService extends IInputManager.Stub @Override public void sendInputEvent(InputEvent event, int policyFlags) { + if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS, + "sendInputEvent()")) { + throw new SecurityException( + "The INJECT_EVENTS permission is required for injecting input events."); + } Objects.requireNonNull(event, "event must not be null"); synchronized (mInputFilterLock) { if (!mDisconnected) { - mNative.injectInputEvent(event, 0, 0, - InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0, + mNative.injectInputEvent(event, false /* injectIntoUid */, -1 /* uid */, + InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0 /* timeout */, policyFlags | WindowManagerPolicy.FLAG_FILTERED); } } diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java index 81882d277a99..9cf80737e67d 100644 --- a/services/core/java/com/android/server/input/NativeInputManagerService.java +++ b/services/core/java/com/android/server/input/NativeInputManagerService.java @@ -70,7 +70,18 @@ public interface NativeInputManagerService { void setBlockUntrustedTouchesMode(int mode); - int injectInputEvent(InputEvent event, int pid, int uid, int syncMode, + /** + * Inject an input event into the system. + * + * @param event the input event to inject + * @param injectIntoUid true if the event should target windows owned by uid, false otherwise + * @param uid the uid whose windows should be targeted, if any + * @param syncMode {@link android.os.InputEventInjectionSync} + * @param timeoutMillis timeout to wait for input injection to complete, in milliseconds + * @param policyFlags defined in {@link android.view.WindowManagerPolicyConstants} + * @return {@link android.os.InputEventInjectionResult} + */ + int injectInputEvent(InputEvent event, boolean injectIntoUid, int uid, int syncMode, int timeoutMillis, int policyFlags); VerifiedInputEvent verifyInputEvent(InputEvent event); @@ -240,7 +251,8 @@ public interface NativeInputManagerService { public native void setBlockUntrustedTouchesMode(int mode); @Override - public native int injectInputEvent(InputEvent event, int pid, int uid, int syncMode, + public native int injectInputEvent(InputEvent event, boolean injectIntoUid, int uid, + int syncMode, int timeoutMillis, int policyFlags); @Override diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java index db17c1056e39..8180e66166d9 100644 --- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java +++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java @@ -64,7 +64,9 @@ final class HandwritingEventReceiverSurface { | InputConfig.INTERCEPTS_STYLUS | InputConfig.TRUSTED_OVERLAY; - // The touchable region of this input surface is not initially configured. + // Configure the surface to receive stylus events across the entire display. + mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */); + final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); t.setInputWindowInfo(mInputSurface, mWindowHandle); t.setLayer(mInputSurface, HANDWRITING_SURFACE_LAYER); @@ -81,10 +83,6 @@ final class HandwritingEventReceiverSurface { mWindowHandle.ownerUid = imeUid; mWindowHandle.inputConfig &= ~InputConfig.SPY; - // Update the touchable region so that the IME can intercept stylus events - // across the entire display. - mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */); - new SurfaceControl.Transaction() .setInputWindowInfo(mInputSurface, mWindowHandle) .apply(); diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java index a70677222506..f89b6aedf1f5 100644 --- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java +++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java @@ -91,7 +91,7 @@ final class HandwritingModeController { * InputEventReceiver that batches events according to the current thread's Choreographer. */ @UiThread - void initializeHandwritingSpy(int displayId, IBinder focusedWindowToken) { + void initializeHandwritingSpy(int displayId) { // When resetting, reuse resources if we are reinitializing on the same display. reset(displayId == mCurrentDisplayId); mCurrentDisplayId = displayId; @@ -115,12 +115,6 @@ final class HandwritingModeController { mHandwritingSurface = new HandwritingEventReceiverSurface( name, displayId, surface, channel); - // Configure the handwriting window to receive events over the focused window's bounds. - mWindowManagerInternal.replaceInputSurfaceTouchableRegionWithWindowCrop( - mHandwritingSurface.getSurface(), - mHandwritingSurface.getInputWindowHandle(), - focusedWindowToken); - // Use a dup of the input channel so that event processing can be paused by disposing the // event receiver without causing a fd hangup. mHandwritingEventReceiver = new BatchedInputEventReceiver.SimpleBatchedInputEventReceiver( @@ -149,7 +143,8 @@ final class HandwritingModeController { */ @UiThread @Nullable - HandwritingSession startHandwritingSession(int requestId, int imePid, int imeUid) { + HandwritingSession startHandwritingSession( + int requestId, int imePid, int imeUid, IBinder focusedWindowToken) { if (mHandwritingSurface == null) { Slog.e(TAG, "Cannot start handwriting session: Handwriting was not initialized."); return null; @@ -158,12 +153,20 @@ final class HandwritingModeController { Slog.e(TAG, "Cannot start handwriting session: Invalid request id: " + requestId); return null; } - if (!mRecordingGesture) { + if (!mRecordingGesture || mHandwritingBuffer.isEmpty()) { Slog.e(TAG, "Cannot start handwriting session: No stylus gesture is being recorded."); return null; } Objects.requireNonNull(mHandwritingEventReceiver, "Handwriting session was already transferred to IME."); + final MotionEvent downEvent = mHandwritingBuffer.get(0); + assert (downEvent.getActionMasked() == MotionEvent.ACTION_DOWN); + if (!mWindowManagerInternal.isPointInsideWindow( + focusedWindowToken, mCurrentDisplayId, downEvent.getRawX(), downEvent.getRawY())) { + Slog.e(TAG, "Cannot start handwriting session: " + + "Stylus gesture did not start inside the focused window."); + return null; + } if (DEBUG) Slog.d(TAG, "Starting handwriting session in display: " + mCurrentDisplayId); mInputManagerInternal.pilferPointers(mHandwritingSurface.getInputChannel().getToken()); @@ -226,13 +229,17 @@ final class HandwritingModeController { } if (!(ev instanceof MotionEvent)) { - Slog.e("Stylus", "Received non-motion event in stylus monitor."); + Slog.wtf(TAG, "Received non-motion event in stylus monitor."); return false; } final MotionEvent event = (MotionEvent) ev; if (!isStylusEvent(event)) { return false; } + if (event.getDisplayId() != mCurrentDisplayId) { + Slog.wtf(TAG, "Received stylus event associated with the incorrect display."); + return false; + } onStylusEvent(event); return true; diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index c759c645a318..ea2b1571c0ae 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -5118,9 +5118,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub case MSG_RESET_HANDWRITING: { synchronized (ImfLock.class) { if (mBindingController.supportsStylusHandwriting() - && getCurMethodLocked() != null && mCurFocusedWindow != null) { - mHwController.initializeHandwritingSpy( - mCurTokenDisplayId, mCurFocusedWindow); + && getCurMethodLocked() != null) { + mHwController.initializeHandwritingSpy(mCurTokenDisplayId); } else { mHwController.reset(); } @@ -5130,14 +5129,15 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub case MSG_START_HANDWRITING: synchronized (ImfLock.class) { IInputMethodInvoker curMethod = getCurMethodLocked(); - if (curMethod == null) { + if (curMethod == null || mCurFocusedWindow == null) { return true; } final HandwritingModeController.HandwritingSession session = mHwController.startHandwritingSession( msg.arg1 /*requestId*/, msg.arg2 /*pid*/, - mBindingController.getCurMethodUid()); + mBindingController.getCurMethodUid(), + mCurFocusedWindow); if (session == null) { Slog.e(TAG, "Failed to start handwriting session for requestId: " + msg.arg1); diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index ea99e7972887..f5c2bbc8d5a2 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -1587,6 +1587,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements if (isGpsEnabled()) { setGpsEnabled(false); updateEnabled(); + restartLocationRequest(); } } diff --git a/services/core/java/com/android/server/logcat/LogcatManagerService.java b/services/core/java/com/android/server/logcat/LogcatManagerService.java index 21beb964529a..1bcc21e66302 100644 --- a/services/core/java/com/android/server/logcat/LogcatManagerService.java +++ b/services/core/java/com/android/server/logcat/LogcatManagerService.java @@ -410,7 +410,8 @@ public final class LogcatManagerService extends SystemService { } private void processNewLogAccessRequest(LogAccessClient client) { - boolean isInstrumented = mActivityManagerInternal.isUidCurrentlyInstrumented(client.mUid); + boolean isInstrumented = mActivityManagerInternal.getInstrumentationSourceUid(client.mUid) + != android.os.Process.INVALID_UID; // The instrumented apks only run for testing, so we don't check user permission. if (isInstrumented) { diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 537385e8bfa3..3330211b0b92 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -58,6 +58,7 @@ import static android.content.Context.BIND_AUTO_CREATE; import static android.content.Context.BIND_FOREGROUND_SERVICE; import static android.content.Context.BIND_NOT_PERCEPTIBLE; import static android.content.pm.PackageManager.FEATURE_LEANBACK; +import static android.content.pm.PackageManager.FEATURE_TELECOM; import static android.content.pm.PackageManager.FEATURE_TELEVISION; import static android.content.pm.PackageManager.MATCH_ALL; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; @@ -655,10 +656,10 @@ public class NotificationManagerService extends SystemService { private int mWarnRemoteViewsSizeBytes; private int mStripRemoteViewsSizeBytes; - final boolean mEnableAppSettingMigration; private boolean mForceUserSetOnUpgrade; private MetricsLogger mMetricsLogger; + private NotificationChannelLogger mNotificationChannelLogger; private TriPredicate<String, Integer, String> mAllowedManagedServicePackages; private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable(); @@ -1998,12 +1999,6 @@ public class NotificationManagerService extends SystemService { mNotificationRecordLogger = notificationRecordLogger; mNotificationInstanceIdSequence = notificationInstanceIdSequence; Notification.processAllowlistToken = ALLOWLIST_TOKEN; - // TODO (b/194833441): remove when OS is ready for migration. This flag is checked once - // rather than having a settings observer because some of the behaviors (e.g. readXml) only - // happen on reboot - mEnableAppSettingMigration = Settings.Secure.getIntForUser( - getContext().getContentResolver(), - Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 0, USER_SYSTEM) == 1; } // TODO - replace these methods with new fields in the VisibleForTesting constructor @@ -2161,6 +2156,11 @@ public class NotificationManagerService extends SystemService { mAccessibilityManager = am; } + @VisibleForTesting + void setTelecomManager(TelecomManager tm) { + mTelecomManager = tm; + } + // TODO: All tests should use this init instead of the one-off setters above. @VisibleForTesting void init(WorkerHandler handler, RankingHandler rankingHandler, @@ -2178,7 +2178,7 @@ public class NotificationManagerService extends SystemService { TelephonyManager telephonyManager, ActivityManagerInternal ami, MultiRateLimiter toastRateLimiter, PermissionHelper permissionHelper, UsageStatsManagerInternal usageStatsManagerInternal, - TelecomManager telecomManager) { + TelecomManager telecomManager, NotificationChannelLogger channelLogger) { mHandler = handler; Resources resources = getContext().getResources(); mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(), @@ -2275,12 +2275,13 @@ public class NotificationManagerService extends SystemService { } }); mPermissionHelper = permissionHelper; + mNotificationChannelLogger = channelLogger; mPreferencesHelper = new PreferencesHelper(getContext(), mPackageManagerClient, mRankingHandler, mZenModeHelper, mPermissionHelper, - new NotificationChannelLoggerImpl(), + mNotificationChannelLogger, mAppOps, new SysUiStatsEvent.BuilderFactory()); mRankingHelper = new RankingHelper(getContext(), @@ -2362,9 +2363,6 @@ public class NotificationManagerService extends SystemService { mNotificationEffectsEnabledForAutomotive = resources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive); - mPreferencesHelper.lockChannelsForOEM(getContext().getResources().getStringArray( - com.android.internal.R.array.config_nonBlockableNotificationPackages)); - mZenModeHelper.setPriorityOnlyDndExemptPackages(getContext().getResources().getStringArray( com.android.internal.R.array.config_priorityOnlyDndExemptPackages)); @@ -2504,10 +2502,11 @@ public class NotificationManagerService extends SystemService { LocalServices.getService(ActivityManagerInternal.class), createToastRateLimiter(), new PermissionHelper(LocalServices.getService( PermissionManagerServiceInternal.class), AppGlobals.getPackageManager(), - AppGlobals.getPermissionManager(), mEnableAppSettingMigration, + AppGlobals.getPermissionManager(), mForceUserSetOnUpgrade), LocalServices.getService(UsageStatsManagerInternal.class), - getContext().getSystemService(TelecomManager.class)); + getContext().getSystemService(TelecomManager.class), + new NotificationChannelLoggerImpl()); publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL); @@ -2799,7 +2798,7 @@ public class NotificationManagerService extends SystemService { } } - private void updateNotificationChannelInt(String pkg, int uid, NotificationChannel channel, + void updateNotificationChannelInt(String pkg, int uid, NotificationChannel channel, boolean fromListener) { if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) { // cancel @@ -2821,11 +2820,9 @@ public class NotificationManagerService extends SystemService { mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), true); mPreferencesHelper.updateNotificationChannel(pkg, uid, channel, true); - if (mEnableAppSettingMigration) { - if (mPreferencesHelper.onlyHasDefaultChannel(pkg, uid)) { - mPermissionHelper.setNotificationPermission(pkg, UserHandle.getUserId(uid), - channel.getImportance() != IMPORTANCE_NONE, true); - } + if (mPreferencesHelper.onlyHasDefaultChannel(pkg, uid)) { + mPermissionHelper.setNotificationPermission(pkg, UserHandle.getUserId(uid), + channel.getImportance() != IMPORTANCE_NONE, true); } maybeNotifyChannelOwner(pkg, uid, preUpdate, channel); @@ -3474,36 +3471,19 @@ public class NotificationManagerService extends SystemService { @Override public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) { enforceSystemOrSystemUI("setNotificationsEnabledForPackage"); - if (mEnableAppSettingMigration) { - boolean wasEnabled = mPermissionHelper.hasPermission(uid); - if (wasEnabled == enabled) { - return; - } - mPermissionHelper.setNotificationPermission( - pkg, UserHandle.getUserId(uid), enabled, true); - sendAppBlockStateChangedBroadcast(pkg, uid, !enabled); - } else { - synchronized (mNotificationLock) { - boolean wasEnabled = mPreferencesHelper.getImportance(pkg, uid) - != NotificationManager.IMPORTANCE_NONE; - - if (wasEnabled == enabled) { - return; - } - } - - mPreferencesHelper.setEnabled(pkg, uid, enabled); - // TODO (b/194833441): this is being ignored by app ops now that the permission - // exists, so send the broadcast manually - mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg, - enabled ? MODE_ALLOWED : AppOpsManager.MODE_IGNORED); - - sendAppBlockStateChangedBroadcast(pkg, uid, !enabled); + boolean wasEnabled = mPermissionHelper.hasPermission(uid); + if (wasEnabled == enabled) { + return; } + mPermissionHelper.setNotificationPermission( + pkg, UserHandle.getUserId(uid), enabled, true); + sendAppBlockStateChangedBroadcast(pkg, uid, !enabled); + mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES) .setType(MetricsEvent.TYPE_ACTION) .setPackageName(pkg) .setSubtype(enabled ? 1 : 0)); + mNotificationChannelLogger.logAppNotificationsAllowed(uid, pkg, enabled); // Now, cancel any outstanding notifications that are part of a just-disabled app if (!enabled) { cancelAllNotificationsInt(MY_UID, MY_PID, pkg, null, 0, 0, true, @@ -3529,8 +3509,6 @@ public class NotificationManagerService extends SystemService { public void setNotificationsEnabledWithImportanceLockForPackage( String pkg, int uid, boolean enabled) { setNotificationsEnabledForPackage(pkg, uid, enabled); - - mPreferencesHelper.setAppImportanceLocked(pkg, uid); } /** @@ -3646,14 +3624,10 @@ public class NotificationManagerService extends SystemService { @Override public int getPackageImportance(String pkg) { checkCallerIsSystemOrSameApp(pkg); - if (mEnableAppSettingMigration) { - if (mPermissionHelper.hasPermission(Binder.getCallingUid())) { - return IMPORTANCE_DEFAULT; - } else { - return IMPORTANCE_NONE; - } + if (mPermissionHelper.hasPermission(Binder.getCallingUid())) { + return IMPORTANCE_DEFAULT; } else { - return mPreferencesHelper.getImportance(pkg, Binder.getCallingUid()); + return IMPORTANCE_NONE; } } @@ -5885,8 +5859,7 @@ public class NotificationManagerService extends SystemService { NotificationRecord createAutoGroupSummary(int userId, String pkg, String triggeringKey, boolean needsOngoingFlag) { NotificationRecord summaryRecord = null; - boolean isPermissionFixed = mPermissionHelper.isMigrationEnabled() - ? mPermissionHelper.isPermissionFixed(pkg, userId) : false; + boolean isPermissionFixed = mPermissionHelper.isPermissionFixed(pkg, userId); synchronized (mNotificationLock) { NotificationRecord notificationRecord = mNotificationsByKey.get(triggeringKey); if (notificationRecord == null) { @@ -5895,10 +5868,6 @@ public class NotificationManagerService extends SystemService { return null; } NotificationChannel channel = notificationRecord.getChannel(); - boolean isImportanceFixed = mPermissionHelper.isMigrationEnabled() - ? isPermissionFixed - : (channel.isImportanceLockedByOEM() - || channel.isImportanceLockedByCriticalDeviceFunction()); final StatusBarNotification adjustedSbn = notificationRecord.getSbn(); userId = adjustedSbn.getUser().getIdentifier(); int uid = adjustedSbn.getUid(); @@ -5944,7 +5913,7 @@ public class NotificationManagerService extends SystemService { System.currentTimeMillis()); summaryRecord = new NotificationRecord(getContext(), summarySbn, notificationRecord.getChannel()); - summaryRecord.setImportanceFixed(isImportanceFixed); + summaryRecord.setImportanceFixed(isPermissionFixed); summaryRecord.setIsAppImportanceLocked( notificationRecord.getIsAppImportanceLocked()); summaries.put(pkg, summarySbn.getKey()); @@ -5992,10 +5961,6 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting protected ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> getAllUsersNotificationPermissions() { - // don't bother if migration is not enabled - if (!mEnableAppSettingMigration) { - return null; - } ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> allPermissions = new ArrayMap<>(); final List<UserInfo> allUsers = mUm.getUsers(); // for each of these, get the package notification permissions that are associated @@ -6509,13 +6474,8 @@ public class NotificationManagerService extends SystemService { + ", notificationUid=" + notificationUid + ", notification=" + notification; Slog.e(TAG, noChannelStr); - boolean appNotificationsOff; - if (mEnableAppSettingMigration) { - appNotificationsOff = !mPermissionHelper.hasPermission(notificationUid); - } else { - appNotificationsOff = mPreferencesHelper.getImportance(pkg, notificationUid) - == NotificationManager.IMPORTANCE_NONE; - } + boolean appNotificationsOff = !mPermissionHelper.hasPermission(notificationUid); + if (!appNotificationsOff) { doChannelWarningToast(notificationUid, @@ -6527,14 +6487,11 @@ public class NotificationManagerService extends SystemService { } final NotificationRecord r = new NotificationRecord(getContext(), n, channel); - r.setIsAppImportanceLocked(mPreferencesHelper.getIsAppImportanceLocked(pkg, callingUid)); + r.setIsAppImportanceLocked(mPermissionHelper.isPermissionUserSet(pkg, userId)); r.setPostSilently(postSilently); r.setFlagBubbleRemoved(false); r.setPkgAllowedAsConvo(mMsgPkgsAllowedAsConvos.contains(pkg)); - boolean isImportanceFixed = mPermissionHelper.isMigrationEnabled() - ? mPermissionHelper.isPermissionFixed(pkg, userId) - : (channel.isImportanceLockedByOEM() - || channel.isImportanceLockedByCriticalDeviceFunction()); + boolean isImportanceFixed = mPermissionHelper.isPermissionFixed(pkg, userId); r.setImportanceFixed(isImportanceFixed); if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) { @@ -6978,19 +6935,20 @@ public class NotificationManagerService extends SystemService { private boolean isCallNotification(String pkg, int uid) { final long identity = Binder.clearCallingIdentity(); try { - return mTelecomManager.isInManagedCall() || mTelecomManager.isInSelfManagedCall( - pkg, UserHandle.getUserHandleForUid(uid)); + if (mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM) + && mTelecomManager != null) { + return mTelecomManager.isInManagedCall() + || mTelecomManager.isInSelfManagedCall( + pkg, UserHandle.getUserHandleForUid(uid)); + } + return false; } finally { Binder.restoreCallingIdentity(identity); } } private boolean areNotificationsEnabledForPackageInt(String pkg, int uid) { - if (mEnableAppSettingMigration) { - return mPermissionHelper.hasPermission(uid); - } else { - return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE; - } + return mPermissionHelper.hasPermission(uid); } protected int getNotificationCount(String pkg, int userId, int excludedId, @@ -7405,6 +7363,7 @@ public class NotificationManagerService extends SystemService { @Override public void run() { boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid); + boolean isCallNotification = isCallNotification(pkg, uid); synchronized (mNotificationLock) { try { NotificationRecord r = null; @@ -7423,8 +7382,10 @@ public class NotificationManagerService extends SystemService { final StatusBarNotification n = r.getSbn(); final Notification notification = n.getNotification(); + boolean isCallNotificationAndCorrectStyle = isCallNotification + && notification.isStyle(Notification.CallStyle.class); - if (!notification.isMediaNotification() + if (!(notification.isMediaNotification() || isCallNotificationAndCorrectStyle) && (appBanned || isRecordBlockedLocked(r))) { mUsageStats.registerBlocked(r); if (DBG) { diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index f979343248f1..cbaf485c077f 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -1089,7 +1089,7 @@ public final class NotificationRecord { } /** - * @see PreferencesHelper#getIsAppImportanceLocked(String, int) + * @see PermissionHelper#isPermissionUserSet(String, int) */ public boolean getIsAppImportanceLocked() { return mIsAppImportanceLocked; diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java index b4230c11bcab..b2fee1e8b545 100644 --- a/services/core/java/com/android/server/notification/PermissionHelper.java +++ b/services/core/java/com/android/server/notification/PermissionHelper.java @@ -55,30 +55,21 @@ public final class PermissionHelper { private final PermissionManagerServiceInternal mPmi; private final IPackageManager mPackageManager; private final IPermissionManager mPermManager; - // TODO (b/194833441): Remove when the migration is enabled - private final boolean mMigrationEnabled; private final boolean mForceUserSetOnUpgrade; public PermissionHelper(PermissionManagerServiceInternal pmi, IPackageManager packageManager, - IPermissionManager permManager, boolean migrationEnabled, - boolean forceUserSetOnUpgrade) { + IPermissionManager permManager, boolean forceUserSetOnUpgrade) { mPmi = pmi; mPackageManager = packageManager; mPermManager = permManager; - mMigrationEnabled = migrationEnabled; mForceUserSetOnUpgrade = forceUserSetOnUpgrade; } - public boolean isMigrationEnabled() { - return mMigrationEnabled; - } - /** * Returns whether the given uid holds the notification permission. Must not be called * with a lock held. */ public boolean hasPermission(int uid) { - assertFlag(); final long callingId = Binder.clearCallingIdentity(); try { return mPmi.checkPostNotificationsPermissionGrantedOrLegacyAccess(uid) @@ -93,7 +84,6 @@ public final class PermissionHelper { * Must not be called with a lock held. Format: uid, packageName */ Set<Pair<Integer, String>> getAppsRequestingPermission(int userId) { - assertFlag(); Set<Pair<Integer, String>> requested = new HashSet<>(); List<PackageInfo> pkgs = getInstalledPackages(userId); for (PackageInfo pi : pkgs) { @@ -131,7 +121,6 @@ public final class PermissionHelper { * with a lock held. Format: uid, packageName. */ Set<Pair<Integer, String>> getAppsGrantedPermission(int userId) { - assertFlag(); Set<Pair<Integer, String>> granted = new HashSet<>(); ParceledListSlice<PackageInfo> parceledList = null; try { @@ -153,7 +142,6 @@ public final class PermissionHelper { public @NonNull ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> getNotificationPermissionValues(int userId) { - assertFlag(); ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>(); Set<Pair<Integer, String>> allRequestingUids = getAppsRequestingPermission(userId); Set<Pair<Integer, String>> allApprovedUids = getAppsGrantedPermission(userId); @@ -180,7 +168,6 @@ public final class PermissionHelper { */ public void setNotificationPermission(String packageName, @UserIdInt int userId, boolean grant, boolean userSet, boolean reviewRequired) { - assertFlag(); final long callingId = Binder.clearCallingIdentity(); try { // Do not change the permission if the package doesn't request it, do not change fixed @@ -221,7 +208,6 @@ public final class PermissionHelper { * restoring a pre-T backup on a T+ device */ public void setNotificationPermission(PackagePermission pkgPerm) { - assertFlag(); if (pkgPerm == null || pkgPerm.packageName == null) { return; } @@ -233,7 +219,6 @@ public final class PermissionHelper { } public boolean isPermissionFixed(String packageName, @UserIdInt int userId) { - assertFlag(); final long callingId = Binder.clearCallingIdentity(); try { try { @@ -251,7 +236,6 @@ public final class PermissionHelper { } boolean isPermissionUserSet(String packageName, @UserIdInt int userId) { - assertFlag(); final long callingId = Binder.clearCallingIdentity(); try { try { @@ -269,7 +253,6 @@ public final class PermissionHelper { } boolean isPermissionGrantedByDefaultOrRole(String packageName, @UserIdInt int userId) { - assertFlag(); final long callingId = Binder.clearCallingIdentity(); try { try { @@ -288,7 +271,6 @@ public final class PermissionHelper { private boolean packageRequestsNotificationPermission(String packageName, @UserIdInt int userId) { - assertFlag(); try { String[] permissions = mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS, userId).requestedPermissions; @@ -299,12 +281,6 @@ public final class PermissionHelper { return false; } - private void assertFlag() { - if (!mMigrationEnabled) { - throw new IllegalStateException("Method called without checking flag value"); - } - } - public static class PackagePermission { public final String packageName; public final @UserIdInt int userId; diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index ef3c770f125b..4e3fbaa18870 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -209,11 +209,7 @@ public class PreferencesHelper implements RankingConfig { mAppOps = appOpsManager; mStatsEventBuilderFactory = statsEventBuilderFactory; - if (mPermissionHelper.isMigrationEnabled()) { - XML_VERSION = 4; - } else { - XML_VERSION = 2; - } + XML_VERSION = 4; updateBadgingEnabled(); updateBubblesEnabled(); @@ -230,8 +226,7 @@ public class PreferencesHelper implements RankingConfig { final int xmlVersion = parser.getAttributeInt(null, ATT_VERSION, -1); boolean upgradeForBubbles = xmlVersion == XML_VERSION_BUBBLES_UPGRADE; - boolean migrateToPermission = (xmlVersion < XML_VERSION_NOTIF_PERMISSION) - && mPermissionHelper.isMigrationEnabled(); + boolean migrateToPermission = (xmlVersion < XML_VERSION_NOTIF_PERMISSION); if (xmlVersion < XML_VERSION_REVIEW_PERMISSIONS_NOTIFICATION) { // make a note that we should show the notification at some point. // it shouldn't be possible for the user to already have seen it, as the XML version @@ -393,8 +388,6 @@ public class PreferencesHelper implements RankingConfig { hasUserConfiguredSettings(r)); pkgPerms.add(pkgPerm); } - } else if (!mPermissionHelper.isMigrationEnabled()) { - r.importance = appImportance; } } catch (Exception e) { Slog.w(TAG, "Failed to restore pkg", e); @@ -417,16 +410,8 @@ public class PreferencesHelper implements RankingConfig { } else { channel.populateFromXml(parser); } - if (!mPermissionHelper.isMigrationEnabled()) { - channel.setImportanceLockedByCriticalDeviceFunction( - r.defaultAppLockedImportance); - channel.setImportanceLockedByOEM(r.oemLockedImportance); - if (!channel.isImportanceLockedByOEM()) { - if (r.oemLockedChannels.contains(channel.getId())) { - channel.setImportanceLockedByOEM(true); - } - } - } + channel.setImportanceLockedByCriticalDeviceFunction( + r.defaultAppLockedImportance); if (isShortcutOk(channel) && isDeletionOk(channel)) { r.channels.put(id, channel); @@ -604,7 +589,7 @@ public class PreferencesHelper implements RankingConfig { out.endTag(null, TAG_STATUS_ICONS); } ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>(); - if (mPermissionHelper.isMigrationEnabled() && forBackup) { + if (forBackup) { notifPermissions = mPermissionHelper.getNotificationPermissionValues(userId); } @@ -736,28 +721,6 @@ public class PreferencesHelper implements RankingConfig { } } - /** - * Gets importance. - */ - @Override - public int getImportance(String packageName, int uid) { - synchronized (mPackagePreferences) { - return getOrCreatePackagePreferencesLocked(packageName, uid).importance; - } - } - - /** - * Returns whether the importance of the corresponding notification is user-locked and shouldn't - * be adjusted by an assistant (via means of a blocking helper, for example). For the channel - * locking field, see {@link NotificationChannel#USER_LOCKED_IMPORTANCE}. - */ - public boolean getIsAppImportanceLocked(String packageName, int uid) { - synchronized (mPackagePreferences) { - int userLockedFields = getOrCreatePackagePreferencesLocked(packageName, uid).lockedAppFields; - return (userLockedFields & LockableAppFields.USER_LOCKED_IMPORTANCE) != 0; - } - } - @Override public boolean canShowBadge(String packageName, int uid) { synchronized (mPackagePreferences) { @@ -1043,16 +1006,10 @@ public class PreferencesHelper implements RankingConfig { : NotificationChannel.DEFAULT_ALLOW_BUBBLE); } clearLockedFieldsLocked(channel); - if (!mPermissionHelper.isMigrationEnabled()) { - channel.setImportanceLockedByOEM(r.oemLockedImportance); - if (!channel.isImportanceLockedByOEM()) { - if (r.oemLockedChannels.contains(channel.getId())) { - channel.setImportanceLockedByOEM(true); - } - } - channel.setImportanceLockedByCriticalDeviceFunction( - r.defaultAppLockedImportance); - } + + channel.setImportanceLockedByCriticalDeviceFunction( + r.defaultAppLockedImportance); + if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) { channel.setLockscreenVisibility( NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE); @@ -1133,33 +1090,15 @@ public class PreferencesHelper implements RankingConfig { updatedChannel.unlockFields(updatedChannel.getUserLockedFields()); } - if (mPermissionHelper.isMigrationEnabled()) { - if (mPermissionHelper.isPermissionFixed(r.pkg, UserHandle.getUserId(r.uid)) - && !(channel.isBlockable() || channel.getImportance() == IMPORTANCE_NONE)) { - updatedChannel.setImportance(channel.getImportance()); - } - } else { - // no importance updates are allowed if OEM blocked it - updatedChannel.setImportanceLockedByOEM(channel.isImportanceLockedByOEM()); - if (updatedChannel.isImportanceLockedByOEM()) { - updatedChannel.setImportance(channel.getImportance()); - } - updatedChannel.setImportanceLockedByCriticalDeviceFunction( - r.defaultAppLockedImportance); - if (updatedChannel.isImportanceLockedByCriticalDeviceFunction() - && updatedChannel.getImportance() == IMPORTANCE_NONE) { - updatedChannel.setImportance(channel.getImportance()); - } + if ((mPermissionHelper.isPermissionFixed(r.pkg, UserHandle.getUserId(r.uid)) + || channel.isImportanceLockedByCriticalDeviceFunction()) + && !(channel.isBlockable() || channel.getImportance() == IMPORTANCE_NONE)) { + updatedChannel.setImportance(channel.getImportance()); } r.channels.put(updatedChannel.getId(), updatedChannel); if (onlyHasDefaultChannel(pkg, uid)) { - if (!mPermissionHelper.isMigrationEnabled()) { - // copy settings to app level so they are inherited by new channels - // when the app migrates - r.importance = updatedChannel.getImportance(); - } r.priority = updatedChannel.canBypassDnd() ? Notification.PRIORITY_MAX : Notification.PRIORITY_DEFAULT; r.visibility = updatedChannel.getLockscreenVisibility(); @@ -1328,61 +1267,8 @@ public class PreferencesHelper implements RankingConfig { mHideSilentStatusBarIcons = hide; } - public void lockChannelsForOEM(String[] appOrChannelList) { - if (mPermissionHelper.isMigrationEnabled()) { - return; - } - if (appOrChannelList == null) { - return; - } - for (String appOrChannel : appOrChannelList) { - if (!TextUtils.isEmpty(appOrChannel)) { - String[] appSplit = appOrChannel.split(NON_BLOCKABLE_CHANNEL_DELIM); - if (appSplit != null && appSplit.length > 0) { - String appName = appSplit[0]; - String channelId = appSplit.length == 2 ? appSplit[1] : null; - - synchronized (mPackagePreferences) { - boolean foundApp = false; - for (PackagePreferences r : mPackagePreferences.values()) { - if (r.pkg.equals(appName)) { - foundApp = true; - if (channelId == null) { - // lock all channels for the app - r.oemLockedImportance = true; - for (NotificationChannel channel : r.channels.values()) { - channel.setImportanceLockedByOEM(true); - } - } else { - NotificationChannel channel = r.channels.get(channelId); - if (channel != null) { - channel.setImportanceLockedByOEM(true); - } - // Also store the locked channels on the record, so they aren't - // temporarily lost when data is cleared on the package - r.oemLockedChannels.add(channelId); - } - } - } - if (!foundApp) { - List<String> channels = - mOemLockedApps.getOrDefault(appName, new ArrayList<>()); - if (channelId != null) { - channels.add(channelId); - } - mOemLockedApps.put(appName, channels); - } - } - } - } - } - } - public void updateDefaultApps(int userId, ArraySet<String> toRemove, ArraySet<Pair<String, Integer>> toAdd) { - if (mPermissionHelper.isMigrationEnabled()) { - return; - } synchronized (mPackagePreferences) { for (PackagePreferences p : mPackagePreferences.values()) { if (userId == UserHandle.getUserId(p.uid)) { @@ -1802,20 +1688,8 @@ public class PreferencesHelper implements RankingConfig { } for (int i = candidatePkgs.size() - 1; i >= 0; i--) { Pair<String, Integer> app = candidatePkgs.valueAt(i); - if (mPermissionHelper.isMigrationEnabled()) { - if (!mPermissionHelper.hasPermission(app.second)) { - candidatePkgs.removeAt(i); - } - } else { - synchronized (mPackagePreferences) { - PackagePreferences r = getPackagePreferencesLocked(app.first, app.second); - if (r == null) { - continue; - } - if (r.importance == IMPORTANCE_NONE) { - candidatePkgs.removeAt(i); - } - } + if (!mPermissionHelper.hasPermission(app.second)) { + candidatePkgs.removeAt(i); } } boolean haveBypassingApps = candidatePkgs.size() > 0; @@ -1861,27 +1735,6 @@ public class PreferencesHelper implements RankingConfig { } /** - * Sets importance. - */ - @Override - public void setImportance(String pkgName, int uid, int importance) { - synchronized (mPackagePreferences) { - getOrCreatePackagePreferencesLocked(pkgName, uid).importance = importance; - } - updateConfig(); - } - - public void setEnabled(String packageName, int uid, boolean enabled) { - boolean wasEnabled = getImportance(packageName, uid) != IMPORTANCE_NONE; - if (wasEnabled == enabled) { - return; - } - setImportance(packageName, uid, - enabled ? DEFAULT_IMPORTANCE : IMPORTANCE_NONE); - mNotificationChannelLogger.logAppNotificationsAllowed(uid, packageName, enabled); - } - - /** * Sets whether any notifications from the app, represented by the given {@code pkgName} and * {@code uid}, have their importance locked by the user. Locked notifications don't get * considered for sentiment adjustments (and thus never show a blocking helper). @@ -2055,23 +1908,15 @@ public class PreferencesHelper implements RankingConfig { pw.print(" ("); pw.print(r.uid == UNKNOWN_UID ? "UNKNOWN_UID" : Integer.toString(r.uid)); pw.print(')'); - if (!mPermissionHelper.isMigrationEnabled()) { - if (r.importance != DEFAULT_IMPORTANCE) { - pw.print(" importance="); - pw.print(NotificationListenerService.Ranking.importanceToString( - r.importance)); - } - } else { - Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); - if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) { - pw.print(" importance="); - pw.print(NotificationListenerService.Ranking.importanceToString( - packagePermissions.get(key).first - ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); - pw.print(" userSet="); - pw.print(packagePermissions.get(key).second); - pkgsWithPermissionsToHandle.remove(key); - } + Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); + if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) { + pw.print(" importance="); + pw.print(NotificationListenerService.Ranking.importanceToString( + packagePermissions.get(key).first + ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); + pw.print(" userSet="); + pw.print(packagePermissions.get(key).second); + pkgsWithPermissionsToHandle.remove(key); } if (r.priority != DEFAULT_PRIORITY) { pw.print(" priority="); @@ -2111,7 +1956,7 @@ public class PreferencesHelper implements RankingConfig { } } // Handle any remaining packages with permissions - if (mPermissionHelper.isMigrationEnabled() && pkgsWithPermissionsToHandle != null) { + if (pkgsWithPermissionsToHandle != null) { for (Pair<Integer, String> p : pkgsWithPermissionsToHandle) { // p.first is the uid of this package; p.second is the package name if (filter.matches(p.second)) { @@ -2151,16 +1996,12 @@ public class PreferencesHelper implements RankingConfig { proto.write(RankingHelperProto.RecordProto.PACKAGE, r.pkg); proto.write(RankingHelperProto.RecordProto.UID, r.uid); - if (mPermissionHelper.isMigrationEnabled()) { - Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); - if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) { - proto.write(RankingHelperProto.RecordProto.IMPORTANCE, - packagePermissions.get(key).first - ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); - pkgsWithPermissionsToHandle.remove(key); - } - } else { - proto.write(RankingHelperProto.RecordProto.IMPORTANCE, r.importance); + Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); + if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) { + proto.write(RankingHelperProto.RecordProto.IMPORTANCE, + packagePermissions.get(key).first + ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE); + pkgsWithPermissionsToHandle.remove(key); } proto.write(RankingHelperProto.RecordProto.PRIORITY, r.priority); proto.write(RankingHelperProto.RecordProto.VISIBILITY, r.visibility); @@ -2177,7 +2018,7 @@ public class PreferencesHelper implements RankingConfig { } } - if (mPermissionHelper.isMigrationEnabled() && pkgsWithPermissionsToHandle != null) { + if (pkgsWithPermissionsToHandle != null) { for (Pair<Integer, String> p : pkgsWithPermissionsToHandle) { if (filter.matches(p.second)) { fToken = proto.start(fieldId); @@ -2217,25 +2058,22 @@ public class PreferencesHelper implements RankingConfig { // collect whether this package's importance info was user-set for later, if needed // before the migration is enabled, this will simply default to false in all cases. boolean importanceIsUserSet = false; - if (mPermissionHelper.isMigrationEnabled()) { - // Even if this package's data is not present, we need to write something; - // so default to IMPORTANCE_NONE, since if PM doesn't know about the package - // for some reason, notifications are not allowed. - int importance = IMPORTANCE_NONE; - Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); - if (pkgPermissions != null && pkgsWithPermissionsToHandle.contains(key)) { - Pair<Boolean, Boolean> permissionPair = pkgPermissions.get(key); - importance = permissionPair.first - ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE; - // cache the second value for writing later - importanceIsUserSet = permissionPair.second; - - pkgsWithPermissionsToHandle.remove(key); - } - event.writeInt(importance); - } else { - event.writeInt(r.importance); - } + // Even if this package's data is not present, we need to write something; + // so default to IMPORTANCE_NONE, since if PM doesn't know about the package + // for some reason, notifications are not allowed. + int importance = IMPORTANCE_NONE; + Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); + if (pkgPermissions != null && pkgsWithPermissionsToHandle.contains(key)) { + Pair<Boolean, Boolean> permissionPair = pkgPermissions.get(key); + importance = permissionPair.first + ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE; + // cache the second value for writing later + importanceIsUserSet = permissionPair.second; + + pkgsWithPermissionsToHandle.remove(key); + } + event.writeInt(importance); + event.writeInt(r.visibility); event.writeInt(r.lockedAppFields); event.writeBoolean(importanceIsUserSet); // optional bool user_set_importance = 5; @@ -2244,7 +2082,7 @@ public class PreferencesHelper implements RankingConfig { } // handle remaining packages with PackageManager permissions but not local settings - if (mPermissionHelper.isMigrationEnabled() && pkgPermissions != null) { + if (pkgPermissions != null) { for (Pair<Integer, String> p : pkgsWithPermissionsToHandle) { if (pulledEvents > NOTIFICATION_PREFERENCES_PULL_LIMIT) { break; @@ -2357,22 +2195,14 @@ public class PreferencesHelper implements RankingConfig { try { PackagePreferences.put("userId", UserHandle.getUserId(r.uid)); PackagePreferences.put("packageName", r.pkg); - if (mPermissionHelper.isMigrationEnabled()) { - Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); - if (pkgPermissions != null - && pkgsWithPermissionsToHandle.contains(key)) { - PackagePreferences.put("importance", - NotificationListenerService.Ranking.importanceToString( - pkgPermissions.get(key).first - ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); - pkgsWithPermissionsToHandle.remove(key); - } - } else { - if (r.importance != DEFAULT_IMPORTANCE) { - PackagePreferences.put("importance", - NotificationListenerService.Ranking.importanceToString( - r.importance)); - } + Pair<Integer, String> key = new Pair<>(r.uid, r.pkg); + if (pkgPermissions != null + && pkgsWithPermissionsToHandle.contains(key)) { + PackagePreferences.put("importance", + NotificationListenerService.Ranking.importanceToString( + pkgPermissions.get(key).first + ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE)); + pkgsWithPermissionsToHandle.remove(key); } if (r.priority != DEFAULT_PRIORITY) { PackagePreferences.put("priority", @@ -2404,7 +2234,7 @@ public class PreferencesHelper implements RankingConfig { } // handle packages for which there are permissions but no local settings - if (mPermissionHelper.isMigrationEnabled() && pkgsWithPermissionsToHandle != null) { + if (pkgsWithPermissionsToHandle != null) { for (Pair<Integer, String> p : pkgsWithPermissionsToHandle) { if (filter == null || filter.matches(p.second)) { JSONObject PackagePreferences = new JSONObject(); @@ -2443,8 +2273,7 @@ public class PreferencesHelper implements RankingConfig { public JSONArray dumpBansJson(NotificationManagerService.DumpFilter filter, ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONArray bans = new JSONArray(); - Map<Integer, String> packageBans = mPermissionHelper.isMigrationEnabled() - ? getPermissionBasedPackageBans(pkgPermissions) : getPackageBans(); + Map<Integer, String> packageBans = getPermissionBasedPackageBans(pkgPermissions); for (Map.Entry<Integer, String> ban : packageBans.entrySet()) { final int userId = UserHandle.getUserId(ban.getKey()); final String packageName = ban.getValue(); @@ -2597,7 +2426,7 @@ public class PreferencesHelper implements RankingConfig { synchronized (mPackagePreferences) { mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r); } - if (mPermissionHelper.isMigrationEnabled() && r.migrateToPm) { + if (r.migrateToPm) { try { PackagePermission p = new PackagePermission( r.pkg, UserHandle.getUserId(r.uid), diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java index 398259333e16..3e9d90c440b6 100644 --- a/services/core/java/com/android/server/notification/RankingConfig.java +++ b/services/core/java/com/android/server/notification/RankingConfig.java @@ -24,8 +24,6 @@ import java.util.Collection; public interface RankingConfig { - void setImportance(String packageName, int uid, int importance); - int getImportance(String packageName, int uid); void setShowBadge(String packageName, int uid, boolean showBadge); boolean canShowBadge(String packageName, int uid); boolean badgingEnabled(UserHandle userHandle); diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index d26a1ac4fba0..9ea0192eaab5 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -91,17 +91,21 @@ public final class BackgroundDexOptService { // Possible return codes of individual optimization steps. /** Ok status: Optimizations finished, All packages were processed, can continue */ - private static final int STATUS_OK = 0; + /* package */ static final int STATUS_OK = 0; /** Optimizations should be aborted. Job scheduler requested it. */ - private static final int STATUS_ABORT_BY_CANCELLATION = 1; + /* package */ static final int STATUS_ABORT_BY_CANCELLATION = 1; /** Optimizations should be aborted. No space left on device. */ - private static final int STATUS_ABORT_NO_SPACE_LEFT = 2; + /* package */ static final int STATUS_ABORT_NO_SPACE_LEFT = 2; /** Optimizations should be aborted. Thermal throttling level too high. */ - private static final int STATUS_ABORT_THERMAL = 3; + /* package */ static final int STATUS_ABORT_THERMAL = 3; /** Battery level too low */ - private static final int STATUS_ABORT_BATTERY = 4; - /** {@link PackageDexOptimizer#DEX_OPT_FAILED} case */ - private static final int STATUS_DEX_OPT_FAILED = 5; + /* package */ static final int STATUS_ABORT_BATTERY = 4; + /** + * {@link PackageDexOptimizer#DEX_OPT_FAILED} case. This state means some packages have failed + * compilation during the job. Note that the failure will not be permanent as the next dexopt + * job will exclude those failed packages. + */ + /* package */ static final int STATUS_DEX_OPT_FAILED = 5; @IntDef(prefix = {"STATUS_"}, value = { STATUS_OK, @@ -525,7 +529,10 @@ public final class BackgroundDexOptService { } } - /** Returns true if completed */ + /** + * Returns whether we've successfully run the job. Note that it will return true even if some + * packages may have failed compiling. + */ private boolean runIdleOptimization(PackageManagerService pm, List<String> pkgs, boolean isPostBootUpdate) { synchronized (mLock) { @@ -541,7 +548,7 @@ public final class BackgroundDexOptService { mLastExecutionDurationMs = SystemClock.elapsedRealtime() - mLastExecutionStartTimeMs; } - return status == STATUS_OK; + return status == STATUS_OK || status == STATUS_DEX_OPT_FAILED; } /** Gets the size of the directory. It uses recursion to go over all files. */ @@ -661,6 +668,11 @@ public final class BackgroundDexOptService { ArraySet<String> updatedPackages, boolean isPostBootUpdate) { boolean supportSecondaryDex = mInjector.supportSecondaryDex(); + // Keep the error if there is any error from any package. + @Status int status = STATUS_OK; + + // Other than cancellation, all packages will be processed even if an error happens + // in a package. for (String pkg : pkgs) { int abortCode = abortIdleOptimizations(lowStorageThreshold); if (abortCode != STATUS_OK) { @@ -670,10 +682,13 @@ public final class BackgroundDexOptService { @DexOptResult int primaryResult = optimizePackage(pkg, true /* isForPrimaryDex */, isPostBootUpdate); + if (primaryResult == PackageDexOptimizer.DEX_OPT_CANCELLED) { + return STATUS_ABORT_BY_CANCELLATION; + } if (primaryResult == PackageDexOptimizer.DEX_OPT_PERFORMED) { updatedPackages.add(pkg); - } else if (primaryResult != PackageDexOptimizer.DEX_OPT_SKIPPED) { - return convertPackageDexOptimizerStatusToInternal(primaryResult); + } else if (primaryResult == PackageDexOptimizer.DEX_OPT_FAILED) { + status = convertPackageDexOptimizerStatusToInternal(primaryResult); } if (!supportSecondaryDex) { @@ -682,12 +697,14 @@ public final class BackgroundDexOptService { @DexOptResult int secondaryResult = optimizePackage(pkg, false /* isForPrimaryDex */, isPostBootUpdate); - if (secondaryResult != PackageDexOptimizer.DEX_OPT_PERFORMED - && secondaryResult != PackageDexOptimizer.DEX_OPT_SKIPPED) { - return convertPackageDexOptimizerStatusToInternal(secondaryResult); + if (secondaryResult == PackageDexOptimizer.DEX_OPT_CANCELLED) { + return STATUS_ABORT_BY_CANCELLATION; + } + if (secondaryResult == PackageDexOptimizer.DEX_OPT_FAILED) { + status = convertPackageDexOptimizerStatusToInternal(secondaryResult); } } - return STATUS_OK; + return status; } /** @@ -779,9 +796,9 @@ public final class BackgroundDexOptService { @DexOptResult private int performDexOptPrimary(String pkg, int reason, int dexoptFlags) { + DexoptOptions dexoptOptions = new DexoptOptions(pkg, reason, dexoptFlags); return trackPerformDexOpt(pkg, /*isForPrimaryDex=*/ true, - () -> mDexOptHelper.performDexOptWithStatus( - new DexoptOptions(pkg, reason, dexoptFlags))); + () -> mDexOptHelper.performDexOptWithStatus(dexoptOptions)); } @DexOptResult @@ -791,7 +808,7 @@ public final class BackgroundDexOptService { dexoptFlags | DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX); return trackPerformDexOpt(pkg, /*isForPrimaryDex=*/ false, () -> mDexOptHelper.performDexOpt(dexoptOptions) - ? PackageDexOptimizer.DEX_OPT_PERFORMED : PackageDexOptimizer.DEX_OPT_FAILED + ? PackageDexOptimizer.DEX_OPT_PERFORMED : PackageDexOptimizer.DEX_OPT_FAILED ); } diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java index ed71f1eb5313..9d1f0704a3cf 100644 --- a/services/core/java/com/android/server/pm/BroadcastHelper.java +++ b/services/core/java/com/android/server/pm/BroadcastHelper.java @@ -197,7 +197,7 @@ public final class BroadcastHelper { final BroadcastOptions bOptions = getTemporaryAppAllowlistBroadcastOptions( REASON_LOCKED_BOOT_COMPLETED); am.broadcastIntentWithFeature(null, null, lockedBcIntent, null, null, 0, null, null, - requiredPermissions, null, android.app.AppOpsManager.OP_NONE, + requiredPermissions, null, null, android.app.AppOpsManager.OP_NONE, bOptions.toBundle(), false, false, userId); // Deliver BOOT_COMPLETED only if user is unlocked @@ -207,7 +207,7 @@ public final class BroadcastHelper { bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); } am.broadcastIntentWithFeature(null, null, bcIntent, null, null, 0, null, null, - requiredPermissions, null, android.app.AppOpsManager.OP_NONE, + requiredPermissions, null, null, android.app.AppOpsManager.OP_NONE, bOptions.toBundle(), false, false, userId); } } catch (RemoteException e) { @@ -263,7 +263,7 @@ public final class BroadcastHelper { }; try { am.broadcastIntentWithFeature(null, null, intent, null, null, 0, null, null, - requiredPermissions, null, android.app.AppOpsManager.OP_NONE, null, false, + requiredPermissions, null, null, android.app.AppOpsManager.OP_NONE, null, false, false, UserHandle.USER_ALL); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -301,7 +301,7 @@ public final class BroadcastHelper { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); try { am.broadcastIntentWithFeature(null, null, intent, null, null, - 0, null, null, null, null, android.app.AppOpsManager.OP_NONE, + 0, null, null, null, null, null, android.app.AppOpsManager.OP_NONE, null, false, false, userId); } catch (RemoteException e) { } diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java index f1296e0cd7b0..8c33dd935822 100644 --- a/services/core/java/com/android/server/pm/DexOptHelper.java +++ b/services/core/java/com/android/server/pm/DexOptHelper.java @@ -29,9 +29,7 @@ import static com.android.server.pm.PackageManagerService.TAG; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter; import static com.android.server.pm.PackageManagerServiceUtils.REMOVE_IF_NULL_PKG; -import android.Manifest; import android.annotation.NonNull; -import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.AppGlobals; import android.content.Intent; @@ -44,7 +42,6 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; -import android.provider.DeviceConfig; import android.util.ArraySet; import android.util.Log; import android.util.Slog; @@ -253,60 +250,10 @@ final class DexOptHelper { numberOfPackagesFailed}; } - /** - * Checks if system UI package (typically "com.android.systemui") needs to be re-compiled, and - * compiles it if needed. - */ - private void checkAndDexOptSystemUi() { - Computer snapshot = mPm.snapshotComputer(); - String sysUiPackageName = - mPm.mContext.getString(com.android.internal.R.string.config_systemUi); - AndroidPackage pkg = snapshot.getPackage(sysUiPackageName); - if (pkg == null) { - Log.w(TAG, "System UI package " + sysUiPackageName + " is not found for dexopting"); - return; - } - - boolean useProfileForDexopt = false; - File profileFile = new File(getPrebuildProfilePath(pkg)); - // Copy the profile to the reference profile path if it exists. Installd can only use a - // profile at the reference profile path for dexopt. - if (profileFile.exists()) { - try { - synchronized (mPm.mInstallLock) { - if (mPm.mInstaller.copySystemProfile(profileFile.getAbsolutePath(), - pkg.getUid(), pkg.getPackageName(), - ArtManager.getProfileName(null))) { - useProfileForDexopt = true; - } else { - Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath()); - } - } - } catch (Exception e) { - Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath(), e); - } - } - - // It could also be after mainline update, but we're not introducing a new reason just for - // this special case. - performDexOptTraced(new DexoptOptions(pkg.getPackageName(), REASON_BOOT_AFTER_OTA, - useProfileForDexopt ? "speed-profile" : "speed", null /* splitName */, - 0 /* dexoptFlags */)); - } - - @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) public void performPackageDexOptUpgradeIfNeeded() { PackageManagerServiceUtils.enforceSystemOrRoot( "Only the system can request package update"); - // The default is "true". - if (!"false".equals(DeviceConfig.getProperty("runtime", "dexopt_system_ui_on_boot"))) { - // System UI is important to user experience, so we check it on every boot. It may need - // to be re-compiled after a mainline update or an OTA. - // TODO(b/227310505): Only do this after a mainline update or an OTA. - checkAndDexOptSystemUi(); - } - // We need to re-extract after an OTA. boolean causeUpgrade = mPm.isDeviceUpgrading(); diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index 32f0f109821d..9de667fbc6f5 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -44,6 +44,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; public class Installer extends SystemService { private static final String TAG = "Installer"; @@ -118,9 +121,13 @@ public class Installer extends SystemService { public static final int FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES = IInstalld.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES; + private static final long CONNECT_RETRY_DELAY_MS = DateUtils.SECOND_IN_MILLIS; + private static final long CONNECT_WAIT_MS = 10 * DateUtils.SECOND_IN_MILLIS; + private final boolean mIsolated; private volatile boolean mDeferSetFirstBoot; - private volatile IInstalld mInstalld; + private volatile IInstalld mInstalld = null; + private volatile CompletableFuture<IInstalld> mInstalldFuture = new CompletableFuture<>(); private volatile Object mWarnIfHeld; public Installer(Context context) { @@ -149,6 +156,7 @@ public class Installer extends SystemService { public void onStart() { if (mIsolated) { mInstalld = null; + mInstalldFuture = null; } else { connect(); } @@ -168,7 +176,9 @@ public class Installer extends SystemService { } if (binder != null) { - mInstalld = IInstalld.Stub.asInterface(binder); + IInstalld installd = IInstalld.Stub.asInterface(binder); + mInstalld = installd; + mInstalldFuture.complete(installd); try { invalidateMounts(); executeDeferredActions(); @@ -202,9 +212,18 @@ public class Installer extends SystemService { if (mIsolated) { Slog.i(TAG, "Ignoring request because this installer is isolated"); return false; - } else { - return true; } + + if (mInstalld == null && mInstalldFuture != null) { + try { + Slog.i(TAG, "installd not ready, waiting for: " + CONNECT_WAIT_MS + "ms"); + mInstalld = mInstalldFuture.get(CONNECT_WAIT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + Slog.e(TAG, "Ignoring request because this installer is not initialized", e); + } + } + + return mInstalld != null; } // We explicitly do NOT set previousAppId because the default value should always be 0. diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java index ec6443db9f0f..652847ad1647 100644 --- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java +++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java @@ -315,9 +315,9 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal { @Deprecated public final List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, - int filterCallingUid, int userId) { - return getResolveIntentHelper().queryIntentReceiversInternal( - snapshot(), intent, resolvedType, flags, userId, filterCallingUid); + int filterCallingUid, int userId, boolean forSend) { + return getResolveIntentHelper().queryIntentReceiversInternal(snapshot(), intent, + resolvedType, flags, userId, filterCallingUid, forSend); } @Override @@ -352,10 +352,9 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal { @Override @Deprecated - public final void setDeviceOwnerProtectedPackages( - String deviceOwnerPackageName, List<String> packageNames) { - getProtectedPackages().setDeviceOwnerProtectedPackages( - deviceOwnerPackageName, packageNames); + public final void setOwnerProtectedPackages( + @UserIdInt int userId, @NonNull List<String> packageNames) { + getProtectedPackages().setOwnerProtectedPackages(userId, packageNames); } @Override diff --git a/services/core/java/com/android/server/pm/ProtectedPackages.java b/services/core/java/com/android/server/pm/ProtectedPackages.java index bf4612973023..e9239889973a 100644 --- a/services/core/java/com/android/server/pm/ProtectedPackages.java +++ b/services/core/java/com/android/server/pm/ProtectedPackages.java @@ -16,11 +16,11 @@ package com.android.server.pm; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; import android.os.UserHandle; -import android.util.ArrayMap; import android.util.ArraySet; import android.util.SparseArray; @@ -56,7 +56,7 @@ public class ProtectedPackages { @Nullable @GuardedBy("this") - private final ArrayMap<String, Set<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>(); + private final SparseArray<Set<String>> mOwnerProtectedPackages = new SparseArray<>(); private final Context mContext; @@ -79,13 +79,13 @@ public class ProtectedPackages { : profileOwnerPackages.clone(); } - /** Sets the protected packages for the device owner. */ - public synchronized void setDeviceOwnerProtectedPackages( - String deviceOwnerPackageName, List<String> packageNames) { + /** Sets packages protected by a device or profile owner. */ + public synchronized void setOwnerProtectedPackages( + @UserIdInt int userId, @NonNull List<String> packageNames) { if (packageNames.isEmpty()) { - mDeviceOwnerProtectedPackages.remove(deviceOwnerPackageName); + mOwnerProtectedPackages.remove(userId); } else { - mDeviceOwnerProtectedPackages.put(deviceOwnerPackageName, new ArraySet<>(packageNames)); + mOwnerProtectedPackages.put(userId, new ArraySet<>(packageNames)); } } @@ -123,19 +123,24 @@ public class ProtectedPackages { * <p>A protected package means that, apart from the package owner, no system or privileged apps * can modify its data or package state. */ - private synchronized boolean isProtectedPackage(String packageName) { + private synchronized boolean isProtectedPackage(@UserIdInt int userId, String packageName) { return packageName != null && (packageName.equals(mDeviceProvisioningPackage) - || isDeviceOwnerProtectedPackage(packageName)); + || isOwnerProtectedPackage(userId, packageName)); } - /** Returns {@code true} if the given package is a protected package set by any device owner. */ - private synchronized boolean isDeviceOwnerProtectedPackage(String packageName) { - for (Set<String> protectedPackages : mDeviceOwnerProtectedPackages.values()) { - if (protectedPackages.contains(packageName)) { - return true; - } - } - return false; + /** + * Returns {@code true} if the given package is a protected package set by any device or + * profile owner. + */ + private synchronized boolean isOwnerProtectedPackage( + @UserIdInt int userId, String packageName) { + return isPackageProtectedForUser(UserHandle.USER_ALL, packageName) + || isPackageProtectedForUser(userId, packageName); + } + + private synchronized boolean isPackageProtectedForUser(int userId, String packageName) { + int userIdx = mOwnerProtectedPackages.indexOfKey(userId); + return userIdx >= 0 && mOwnerProtectedPackages.valueAt(userIdx).contains(packageName); } /** @@ -146,7 +151,7 @@ public class ProtectedPackages { */ public boolean isPackageStateProtected(@UserIdInt int userId, String packageName) { return hasDeviceOwnerOrProfileOwner(userId, packageName) - || isProtectedPackage(packageName); + || isProtectedPackage(userId, packageName); } /** @@ -155,6 +160,6 @@ public class ProtectedPackages { */ public boolean isPackageDataProtected(@UserIdInt int userId, String packageName) { return hasDeviceOwnerOrProfileOwner(userId, packageName) - || isProtectedPackage(packageName); + || isProtectedPackage(userId, packageName); } } diff --git a/services/core/java/com/android/server/pm/ResolveIntentHelper.java b/services/core/java/com/android/server/pm/ResolveIntentHelper.java index b74670b77a11..2db1c2029d9c 100644 --- a/services/core/java/com/android/server/pm/ResolveIntentHelper.java +++ b/services/core/java/com/android/server/pm/ResolveIntentHelper.java @@ -306,16 +306,32 @@ final class ResolveIntentHelper { return new IntentSender(target); } - // In this method, we have to know the actual calling UID, but in some cases Binder's - // call identity is removed, so the UID has to be passed in explicitly. - public @NonNull List<ResolveInfo> queryIntentReceiversInternal(Computer computer, Intent intent, + /** + * Retrieve all receivers that can handle a broadcast of the given intent. + * @param queryingUid the results will be filtered in the context of this UID instead. + */ + @NonNull + public List<ResolveInfo> queryIntentReceiversInternal(Computer computer, Intent intent, + String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId, + int queryingUid) { + return queryIntentReceiversInternal(computer, intent, resolvedType, flags, userId, + queryingUid, false); + } + + /** + * @see PackageManagerInternal#queryIntentReceivers(Intent, String, long, int, int, boolean) + */ + @NonNull + public List<ResolveInfo> queryIntentReceiversInternal(Computer computer, Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId, - int filterCallingUid) { + int filterCallingUid, boolean forSend) { if (!mUserManager.exists(userId)) return Collections.emptyList(); - computer.enforceCrossUserPermission(filterCallingUid, userId, false /*requireFullPermission*/, - false /*checkShell*/, "query intent receivers"); - final String instantAppPkgName = computer.getInstantAppPackageName(filterCallingUid); - flags = computer.updateFlagsForResolve(flags, userId, filterCallingUid, + // The identity used to filter the receiver components + final int queryingUid = forSend ? Process.SYSTEM_UID : filterCallingUid; + computer.enforceCrossUserPermission(queryingUid, userId, + false /*requireFullPermission*/, false /*checkShell*/, "query intent receivers"); + final String instantAppPkgName = computer.getInstantAppPackageName(queryingUid); + flags = computer.updateFlagsForResolve(flags, userId, queryingUid, false /*includeInstantApps*/, computer.isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId, resolvedType, flags)); @@ -397,7 +413,7 @@ final class ResolveIntentHelper { list, true, originalIntent, resolvedType, filterCallingUid); } - return computer.applyPostResolutionFilter(list, instantAppPkgName, false, filterCallingUid, + return computer.applyPostResolutionFilter(list, instantAppPkgName, false, queryingUid, false, userId, intent); } diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java index 95482d7c7f1a..974a1e1cd59d 100644 --- a/services/core/java/com/android/server/pm/UserDataPreparer.java +++ b/services/core/java/com/android/server/pm/UserDataPreparer.java @@ -70,9 +70,16 @@ class UserDataPreparer { void prepareUserData(int userId, int userSerial, int flags) { synchronized (mInstallLock) { final StorageManager storage = mContext.getSystemService(StorageManager.class); + /* + * Internal storage must be prepared before adoptable storage, since the user's volume + * keys are stored in their internal storage. + */ + prepareUserDataLI(null /* internal storage */, userId, userSerial, flags, true); for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { final String volumeUuid = vol.getFsUuid(); - prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); + if (volumeUuid != null) { + prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); + } } } } @@ -136,10 +143,17 @@ class UserDataPreparer { void destroyUserData(int userId, int flags) { synchronized (mInstallLock) { final StorageManager storage = mContext.getSystemService(StorageManager.class); + /* + * Volume destruction order isn't really important, but to avoid any weird issues we + * process internal storage last, the opposite of prepareUserData. + */ for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { final String volumeUuid = vol.getFsUuid(); - destroyUserDataLI(volumeUuid, userId, flags); + if (volumeUuid != null) { + destroyUserDataLI(volumeUuid, userId, flags); + } } + destroyUserDataLI(null /* internal storage */, userId, flags); } } diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index a04f6d64ef8f..f727c11879b0 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -1018,8 +1018,6 @@ final class DefaultPermissionGrantPolicy { for (String packageName : packageNames) { grantPermissionsToSystemPackage(NO_PM_CACHE, packageName, userId, PHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS, SMS_PERMISSIONS); - grantPermissionsToPackage(NO_PM_CACHE, packageName, userId, false, false, - NOTIFICATION_PERMISSIONS); } } diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerInternal.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerInternal.java index 446e20b70279..6c2354f1b3e6 100644 --- a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerInternal.java +++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerInternal.java @@ -17,6 +17,7 @@ package com.android.server.pm.permission; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UserIdInt; /** @@ -105,6 +106,20 @@ public interface LegacyPermissionManagerInternal { void scheduleReadDefaultPermissionExceptions(); /** + * Check whether a particular package should have access to the microphone data from the + * SoundTrigger. + * + * @param uid the uid of the package you are checking against + * @param packageName the name of the package you are checking against + * @param attributionTag the attributionTag to attach to the app op transaction + * @param reason the reason to attach to the app op transaction + * @return {@code PERMISSION_GRANTED} if the permission is granted, + * or {@code PERMISSION_SOFT/HARD DENIED otherwise + */ + int checkSoundTriggerRecordAudioPermissionForDataDelivery(int uid, + @NonNull String packageName, @Nullable String attributionTag, @NonNull String reason); + + /** * Provider for package names. */ interface PackagesProvider { diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java index 360a04f7e9bc..88b4a94f7027 100644 --- a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java @@ -16,12 +16,15 @@ package com.android.server.pm.permission; +import static android.Manifest.permission.RECORD_AUDIO; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.content.Context; +import android.content.PermissionChecker; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; @@ -399,6 +402,21 @@ public class LegacyPermissionManagerService extends ILegacyPermissionManager.Stu public void scheduleReadDefaultPermissionExceptions() { mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions(); } + + @Override + public int checkSoundTriggerRecordAudioPermissionForDataDelivery(int uid, + @NonNull String packageName, @Nullable String attributionTag, + @NonNull String reason) { + int result = PermissionChecker.checkPermissionForPreflight(mContext, RECORD_AUDIO, -1, + uid, packageName); + if (result != PermissionChecker.PERMISSION_GRANTED) { + return result; + } + mContext.getSystemService(AppOpsManager.class).noteOpNoThrow( + AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, uid, packageName, + attributionTag, reason); + return result; + } } /** diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java index 9897c42e4cec..3799dbb630f0 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java @@ -392,6 +392,9 @@ public class ParsingPackageUtils { if ((flags & PARSE_FRAMEWORK_RES_SPLITS) != 0) { liteParseFlags = flags; } + if ((flags & PARSE_APK_IN_APEX) != 0) { + liteParseFlags |= PARSE_APK_IN_APEX; + } final ParseResult<PackageLite> liteResult = ApkLiteParseUtils.parseClusterPackageLite(input, packageDir, frameworkSplits, liteParseFlags); diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java index a8ed70b91442..ebd9126d1439 100644 --- a/services/core/java/com/android/server/policy/AppOpsPolicy.java +++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java @@ -87,8 +87,8 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat private final VoiceInteractionManagerInternal mVoiceInteractionManagerInternal; /** - * Whether this device allows only the HotwordDetectionService to use OP_RECORD_AUDIO_HOTWORD - * which doesn't incur the privacy indicator. + * Whether this device allows only the HotwordDetectionService to use + * OP_RECORD_AUDIO_HOTWORD which doesn't incur the privacy indicator. */ private final boolean mIsHotwordDetectionServiceRequired; @@ -427,8 +427,8 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat if (!mIsHotwordDetectionServiceRequired) { return code; } - // Only the HotwordDetectionService can use the HOTWORD op which doesn't incur the - // privacy indicator. Downgrade to standard RECORD_AUDIO for other processes. + // Only the HotwordDetectionService can use the RECORD_AUDIO_HOTWORD op which doesn't + // incur the privacy indicator. Downgrade to standard RECORD_AUDIO for other processes. final HotwordDetectionServiceIdentity hotwordDetectionServiceIdentity = mVoiceInteractionManagerInternal.getHotwordDetectionServiceIdentity(); if (hotwordDetectionServiceIdentity != null diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index 7ba1cadc5c8b..977f79f6175d 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -1453,16 +1453,6 @@ public final class PermissionPolicyService extends SystemService { } } - try { - if (Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, UserHandle.USER_SYSTEM) - == 0) { - return false; - } - } catch (Settings.SettingNotFoundException e) { - return false; - } - if (!pkg.getRequestedPermissions().contains(POST_NOTIFICATIONS) || CompatChanges.isChangeEnabled(NOTIFICATION_PERM_CHANGE_ID, pkgName, user) || mKeyguardManager.isKeyguardLocked()) { diff --git a/services/core/java/com/android/server/sensorprivacy/CameraPrivacyLightController.java b/services/core/java/com/android/server/sensorprivacy/CameraPrivacyLightController.java index 750d4004cb60..fd6ec065d421 100644 --- a/services/core/java/com/android/server/sensorprivacy/CameraPrivacyLightController.java +++ b/services/core/java/com/android/server/sensorprivacy/CameraPrivacyLightController.java @@ -16,44 +16,105 @@ package com.android.server.sensorprivacy; +import static android.hardware.SensorManager.SENSOR_DELAY_NORMAL; + +import android.annotation.ColorInt; import android.app.AppOpsManager; import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.hardware.lights.Light; import android.hardware.lights.LightState; import android.hardware.lights.LightsManager; import android.hardware.lights.LightsRequest; +import android.os.Handler; +import android.os.HandlerExecutor; +import android.os.Looper; +import android.os.SystemClock; import android.permission.PermissionManager; import android.util.ArraySet; +import android.util.Pair; import com.android.internal.R; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.FgThread; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.concurrent.Executor; + +class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedListener, + SensorEventListener { -class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedListener { + @VisibleForTesting + static final double LIGHT_VALUE_MULTIPLIER = 1 / Math.log(1.1); + private final Handler mHandler; + private final Executor mExecutor; private final Context mContext; + private final AppOpsManager mAppOpsManager; private final LightsManager mLightsManager; + private final SensorManager mSensorManager; private final Set<String> mActivePackages = new ArraySet<>(); private final Set<String> mActivePhonePackages = new ArraySet<>(); - private final int mCameraPrivacyLightColor; - private final List<Light> mCameraLights = new ArrayList<>(); - private final AppOpsManager mAppOpsManager; private LightsManager.LightsSession mLightsSession = null; + @ColorInt + private final int mDayColor; + @ColorInt + private final int mNightColor; + + private final Sensor mLightSensor; + + private boolean mIsAmbientLightListenerRegistered = false; + private final long mMovingAverageIntervalMillis; + /** When average of the time integral over the past {@link #mMovingAverageIntervalMillis} + * milliseconds of the log_1.1(lux(t)) is greater than this value, use the daytime brightness + * else use nighttime brightness. */ + private final long mNightThreshold; + private final ArrayDeque<Pair<Long, Integer>> mAmbientLightValues = new ArrayDeque<>(); + /** Tracks the Riemann sum of {@link #mAmbientLightValues} to avoid O(n) operations when sum is + * needed */ + private long mAlvSum = 0; + private int mLastLightColor = 0; + /** The elapsed real time that the ALS was started watching */ + private long mElapsedTimeStartedReading; + + private final Object mDelayedUpdateToken = new Object(); + + // Can't mock static native methods, workaround for testing + private long mElapsedRealTime = -1; + CameraPrivacyLightController(Context context) { + this(context, FgThread.get().getLooper()); + } + + @VisibleForTesting + CameraPrivacyLightController(Context context, Looper looper) { mContext = context; + mHandler = new Handler(looper); + mExecutor = new HandlerExecutor(mHandler); + mAppOpsManager = mContext.getSystemService(AppOpsManager.class); mLightsManager = mContext.getSystemService(LightsManager.class); + mSensorManager = mContext.getSystemService(SensorManager.class); - mCameraPrivacyLightColor = mContext.getColor(R.color.camera_privacy_light); + mDayColor = mContext.getColor(R.color.camera_privacy_light_day); + mNightColor = mContext.getColor(R.color.camera_privacy_light_night); + mMovingAverageIntervalMillis = mContext.getResources() + .getInteger(R.integer.config_cameraPrivacyLightAlsAveragingIntervalMillis); + mNightThreshold = (long) (Math.log(mContext.getResources() + .getInteger(R.integer.config_cameraPrivacyLightAlsNightThreshold)) + * LIGHT_VALUE_MULTIPLIER); List<Light> lights = mLightsManager.getLights(); for (int i = 0; i < lights.size(); i++) { @@ -64,12 +125,60 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis } if (mCameraLights.isEmpty()) { + mLightSensor = null; return; } mAppOpsManager.startWatchingActive( new String[] {AppOpsManager.OPSTR_CAMERA, AppOpsManager.OPSTR_PHONE_CALL_CAMERA}, - FgThread.getExecutor(), this); + mExecutor, this); + + // It may be useful in the future to configure devices to know which lights are near which + // sensors so that we can control individual lights based on their environment. + mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); + } + + private void addElement(long time, int value) { + if (mAmbientLightValues.isEmpty()) { + // Eliminate the size == 1 edge case and assume the light value has been constant for + // the previous interval + mAmbientLightValues.add(new Pair<>(time - getCurrentIntervalMillis() - 1, value)); + } + Pair<Long, Integer> lastElement = mAmbientLightValues.peekLast(); + mAmbientLightValues.add(new Pair<>(time, value)); + + mAlvSum += (time - lastElement.first) * lastElement.second; + removeObsoleteData(time); + } + + private void removeObsoleteData(long time) { + while (mAmbientLightValues.size() > 1) { + Pair<Long, Integer> element0 = mAmbientLightValues.pollFirst(); // NOTICE: POLL + Pair<Long, Integer> element1 = mAmbientLightValues.peekFirst(); // NOTICE: PEEK + if (element1.first > time - getCurrentIntervalMillis()) { + mAmbientLightValues.addFirst(element0); + break; + } + mAlvSum -= (element1.first - element0.first) * element0.second; + } + } + + /** + * Gives the Riemann sum of {@link #mAmbientLightValues} where the part of the interval that + * stretches outside the time window is removed and the time since the last change is added in. + */ + private long getLiveAmbientLightTotal() { + if (mAmbientLightValues.isEmpty()) { + return mAlvSum; + } + long time = getElapsedRealTime(); + removeObsoleteData(time); + + Pair<Long, Integer> firstElement = mAmbientLightValues.peekFirst(); + Pair<Long, Integer> lastElement = mAmbientLightValues.peekLast(); + + return mAlvSum - Math.max(0, time - getCurrentIntervalMillis() - firstElement.first) + * firstElement.second + (time - lastElement.first) * lastElement.second; } @Override @@ -93,10 +202,16 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis } private void updateLightSession() { + if (Looper.myLooper() != mHandler.getLooper()) { + mHandler.post(this::updateLightSession); + return; + } + Set<String> exemptedPackages = PermissionManager.getIndicatorExemptedPackages(mContext); boolean shouldSessionEnd = exemptedPackages.containsAll(mActivePackages) && exemptedPackages.containsAll(mActivePhonePackages); + updateSensorListener(shouldSessionEnd); if (shouldSessionEnd) { if (mLightsSession == null) { @@ -106,20 +221,73 @@ class CameraPrivacyLightController implements AppOpsManager.OnOpActiveChangedLis mLightsSession.close(); mLightsSession = null; } else { - if (mLightsSession != null) { + int lightColor; + if (mLightSensor != null && getLiveAmbientLightTotal() + < getCurrentIntervalMillis() * mNightThreshold) { + lightColor = mNightColor; + } else { + lightColor = mDayColor; + } + + if (mLastLightColor == lightColor && mLightsSession != null) { return; } + mLastLightColor = lightColor; LightsRequest.Builder requestBuilder = new LightsRequest.Builder(); for (int i = 0; i < mCameraLights.size(); i++) { requestBuilder.addLight(mCameraLights.get(i), new LightState.Builder() - .setColor(mCameraPrivacyLightColor) + .setColor(lightColor) .build()); } - mLightsSession = mLightsManager.openSession(Integer.MAX_VALUE); + if (mLightsSession == null) { + mLightsSession = mLightsManager.openSession(Integer.MAX_VALUE); + } + mLightsSession.requestLights(requestBuilder.build()); } } + + private void updateSensorListener(boolean shouldSessionEnd) { + if (shouldSessionEnd && mIsAmbientLightListenerRegistered) { + mSensorManager.unregisterListener(this); + mIsAmbientLightListenerRegistered = false; + } + if (!shouldSessionEnd && !mIsAmbientLightListenerRegistered && mLightSensor != null) { + mSensorManager.registerListener(this, mLightSensor, SENSOR_DELAY_NORMAL, mHandler); + mIsAmbientLightListenerRegistered = true; + mElapsedTimeStartedReading = getElapsedRealTime(); + } + } + + private long getElapsedRealTime() { + return mElapsedRealTime == -1 ? SystemClock.elapsedRealtime() : mElapsedRealTime; + } + + @VisibleForTesting + void setElapsedRealTime(long time) { + mElapsedRealTime = time; + } + + @Override + public void onSensorChanged(SensorEvent event) { + // Using log space to represent human sensation (Fechner's Law) instead of lux + // because lux values causes bright flashes to skew the average very high. + addElement(event.timestamp, Math.max(0, + (int) (Math.log(event.values[0]) * LIGHT_VALUE_MULTIPLIER))); + updateLightSession(); + mHandler.removeCallbacksAndMessages(mDelayedUpdateToken); + mHandler.postDelayed(CameraPrivacyLightController.this::updateLightSession, + mDelayedUpdateToken, mMovingAverageIntervalMillis); + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + private long getCurrentIntervalMillis() { + return Math.min(mMovingAverageIntervalMillis, + getElapsedRealTime() - mElapsedTimeStartedReading); + } } diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java index 3c779f387673..c354f116af5f 100644 --- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java +++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java @@ -25,6 +25,7 @@ import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA; import static android.app.AppOpsManager.OP_PHONE_CALL_MICROPHONE; +import static android.app.AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; @@ -1067,6 +1068,10 @@ public final class SensorPrivacyService extends SystemService { mAppOpsRestrictionToken); mAppOpsManagerInternal.setGlobalRestriction(OP_PHONE_CALL_MICROPHONE, enabled, mAppOpsRestrictionToken); + // We don't show the dialog for RECEIVE_SOUNDTRIGGER_AUDIO, but still want to + // restrict it when the microphone is disabled + mAppOpsManagerInternal.setGlobalRestriction(OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, + enabled, mAppOpsRestrictionToken); break; case CAMERA: mAppOpsManagerInternal.setGlobalRestriction(OP_CAMERA, enabled, diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java index 24eb0ebe3311..6318a99fc9a2 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java @@ -42,6 +42,9 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceSpecificException; +import com.android.server.LocalServices; +import com.android.server.pm.permission.LegacyPermissionManagerInternal; + import java.io.PrintWriter; import java.util.Objects; @@ -123,19 +126,8 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware * Throws a {@link SecurityException} iff the originator has permission to receive data. */ void enforcePermissionsForDataDelivery(@NonNull Identity identity, @NonNull String reason) { - // SoundTrigger data is treated the same as Hotword-source audio. This should incur the - // HOTWORD op instead of the RECORD_AUDIO op. The RECORD_AUDIO permission is still required, - // and since this is a data delivery check, soft denials aren't accepted. - // TODO(b/212458940): Find a better approach for checking the permission that doesn't - // require the client to know such details about the permissions logic. - enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO, - /* allowSoftDenial= */ false); - int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD); - mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp, identity.uid, - identity.packageName, identity.attributionTag, reason); - - enforcePermissionForDataDelivery(mContext, identity, CAPTURE_AUDIO_HOTWORD, - reason); + enforceSoundTriggerRecordAudioPermissionForDataDelivery(identity, reason); + enforcePermissionForDataDelivery(mContext, identity, CAPTURE_AUDIO_HOTWORD, reason); } /** @@ -159,6 +151,19 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware } } + private static void enforceSoundTriggerRecordAudioPermissionForDataDelivery( + @NonNull Identity identity, @NonNull String reason) { + LegacyPermissionManagerInternal lpmi = + LocalServices.getService(LegacyPermissionManagerInternal.class); + final int status = lpmi.checkSoundTriggerRecordAudioPermissionForDataDelivery(identity.uid, + identity.packageName, identity.attributionTag, reason); + if (status != PermissionChecker.PERMISSION_GRANTED) { + throw new SecurityException( + String.format("Failed to obtain permission RECORD_AUDIO for identity %s", + ObjectPrinter.print(identity, 16))); + } + } + /** * Throws a {@link SecurityException} if originator permanently doesn't have the given * permission. diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 5e7b5860629d..977f6fd7b528 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -204,6 +204,7 @@ import com.android.server.SystemServiceManager; import com.android.server.am.MemoryStatUtil.MemoryStat; import com.android.server.health.HealthServiceWrapper; import com.android.server.notification.NotificationManagerService; +import com.android.server.pm.UserManagerInternal; import com.android.server.stats.pull.IonMemoryUtil.IonAllocations; import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot; import com.android.server.stats.pull.netstats.NetworkStatsExt; @@ -4106,11 +4107,24 @@ public class StatsPullAtomService extends SystemService { // Incremental is not enabled on this device. The result list will be empty. return StatsManager.PULL_SUCCESS; } - List<PackageInfo> installedPackages = pm.getInstalledPackages(0); - for (PackageInfo pi : installedPackages) { - if (IncrementalManager.isIncrementalPath(pi.applicationInfo.getBaseCodePath())) { - pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, pi.applicationInfo.uid)); + final long token = Binder.clearCallingIdentity(); + try { + int[] userIds = LocalServices.getService(UserManagerInternal.class).getUserIds(); + for (int userId : userIds) { + List<PackageInfo> installedPackages = pm.getInstalledPackagesAsUser(0, userId); + for (PackageInfo pi : installedPackages) { + if (IncrementalManager.isIncrementalPath( + pi.applicationInfo.getBaseCodePath())) { + pulledData.add( + FrameworkStatsLog.buildStatsEvent(atomTag, pi.applicationInfo.uid)); + } + } } + } catch (Exception e) { + Slog.e(TAG, "failed to pullInstalledIncrementalPackagesLocked", e); + return StatsManager.PULL_SKIP; + } finally { + Binder.restoreCallingIdentity(token); } return StatsManager.PULL_SUCCESS; } diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java index ee30fa2ac928..fb9a4d41ee90 100644 --- a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java +++ b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java @@ -15,6 +15,8 @@ */ package com.android.server.tv.tunerresourcemanager; +import android.media.tv.tunerresourcemanager.TunerResourceManager; + import java.util.HashSet; import java.util.Set; @@ -63,6 +65,11 @@ public final class ClientProfile { private int mNiceValue; /** + * The handle of the primary frontend resource + */ + private int mPrimaryUsingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE; + + /** * List of the frontend handles that are used by the current client. */ private Set<Integer> mUsingFrontendHandles = new HashSet<>(); @@ -175,6 +182,22 @@ public final class ClientProfile { } /** + * Set the primary frontend used by the client + * + * @param frontendHandle being used. + */ + public void setPrimaryFrontend(int frontendHandle) { + mPrimaryUsingFrontendHandle = frontendHandle; + } + + /** + * Get the primary frontend used by the client + */ + public int getPrimaryFrontend() { + return mPrimaryUsingFrontendHandle; + } + + /** * Update the set of client that share frontend with the current client. * * @param clientId the client to share the fe with the current client. @@ -206,6 +229,7 @@ public final class ClientProfile { public void releaseFrontend() { mUsingFrontendHandles.clear(); mShareFeClientIds.clear(); + mPrimaryUsingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE; } /** @@ -276,6 +300,7 @@ public final class ClientProfile { public void reclaimAllResources() { mUsingFrontendHandles.clear(); mShareFeClientIds.clear(); + mPrimaryUsingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE; mUsingLnbHandles.clear(); mUsingCasSystemId = INVALID_RESOURCE_ID; mUsingCiCamId = INVALID_RESOURCE_ID; diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java index af705d597af2..6162d716b85e 100644 --- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java +++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java @@ -42,6 +42,7 @@ import android.os.SystemClock; import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; +import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -72,14 +73,28 @@ public class TunerResourceManagerService extends SystemService implements IBinde private static final long INVALID_THREAD_ID = -1; private static final long TRMS_LOCK_TIMEOUT = 500; + private static final int INVALID_FE_COUNT = -1; + // Map of the registered client profiles private Map<Integer, ClientProfile> mClientProfiles = new HashMap<>(); private int mNextUnusedClientId = 0; // Map of the current available frontend resources private Map<Integer, FrontendResource> mFrontendResources = new HashMap<>(); - // Backup Map of the current available frontend resources + // SparseIntArray of the max usable number for each frontend resource type + private SparseIntArray mFrontendMaxUsableNums = new SparseIntArray(); + // SparseIntArray of the currently used number for each frontend resource type + private SparseIntArray mFrontendUsedNums = new SparseIntArray(); + // SparseIntArray of the existing number for each frontend resource type + private SparseIntArray mFrontendExistingNums = new SparseIntArray(); + + // Backups for the frontend resource maps for enabling testing with custom resource maps + // such as TunerTest.testHasUnusedFrontend1() private Map<Integer, FrontendResource> mFrontendResourcesBackup = new HashMap<>(); + private SparseIntArray mFrontendMaxUsableNumsBackup = new SparseIntArray(); + private SparseIntArray mFrontendUsedNumsBackup = new SparseIntArray(); + private SparseIntArray mFrontendExistingNumsBackup = new SparseIntArray(); + // Map of the current available lnb resources private Map<Integer, LnbResource> mLnbResources = new HashMap<>(); // Map of the current available Cas resources @@ -268,6 +283,29 @@ public class TunerResourceManagerService extends SystemService implements IBinde } @Override + public boolean setMaxNumberOfFrontends(int frontendType, int maxUsableNum) { + enforceTunerAccessPermission("requestFrontend"); + enforceTrmAccessPermission("requestFrontend"); + if (maxUsableNum < 0) { + Slog.w(TAG, "setMaxNumberOfFrontends failed with maxUsableNum:" + maxUsableNum + + " frontendType:" + frontendType); + return false; + } + synchronized (mLock) { + return setMaxNumberOfFrontendsInternal(frontendType, maxUsableNum); + } + } + + @Override + public int getMaxNumberOfFrontends(int frontendType) { + enforceTunerAccessPermission("requestFrontend"); + enforceTrmAccessPermission("requestFrontend"); + synchronized (mLock) { + return getMaxNumberOfFrontendsInternal(frontendType); + } + } + + @Override public void shareFrontend(int selfClientId, int targetClientId) throws RemoteException { enforceTunerAccessPermission("shareFrontend"); enforceTrmAccessPermission("shareFrontend"); @@ -572,71 +610,19 @@ public class TunerResourceManagerService extends SystemService implements IBinde } synchronized (mLock) { - if (mClientProfiles != null) { - pw.println("ClientProfiles:"); - pw.increaseIndent(); - for (Map.Entry<Integer, ClientProfile> entry : mClientProfiles.entrySet()) { - pw.println(entry.getKey() + " : " + entry.getValue()); - } - pw.decreaseIndent(); - } - - if (mFrontendResources != null) { - pw.println("FrontendResources:"); - pw.increaseIndent(); - for (Map.Entry<Integer, FrontendResource> entry - : mFrontendResources.entrySet()) { - pw.println(entry.getKey() + " : " + entry.getValue()); - } - pw.decreaseIndent(); - } - - if (mFrontendResourcesBackup != null) { - pw.println("FrontendResourcesBackUp:"); - pw.increaseIndent(); - for (Map.Entry<Integer, FrontendResource> entry - : mFrontendResourcesBackup.entrySet()) { - pw.println(entry.getKey() + " : " + entry.getValue()); - } - pw.decreaseIndent(); - } - - if (mLnbResources != null) { - pw.println("LnbResources:"); - pw.increaseIndent(); - for (Map.Entry<Integer, LnbResource> entry : mLnbResources.entrySet()) { - pw.println(entry.getKey() + " : " + entry.getValue()); - } - pw.decreaseIndent(); - } - - if (mCasResources != null) { - pw.println("CasResources:"); - pw.increaseIndent(); - for (Map.Entry<Integer, CasResource> entry : mCasResources.entrySet()) { - pw.println(entry.getKey() + " : " + entry.getValue()); - } - pw.decreaseIndent(); - } - - if (mCiCamResources != null) { - pw.println("CiCamResources:"); - pw.increaseIndent(); - for (Map.Entry<Integer, CiCamResource> entry : mCiCamResources.entrySet()) { - pw.println(entry.getKey() + " : " + entry.getValue()); - } - pw.decreaseIndent(); - } - - if (mListeners != null) { - pw.println("Listners:"); - pw.increaseIndent(); - for (Map.Entry<Integer, ResourcesReclaimListenerRecord> entry - : mListeners.entrySet()) { - pw.println(entry.getKey() + " : " + entry.getValue()); - } - pw.decreaseIndent(); - } + dumpMap(mClientProfiles, "ClientProfiles:", "\n", pw); + dumpMap(mFrontendResources, "FrontendResources:", "\n", pw); + dumpSIA(mFrontendExistingNums, "FrontendExistingNums:", ", ", pw); + dumpSIA(mFrontendUsedNums, "FrontendUsedNums:", ", ", pw); + dumpSIA(mFrontendMaxUsableNums, "FrontendMaxUsableNums:", ", ", pw); + dumpMap(mFrontendResourcesBackup, "FrontendResourcesBackUp:", "\n", pw); + dumpSIA(mFrontendExistingNumsBackup, "FrontendExistingNumsBackup:", ", ", pw); + dumpSIA(mFrontendUsedNumsBackup, "FrontendUsedNumsBackup:", ", ", pw); + dumpSIA(mFrontendMaxUsableNumsBackup, "FrontendUsedNumsBackup:", ", ", pw); + dumpMap(mLnbResources, "LnbResource:", "\n", pw); + dumpMap(mCasResources, "CasResource:", "\n", pw); + dumpMap(mCiCamResources, "CiCamResource:", "\n", pw); + dumpMap(mListeners, "Listners:", "\n", pw); } } @@ -786,10 +772,10 @@ public class TunerResourceManagerService extends SystemService implements IBinde protected void storeResourceMapInternal(int resourceType) { switch (resourceType) { case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND: - if (mFrontendResources != null && mFrontendResources.size() > 0) { - mFrontendResourcesBackup.putAll(mFrontendResources); - mFrontendResources.clear(); - } + replaceFeResourceMap(mFrontendResources, mFrontendResourcesBackup); + replaceFeCounts(mFrontendExistingNums, mFrontendExistingNumsBackup); + replaceFeCounts(mFrontendUsedNums, mFrontendUsedNumsBackup); + replaceFeCounts(mFrontendMaxUsableNums, mFrontendMaxUsableNumsBackup); break; // TODO: implement for other resource type when needed default: @@ -800,9 +786,10 @@ public class TunerResourceManagerService extends SystemService implements IBinde protected void clearResourceMapInternal(int resourceType) { switch (resourceType) { case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND: - if (mFrontendResources != null) { - mFrontendResources.clear(); - } + replaceFeResourceMap(null, mFrontendResources); + replaceFeCounts(null, mFrontendExistingNums); + replaceFeCounts(null, mFrontendUsedNums); + replaceFeCounts(null, mFrontendMaxUsableNums); break; // TODO: implement for other resource type when needed default: @@ -813,12 +800,10 @@ public class TunerResourceManagerService extends SystemService implements IBinde protected void restoreResourceMapInternal(int resourceType) { switch (resourceType) { case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND: - if (mFrontendResourcesBackup != null - && mFrontendResourcesBackup.size() > 0) { - mFrontendResources.clear(); - mFrontendResources.putAll(mFrontendResourcesBackup); - mFrontendResourcesBackup.clear(); - } + replaceFeResourceMap(mFrontendResourcesBackup, mFrontendResources); + replaceFeCounts(mFrontendExistingNumsBackup, mFrontendExistingNums); + replaceFeCounts(mFrontendUsedNumsBackup, mFrontendUsedNums); + replaceFeCounts(mFrontendMaxUsableNumsBackup, mFrontendMaxUsableNums); break; // TODO: implement for other resource type when needed default: @@ -954,6 +939,11 @@ public class TunerResourceManagerService extends SystemService implements IBinde for (FrontendResource fr : getFrontendResources().values()) { if (fr.getType() == request.frontendType) { if (!fr.isInUse()) { + // Unused resource cannot be acquired if the max is already reached, but + // TRM still has to look for the reclaim candidate + if (isFrontendMaxNumUseReached(request.frontendType)) { + continue; + } // Grant unused frontend with no exclusive group members first. if (fr.getExclusiveGroupMemberFeHandles().isEmpty()) { grantingFrontendHandle = fr.getHandle(); @@ -1021,6 +1011,9 @@ public class TunerResourceManagerService extends SystemService implements IBinde for (int inUseHandle : newOwnerProfile.getInUseFrontendHandles()) { getFrontendResource(inUseHandle).setOwner(newOwnerId); } + // change the primary frontend + newOwnerProfile.setPrimaryFrontend(currentOwnerProfile.getPrimaryFrontend()); + currentOwnerProfile.setPrimaryFrontend(TunerResourceManager.INVALID_RESOURCE_HANDLE); // double check there is no other resources tied to the previous owner for (int inUseHandle : currentOwnerProfile.getInUseFrontendHandles()) { int ownerId = getFrontendResource(inUseHandle).getOwnerClientId(); @@ -1657,11 +1650,13 @@ public class TunerResourceManagerService extends SystemService implements IBinde FrontendResource grantingFrontend = getFrontendResource(grantingHandle); ClientProfile ownerProfile = getClientProfile(ownerClientId); grantingFrontend.setOwner(ownerClientId); + increFrontendNum(mFrontendUsedNums, grantingFrontend.getType()); ownerProfile.useFrontend(grantingHandle); for (int exclusiveGroupMember : grantingFrontend.getExclusiveGroupMemberFeHandles()) { getFrontendResource(exclusiveGroupMember).setOwner(ownerClientId); ownerProfile.useFrontend(exclusiveGroupMember); } + ownerProfile.setPrimaryFrontend(grantingHandle); } private void updateLnbClientMappingOnNewGrant(int grantingHandle, int ownerClientId) { @@ -1755,6 +1750,109 @@ public class TunerResourceManagerService extends SystemService implements IBinde return mFrontendResources; } + private boolean setMaxNumberOfFrontendsInternal(int frontendType, int maxUsableNum) { + int usedNum = mFrontendUsedNums.get(frontendType, INVALID_FE_COUNT); + if (usedNum == INVALID_FE_COUNT || usedNum <= maxUsableNum) { + mFrontendMaxUsableNums.put(frontendType, maxUsableNum); + return true; + } else { + Slog.e(TAG, "max number of frontend for frontendType: " + frontendType + + " cannot be set to a value lower than the current usage count." + + " (requested max num = " + maxUsableNum + ", current usage = " + usedNum); + return false; + } + } + + private int getMaxNumberOfFrontendsInternal(int frontendType) { + int existingNum = mFrontendExistingNums.get(frontendType, INVALID_FE_COUNT); + if (existingNum == INVALID_FE_COUNT) { + Log.e(TAG, "existingNum is -1 for " + frontendType); + return -1; + } + int maxUsableNum = mFrontendMaxUsableNums.get(frontendType, INVALID_FE_COUNT); + if (maxUsableNum == INVALID_FE_COUNT) { + return existingNum; + } else { + return maxUsableNum; + } + } + + private boolean isFrontendMaxNumUseReached(int frontendType) { + int maxUsableNum = mFrontendMaxUsableNums.get(frontendType, INVALID_FE_COUNT); + if (maxUsableNum == INVALID_FE_COUNT) { + return false; + } + int useNum = mFrontendUsedNums.get(frontendType, INVALID_FE_COUNT); + if (useNum == INVALID_FE_COUNT) { + useNum = 0; + } + return useNum >= maxUsableNum; + } + + private void increFrontendNum(SparseIntArray targetNums, int frontendType) { + int num = targetNums.get(frontendType, INVALID_FE_COUNT); + if (num == INVALID_FE_COUNT) { + targetNums.put(frontendType, 1); + } else { + targetNums.put(frontendType, num + 1); + } + } + + private void decreFrontendNum(SparseIntArray targetNums, int frontendType) { + int num = targetNums.get(frontendType, INVALID_FE_COUNT); + if (num != INVALID_FE_COUNT) { + targetNums.put(frontendType, num - 1); + } + } + + private void replaceFeResourceMap(Map<Integer, FrontendResource> srcMap, Map<Integer, + FrontendResource> dstMap) { + if (dstMap != null) { + dstMap.clear(); + if (srcMap != null && srcMap.size() > 0) { + dstMap.putAll(srcMap); + } + } + } + + private void replaceFeCounts(SparseIntArray srcCounts, SparseIntArray dstCounts) { + if (dstCounts != null) { + dstCounts.clear(); + if (srcCounts != null) { + for (int i = 0; i < srcCounts.size(); i++) { + dstCounts.put(srcCounts.keyAt(i), srcCounts.valueAt(i)); + } + } + } + } + private void dumpMap(Map<?, ?> targetMap, String headline, String delimiter, + IndentingPrintWriter pw) { + if (targetMap != null) { + pw.println(headline); + pw.increaseIndent(); + for (Map.Entry<?, ?> entry : targetMap.entrySet()) { + pw.print(entry.getKey() + " : " + entry.getValue()); + pw.print(delimiter); + } + pw.println(); + pw.decreaseIndent(); + } + } + + private void dumpSIA(SparseIntArray array, String headline, String delimiter, + IndentingPrintWriter pw) { + if (array != null) { + pw.println(headline); + pw.increaseIndent(); + for (int i = 0; i < array.size(); i++) { + pw.print(array.keyAt(i) + " : " + array.valueAt(i)); + pw.print(delimiter); + } + pw.println(); + pw.decreaseIndent(); + } + } + private void addFrontendResource(FrontendResource newFe) { // Update the exclusive group member list in all the existing Frontend resource for (FrontendResource fe : getFrontendResources().values()) { @@ -1771,6 +1869,8 @@ public class TunerResourceManagerService extends SystemService implements IBinde } // Update resource list and available id list mFrontendResources.put(newFe.getHandle(), newFe); + increFrontendNum(mFrontendExistingNums, newFe.getType()); + } private void removeFrontendResource(int removingHandle) { @@ -1789,6 +1889,7 @@ public class TunerResourceManagerService extends SystemService implements IBinde getFrontendResource(excGroupmemberFeHandle) .removeExclusiveGroupMemberFeId(fe.getHandle()); } + decreFrontendNum(mFrontendExistingNums, fe.getType()); mFrontendResources.remove(removingHandle); } @@ -1918,6 +2019,15 @@ public class TunerResourceManagerService extends SystemService implements IBinde } } + + int primaryFeId = profile.getPrimaryFrontend(); + if (primaryFeId != TunerResourceManager.INVALID_RESOURCE_HANDLE) { + FrontendResource primaryFe = getFrontendResource(primaryFeId); + if (primaryFe != null) { + decreFrontendNum(mFrontendUsedNums, primaryFe.getType()); + } + } + profile.releaseFrontend(); } diff --git a/services/core/java/com/android/server/utils/WatchedArrayList.java b/services/core/java/com/android/server/utils/WatchedArrayList.java index 75e39ebb32d8..07474a63cb2a 100644 --- a/services/core/java/com/android/server/utils/WatchedArrayList.java +++ b/services/core/java/com/android/server/utils/WatchedArrayList.java @@ -416,7 +416,7 @@ public class WatchedArrayList<E> extends WatchableImpl dst.mStorage.ensureCapacity(end); for (int i = 0; i < end; i++) { final E val = Snapshots.maybeSnapshot(src.get(i)); - dst.add(val); + dst.mStorage.add(val); } dst.seal(); } diff --git a/services/core/java/com/android/server/utils/WatchedArrayMap.java b/services/core/java/com/android/server/utils/WatchedArrayMap.java index 7c1cde8502bd..63441aac8e1f 100644 --- a/services/core/java/com/android/server/utils/WatchedArrayMap.java +++ b/services/core/java/com/android/server/utils/WatchedArrayMap.java @@ -465,7 +465,7 @@ public class WatchedArrayMap<K, V> extends WatchableImpl for (int i = 0; i < end; i++) { final V val = Snapshots.maybeSnapshot(src.valueAt(i)); final K key = src.keyAt(i); - dst.put(key, val); + dst.mStorage.put(key, val); } dst.seal(); } diff --git a/services/core/java/com/android/server/utils/WatchedArraySet.java b/services/core/java/com/android/server/utils/WatchedArraySet.java index ec80261a2196..a2eaed72dd65 100644 --- a/services/core/java/com/android/server/utils/WatchedArraySet.java +++ b/services/core/java/com/android/server/utils/WatchedArraySet.java @@ -427,7 +427,7 @@ public class WatchedArraySet<E> extends WatchableImpl dst.mStorage.ensureCapacity(end); for (int i = 0; i < end; i++) { final E val = Snapshots.maybeSnapshot(src.valueAt(i)); - dst.append(val); + dst.mStorage.append(val); } dst.seal(); } diff --git a/services/core/java/com/android/server/utils/WatchedLongSparseArray.java b/services/core/java/com/android/server/utils/WatchedLongSparseArray.java index bf23de12ffef..9da9e75f98fb 100644 --- a/services/core/java/com/android/server/utils/WatchedLongSparseArray.java +++ b/services/core/java/com/android/server/utils/WatchedLongSparseArray.java @@ -410,7 +410,7 @@ public class WatchedLongSparseArray<E> extends WatchableImpl for (int i = 0; i < end; i++) { final E val = Snapshots.maybeSnapshot(src.valueAt(i)); final long key = src.keyAt(i); - dst.put(key, val); + dst.mStorage.put(key, val); } dst.seal(); } diff --git a/services/core/java/com/android/server/utils/WatchedSparseArray.java b/services/core/java/com/android/server/utils/WatchedSparseArray.java index 9b99b9176d19..6ce38b71d9cd 100644 --- a/services/core/java/com/android/server/utils/WatchedSparseArray.java +++ b/services/core/java/com/android/server/utils/WatchedSparseArray.java @@ -490,7 +490,7 @@ public class WatchedSparseArray<E> extends WatchableImpl for (int i = 0; i < end; i++) { final E val = Snapshots.maybeSnapshot(src.valueAt(i)); final int key = src.keyAt(i); - dst.put(key, val); + dst.mStorage.put(key, val); } dst.seal(); } diff --git a/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java b/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java index 772a8d07cffb..50e2272afb72 100644 --- a/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java +++ b/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java @@ -310,7 +310,7 @@ public class WatchedSparseBooleanArray extends WatchableImpl } final int end = src.size(); for (int i = 0; i < end; i++) { - dst.put(src.keyAt(i), src.valueAt(i)); + dst.mStorage.put(src.keyAt(i), src.valueAt(i)); } dst.seal(); } diff --git a/services/core/java/com/android/server/utils/WatchedSparseIntArray.java b/services/core/java/com/android/server/utils/WatchedSparseIntArray.java index 72705bf24199..53d168245180 100644 --- a/services/core/java/com/android/server/utils/WatchedSparseIntArray.java +++ b/services/core/java/com/android/server/utils/WatchedSparseIntArray.java @@ -315,7 +315,7 @@ public class WatchedSparseIntArray extends WatchableImpl } final int end = src.size(); for (int i = 0; i < end; i++) { - dst.put(src.keyAt(i), src.valueAt(i)); + dst.mStorage.put(src.keyAt(i), src.valueAt(i)); } dst.seal(); } diff --git a/services/core/java/com/android/server/utils/WatchedSparseSetArray.java b/services/core/java/com/android/server/utils/WatchedSparseSetArray.java index 05db12e49a13..77750ed92273 100644 --- a/services/core/java/com/android/server/utils/WatchedSparseSetArray.java +++ b/services/core/java/com/android/server/utils/WatchedSparseSetArray.java @@ -169,7 +169,7 @@ public class WatchedSparseSetArray<T> extends WatchableImpl implements Snappable final ArraySet set = src.get(i); final int setSize = set.size(); for (int j = 0; j < setSize; j++) { - dst.add(src.keyAt(i), set.valueAt(j)); + dst.mStorage.add(src.keyAt(i), set.valueAt(j)); } } dst.seal(); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 9932272f7473..328a21519ed2 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3532,7 +3532,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final ActivityRecord next = getDisplayArea().topRunningActivity( true /* considerKeyguardState */); - // If the finishing activity is the last activity of a organized TaskFragment and has an + // If the finishing activity is the last activity of an organized TaskFragment and has an // adjacent TaskFragment, check if the activity removal should be delayed. boolean delayRemoval = false; final TaskFragment taskFragment = getTaskFragment(); @@ -3540,7 +3540,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final TaskFragment organized = taskFragment.getOrganizedTaskFragment(); final TaskFragment adjacent = organized != null ? organized.getAdjacentTaskFragment() : null; - if (adjacent != null && organized.topRunningActivity() == null) { + if (adjacent != null && next.isDescendantOf(adjacent) + && organized.topRunningActivity() == null) { delayRemoval = organized.isDelayLastActivityRemoval(); } } @@ -6342,8 +6343,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mSharedStartingData != null ? mSharedStartingData.mAssociatedTask : null; if (associatedTask == null) { removeStartingWindow(); - } else if (associatedTask.getActivity( - r -> r.mVisibleRequested && !r.firstWindowDrawn) == null) { + } else if (associatedTask.getActivity(r -> r.mVisibleRequested && !r.firstWindowDrawn + // Don't block starting window removal if an Activity can't be a starting window + // target. + && r.mSharedStartingData != null) == null) { // The last drawn activity may not be the one that owns the starting window. final ActivityRecord r = associatedTask.topActivityContainsStartingWindow(); if (r != null) { @@ -7727,7 +7730,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (isFixedOrientationLetterboxAllowed || mCompatDisplayInsets != null // In fullscreen, can be letterboxed for aspect ratio. || !inMultiWindowMode()) { - updateResolvedBoundsHorizontalPosition(newParentConfiguration); + updateResolvedBoundsPosition(newParentConfiguration); } if (mVisibleRequested) { @@ -7830,39 +7833,61 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } /** - * Adjusts horizontal position of resolved bounds if they doesn't fill the parent using gravity + * Adjusts position of resolved bounds if they doesn't fill the parent using gravity * requested in the config or via an ADB command. For more context see {@link - * LetterboxUiController#getHorizontalPositionMultiplier(Configuration)}. + * LetterboxUiController#getHorizontalPositionMultiplier(Configuration)} and + * {@link LetterboxUiController#getVerticalPositionMultiplier(Configuration)} */ - private void updateResolvedBoundsHorizontalPosition(Configuration newParentConfiguration) { + private void updateResolvedBoundsPosition(Configuration newParentConfiguration) { final Configuration resolvedConfig = getResolvedOverrideConfiguration(); final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); final Rect screenResolvedBounds = mSizeCompatBounds != null ? mSizeCompatBounds : resolvedBounds; final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds(); final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds(); - if (resolvedBounds.isEmpty() || parentBounds.width() == screenResolvedBounds.width()) { + if (resolvedBounds.isEmpty()) { return; } - + // Horizontal position int offsetX = 0; - if (screenResolvedBounds.width() >= parentAppBounds.width()) { - // If resolved bounds overlap with insets, center within app bounds. - offsetX = getHorizontalCenterOffset( - parentAppBounds.width(), screenResolvedBounds.width()); - } else { - float positionMultiplier = - mLetterboxUiController.getHorizontalPositionMultiplier(newParentConfiguration); - offsetX = (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width()) - * positionMultiplier); + if (parentBounds.width() != screenResolvedBounds.width()) { + if (screenResolvedBounds.width() >= parentAppBounds.width()) { + // If resolved bounds overlap with insets, center within app bounds. + offsetX = getCenterOffset( + parentAppBounds.width(), screenResolvedBounds.width()); + } else { + float positionMultiplier = + mLetterboxUiController.getHorizontalPositionMultiplier( + newParentConfiguration); + offsetX = (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width()) + * positionMultiplier); + } + } + + // Vertical position + int offsetY = 0; + if (parentBounds.height() != screenResolvedBounds.height()) { + + if (screenResolvedBounds.height() >= parentAppBounds.height()) { + // If resolved bounds overlap with insets, center within app bounds. + offsetY = getCenterOffset( + parentAppBounds.height(), screenResolvedBounds.height()); + } else { + float positionMultiplier = + mLetterboxUiController.getVerticalPositionMultiplier( + newParentConfiguration); + offsetY = (int) Math.ceil((parentAppBounds.height() - screenResolvedBounds.height()) + * positionMultiplier); + } } if (mSizeCompatBounds != null) { - mSizeCompatBounds.offset(offsetX, 0 /* offsetY */); + mSizeCompatBounds.offset(offsetX , offsetY); + final int dy = mSizeCompatBounds.top - resolvedBounds.top; final int dx = mSizeCompatBounds.left - resolvedBounds.left; - offsetBounds(resolvedConfig, dx, 0 /* offsetY */); + offsetBounds(resolvedConfig, dx, dy); } else { - offsetBounds(resolvedConfig, offsetX, 0 /* offsetY */); + offsetBounds(resolvedConfig, offsetX, offsetY); } // Since bounds has changed, the configuration needs to be computed accordingly. @@ -7986,20 +8011,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // orientation with insets applied. return; } - // Not using Task#isResizeable() or ActivityRecord#isResizeable() directly because app - // compatibility testing showed that android:supportsPictureInPicture="true" alone is not - // sufficient signal for not letterboxing an app. - // TODO(214602463): Remove multi-window check since orientation and aspect ratio - // restrictions should always be applied in multi-window. - final boolean isResizeable = task != null - // Activity should be resizable if the task is. - ? task.isResizeable(/* checkPictureInPictureSupport */ false) - || isResizeable(/* checkPictureInPictureSupport */ false) - : isResizeable(/* checkPictureInPictureSupport */ false); - if (WindowConfiguration.inMultiWindowMode(windowingMode) && isResizeable) { - // Ignore orientation request for resizable apps in multi window. - return; - } + if (windowingMode == WINDOWING_MODE_PINNED) { // PiP bounds have higher priority than the requested orientation. Otherwise the // activity may be squeezed into a small piece. @@ -8077,14 +8089,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mIsAspectRatioApplied = applyAspectRatio(resolvedBounds, containingBoundsWithInsets, containingBounds, desiredAspectRatio, true); - // Vertically center if orientation is landscape. Center within parent bounds with insets - // to ensure that insets do not trim height. Bounds will later be horizontally centered in - // {@link updateResolvedBoundsHorizontalPosition()} regardless of orientation. - if (forcedOrientation == ORIENTATION_LANDSCAPE) { - final int offsetY = parentBoundsWithInsets.centerY() - resolvedBounds.centerY(); - resolvedBounds.offset(0, offsetY); - } - if (mCompatDisplayInsets != null) { mCompatDisplayInsets.getBoundsByRotation( mTmpBounds, newParentConfig.windowConfiguration.getRotation()); @@ -8107,10 +8111,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** * Resolves aspect ratio restrictions for an activity. If the bounds are restricted by - * aspect ratio, the position will be adjusted later in {@link - * updateResolvedBoundsHorizontalPosition} within parent's app bounds to balance the visual - * appearance. The policy of aspect ratio has higher priority than the requested override - * bounds. + * aspect ratio, the position will be adjusted later in {@link #updateResolvedBoundsPosition + * within parent's app bounds to balance the visual appearance. The policy of aspect ratio has + * higher priority than the requested override bounds. */ private void resolveAspectRatioRestriction(Configuration newParentConfiguration) { final Configuration resolvedConfig = getResolvedOverrideConfiguration(); @@ -8122,7 +8125,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mTmpBounds.setEmpty(); mIsAspectRatioApplied = applyAspectRatio(mTmpBounds, parentAppBounds, parentBounds); // If the out bounds is not empty, it means the activity cannot fill parent's app bounds, - // then they should be aligned later in #updateResolvedBoundsHorizontalPosition(). + // then they should be aligned later in #updateResolvedBoundsPosition() if (!mTmpBounds.isEmpty()) { resolvedBounds.set(mTmpBounds); } @@ -8256,22 +8259,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A forAllWindows(WindowState::updateGlobalScale, false /* traverseTopToBottom */); } - // Vertically center within parent (bounds) - this is a UX choice and exclude the horizontal - // decor if needed. Horizontal position is adjusted in - // updateResolvedBoundsHorizontalPosition. + // The position will be later adjusted in updateResolvedBoundsPosition. // Above coordinates are in "@" space, now place "*" and "#" to screen space. final boolean fillContainer = resolvedBounds.equals(containingBounds); final int screenPosX = fillContainer ? containerBounds.left : containerAppBounds.left; - // If the activity is not in size compat mode, calculate vertical centering - // from the container and resolved bounds. - // If the activity is in size compat mode, calculate vertical centering - // from the container and size compat bounds. - // The container bounds contain the parent bounds offset in the display, for - // example when an activity is in the lower split of split screen. - final int screenPosY = (mSizeCompatBounds == null - ? (containerBounds.height() - resolvedBounds.height()) / 2 - : (containerBounds.height() - mSizeCompatBounds.height()) / 2) - + containerBounds.top; + final int screenPosY = fillContainer ? containerBounds.top : containerAppBounds.top; if (screenPosX != 0 || screenPosY != 0) { if (mSizeCompatBounds != null) { @@ -8331,9 +8323,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return true; } - /** @return The horizontal offset of putting the content in the center of viewport. */ - private static int getHorizontalCenterOffset(int viewportW, int contentW) { - return (int) ((viewportW - contentW + 1) * 0.5f); + /** @return The horizontal / vertical offset of putting the content in the center of viewport.*/ + private static int getCenterOffset(int viewportDim, int contentDim) { + return (int) ((viewportDim - contentDim + 1) * 0.5f); } private static void offsetBounds(Configuration inOutConfig, int offsetX, int offsetY) { @@ -9341,6 +9333,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A sb.append(mUserId); sb.append(' '); sb.append(intent.getComponent().flattenToShortString()); + sb.append("}"); stringName = sb.toString(); return stringName; } @@ -9595,7 +9588,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A outBounds.bottom = dH; outBounds.right = (int) ((float) dH * dH / dW); } - outBounds.offset(getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */); + outBounds.offset(getCenterOffset(mWidth, outBounds.width()), 0 /* dy */); } outAppBounds.set(outBounds); diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index 9771b347cfb1..4e2d1aa803af 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -528,6 +528,8 @@ public class ActivityStartController { .setRequestCode(-1) .setCallingUid(callingUid) .setCallingPid(callingPid) + .setRealCallingUid(callingUid) + .setRealCallingPid(callingPid) .setUserId(caller != null ? caller.mUserId : mService.getCurrentUserId()) .execute(); } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 85305cc6403f..0d447e34502e 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1674,6 +1674,7 @@ class ActivityStarter { private @Nullable Task handleStartResult(@NonNull ActivityRecord started, ActivityOptions options, int result, Transition newTransition, RemoteTransition remoteTransition) { + final boolean userLeaving = mSupervisor.mUserLeaving; mSupervisor.mUserLeaving = false; final Task currentRootTask = started.getRootTask(); final Task startedActivityRootTask = @@ -1747,7 +1748,7 @@ class ActivityStarter { // until after we launched to identify the relevant activity. transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask); } - if (!mSupervisor.mUserLeaving) { + if (!userLeaving) { // no-user-leaving implies not entering PiP. transitionController.setCanPipOnFinish(false /* canPipOnFinish */); } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 17ce26535e3a..dcd8f0fb4db2 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5282,7 +5282,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp void prepareAppTransition(@WindowManager.TransitionType int transit, @WindowManager.TransitionFlags int flags) { final boolean prepared = mAppTransition.prepareAppTransition(transit, flags); - if (prepared && okToAnimate()) { + if (prepared && okToAnimate() && transit != TRANSIT_NONE) { mSkipAppTransitionAnimation = false; } } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index d1ba77d8d6b5..c4e50795fb93 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -652,17 +652,19 @@ public class DisplayPolicy { mForceShowNavBarSettingsObserver = new ForceShowNavBarSettingsObserver( mHandler, mContext); - mForceShowNavBarSettingsObserver.setOnChangeRunnable(() -> { - synchronized (mLock) { - mForceShowNavigationBarEnabled = - mForceShowNavBarSettingsObserver.isEnabled(); - updateSystemBarAttributes(); - } - }); + mForceShowNavBarSettingsObserver.setOnChangeRunnable(this::updateForceShowNavBarSettings); mForceShowNavigationBarEnabled = mForceShowNavBarSettingsObserver.isEnabled(); mHandler.post(mForceShowNavBarSettingsObserver::register); } + private void updateForceShowNavBarSettings() { + synchronized (mLock) { + mForceShowNavigationBarEnabled = + mForceShowNavBarSettingsObserver.isEnabled(); + updateSystemBarAttributes(); + } + } + /** * Returns the first non-null alt bar window matching the given position. */ @@ -1817,6 +1819,7 @@ public class DisplayPolicy { */ public void switchUser() { updateCurrentUserResources(); + updateForceShowNavBarSettings(); } /** diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index ea72e12783c3..ce416ad89c95 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -416,8 +416,22 @@ final class InputMonitor { final IBinder focusToken = focus != null ? focus.mInputChannelToken : null; if (focusToken == null) { + if (recentsAnimationInputConsumer != null + && recentsAnimationInputConsumer.mWindowHandle != null + && mInputFocus == recentsAnimationInputConsumer.mWindowHandle.token) { + // Avoid removing input focus from recentsAnimationInputConsumer. + // When the recents animation input consumer has the input focus, + // mInputFocus does not match to mDisplayContent.mCurrentFocus. Making it to be + // a special case, that do not remove the input focus from it when + // mDisplayContent.mCurrentFocus is null. This special case should be removed + // once recentAnimationInputConsumer is removed. + return; + } // When an app is focused, but its window is not showing yet, remove the input focus - // from the current window. + // from the current window. This enforces the input focus to match + // mDisplayContent.mCurrentFocus. However, if more special cases are discovered that + // the input focus and mDisplayContent.mCurrentFocus are expected to mismatch, + // the whole logic of how and when to revoke focus needs to be checked. if (mDisplayContent.mFocusedApp != null && mInputFocus != null) { ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "App %s is focused," + " but the window is not ready. Start a transaction to remove focus from" diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java index 40df02c176e5..61c09cd60413 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -72,7 +72,8 @@ public class Letterbox { private final LetterboxSurface mFullWindowSurface = new LetterboxSurface("fullWindow"); private final LetterboxSurface[] mSurfaces = { mLeft, mTop, mRight, mBottom }; // Reachability gestures. - private final IntConsumer mDoubleTapCallback; + private final IntConsumer mDoubleTapCallbackX; + private final IntConsumer mDoubleTapCallbackY; /** * Constructs a Letterbox. @@ -86,7 +87,8 @@ public class Letterbox { Supplier<Boolean> hasWallpaperBackgroundSupplier, Supplier<Integer> blurRadiusSupplier, Supplier<Float> darkScrimAlphaSupplier, - IntConsumer doubleTapCallback) { + IntConsumer doubleTapCallbackX, + IntConsumer doubleTapCallbackY) { mSurfaceControlFactory = surfaceControlFactory; mTransactionFactory = transactionFactory; mAreCornersRounded = areCornersRounded; @@ -94,7 +96,8 @@ public class Letterbox { mHasWallpaperBackgroundSupplier = hasWallpaperBackgroundSupplier; mBlurRadiusSupplier = blurRadiusSupplier; mDarkScrimAlphaSupplier = darkScrimAlphaSupplier; - mDoubleTapCallback = doubleTapCallback; + mDoubleTapCallbackX = doubleTapCallbackX; + mDoubleTapCallbackY = doubleTapCallbackY; } /** @@ -264,7 +267,8 @@ public class Letterbox { @Override public boolean onDoubleTapEvent(MotionEvent e) { if (e.getAction() == MotionEvent.ACTION_UP) { - mDoubleTapCallback.accept((int) e.getX()); + mDoubleTapCallbackX.accept((int) e.getX()); + mDoubleTapCallbackY.accept((int) e.getY()); return true; } return false; diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index ad2767c41e82..bef8da8ff917 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -55,25 +55,48 @@ final class LetterboxConfiguration { static final int LETTERBOX_BACKGROUND_WALLPAPER = 3; /** - * Enum for Letterbox reachability position types. + * Enum for Letterbox horizontal reachability position types. * * <p>Order from left to right is important since it's used in {@link * #movePositionForReachabilityToNextRightStop} and {@link * #movePositionForReachabilityToNextLeftStop}. */ @Retention(RetentionPolicy.SOURCE) - @IntDef({LETTERBOX_REACHABILITY_POSITION_LEFT, LETTERBOX_REACHABILITY_POSITION_CENTER, - LETTERBOX_REACHABILITY_POSITION_RIGHT}) - @interface LetterboxReachabilityPosition {}; + @IntDef({LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT, + LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER, + LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT}) + @interface LetterboxHorizontalReachabilityPosition {}; /** Letterboxed app window is aligned to the left side. */ - static final int LETTERBOX_REACHABILITY_POSITION_LEFT = 0; + static final int LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT = 0; /** Letterboxed app window is positioned in the horizontal center. */ - static final int LETTERBOX_REACHABILITY_POSITION_CENTER = 1; + static final int LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER = 1; /** Letterboxed app window is aligned to the right side. */ - static final int LETTERBOX_REACHABILITY_POSITION_RIGHT = 2; + static final int LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT = 2; + + /** + * Enum for Letterbox vertical reachability position types. + * + * <p>Order from top to bottom is important since it's used in {@link + * #movePositionForReachabilityToNextBottomStop} and {@link + * #movePositionForReachabilityToNextTopStop}. + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP, + LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER, + LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM}) + @interface LetterboxVerticalReachabilityPosition {}; + + /** Letterboxed app window is aligned to the left side. */ + static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP = 0; + + /** Letterboxed app window is positioned in the vertical center. */ + static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER = 1; + + /** Letterboxed app window is aligned to the right side. */ + static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM = 2; final Context mContext; @@ -106,25 +129,50 @@ final class LetterboxConfiguration { // side of the screen and 1.0 to the right side. private float mLetterboxHorizontalPositionMultiplier; - // Default horizontal position the letterboxed app window when reachability is enabled and - // an app is fullscreen in landscape device orientatio. - // It is used as a starting point for mLetterboxPositionForReachability. - @LetterboxReachabilityPosition - private int mDefaultPositionForReachability; + // Vertical position of a center of the letterboxed app window. 0 corresponds to the top + // side of the screen and 1.0 to the bottom side. + private float mLetterboxVerticalPositionMultiplier; + + // Default horizontal position the letterboxed app window when horizontal reachability is + // enabled and an app is fullscreen in landscape device orientation. + // It is used as a starting point for mLetterboxPositionForHorizontalReachability. + @LetterboxHorizontalReachabilityPosition + private int mDefaultPositionForHorizontalReachability; + + // Default vertical position the letterboxed app window when vertical reachability is enabled + // and an app is fullscreen in portrait device orientation. + // It is used as a starting point for mLetterboxPositionForVerticalReachability. + @LetterboxVerticalReachabilityPosition + private int mDefaultPositionForVerticalReachability; + + // Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps in + // landscape device orientation. + private boolean mIsHorizontalReachabilityEnabled; + + // Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps in + // portrait device orientation. + private boolean mIsVerticalReachabilityEnabled; - // Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape - // device orientation. - private boolean mIsReachabilityEnabled; // Horizontal position of a center of the letterboxed app window which is global to prevent // "jumps" when switching between letterboxed apps. It's updated to reposition the app window // in response to a double tap gesture (see LetterboxUiController#handleDoubleTap). Used in // LetterboxUiController#getHorizontalPositionMultiplier which is called from - // ActivityRecord#updateResolvedBoundsHorizontalPosition. + // ActivityRecord#updateResolvedBoundsPosition. // TODO(b/199426138): Global reachability setting causes a jump when resuming an app from // Overview after changing position in another app. - @LetterboxReachabilityPosition - private volatile int mLetterboxPositionForReachability; + @LetterboxHorizontalReachabilityPosition + private volatile int mLetterboxPositionForHorizontalReachability; + + // Vertical position of a center of the letterboxed app window which is global to prevent + // "jumps" when switching between letterboxed apps. It's updated to reposition the app window + // in response to a double tap gesture (see LetterboxUiController#handleDoubleTap). Used in + // LetterboxUiController#getVerticalPositionMultiplier which is called from + // ActivityRecord#updateResolvedBoundsPosition. + // TODO(b/199426138): Global reachability setting causes a jump when resuming an app from + // Overview after changing position in another app. + @LetterboxVerticalReachabilityPosition + private volatile int mLetterboxPositionForVerticalReachability; // Whether education is allowed for letterboxed fullscreen apps. private boolean mIsEducationEnabled; @@ -142,10 +190,16 @@ final class LetterboxConfiguration { R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha); mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat( R.dimen.config_letterboxHorizontalPositionMultiplier); - mIsReachabilityEnabled = mContext.getResources().getBoolean( - R.bool.config_letterboxIsReachabilityEnabled); - mDefaultPositionForReachability = readLetterboxReachabilityPositionFromConfig(mContext); - mLetterboxPositionForReachability = mDefaultPositionForReachability; + mIsHorizontalReachabilityEnabled = mContext.getResources().getBoolean( + R.bool.config_letterboxIsHorizontalReachabilityEnabled); + mIsVerticalReachabilityEnabled = mContext.getResources().getBoolean( + R.bool.config_letterboxIsVerticalReachabilityEnabled); + mDefaultPositionForHorizontalReachability = + readLetterboxHorizontalReachabilityPositionFromConfig(mContext); + mDefaultPositionForVerticalReachability = + readLetterboxVerticalReachabilityPositionFromConfig(mContext); + mLetterboxPositionForHorizontalReachability = mDefaultPositionForHorizontalReachability; + mLetterboxPositionForVerticalReachability = mDefaultPositionForVerticalReachability; mIsEducationEnabled = mContext.getResources().getBoolean( R.bool.config_letterboxIsEducationEnabled); } @@ -375,6 +429,19 @@ final class LetterboxConfiguration { ? 0.5f : mLetterboxHorizontalPositionMultiplier; } + /* + * Gets vertical position of a center of the letterboxed app window specified + * in {@link com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier} + * or via an ADB command. 0 corresponds to the top side of the screen and 1 to the + * bottom side. + */ + float getLetterboxVerticalPositionMultiplier() { + return (mLetterboxVerticalPositionMultiplier < 0.0f + || mLetterboxVerticalPositionMultiplier > 1.0f) + // Default to central position if invalid value is provided. + ? 0.5f : mLetterboxVerticalPositionMultiplier; + } + /** * Overrides horizontal position of a center of the letterboxed app window. If given value < 0 * or > 1, then it and a value of {@link @@ -386,6 +453,16 @@ final class LetterboxConfiguration { } /** + * Overrides vertical position of a center of the letterboxed app window. If given value < 0 + * or > 1, then it and a value of {@link + * com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier} are ignored and + * central position (0.5) is used. + */ + void setLetterboxVerticalPositionMultiplier(float multiplier) { + mLetterboxVerticalPositionMultiplier = multiplier; + } + + /** * Resets horizontal position of a center of the letterboxed app window to {@link * com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}. */ @@ -394,65 +471,145 @@ final class LetterboxConfiguration { com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier); } + /** + * Resets vertical position of a center of the letterboxed app window to {@link + * com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier}. + */ + void resetLetterboxVerticalPositionMultiplier() { + mLetterboxVerticalPositionMultiplier = mContext.getResources().getFloat( + com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier); + } + /* - * Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape - * device orientation. + * Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps in + * landscape device orientation. */ - boolean getIsReachabilityEnabled() { - return mIsReachabilityEnabled; + boolean getIsHorizontalReachabilityEnabled() { + return mIsHorizontalReachabilityEnabled; + } + + /* + * Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps in + * portrait device orientation. + */ + boolean getIsVerticalReachabilityEnabled() { + return mIsVerticalReachabilityEnabled; } /** - * Overrides whether reachability repositioning is allowed for letterboxed fullscreen apps in - * landscape device orientation. + * Overrides whether horizontal reachability repositioning is allowed for letterboxed fullscreen + * apps in landscape device orientation. */ - void setIsReachabilityEnabled(boolean enabled) { - mIsReachabilityEnabled = enabled; + void setIsHorizontalReachabilityEnabled(boolean enabled) { + mIsHorizontalReachabilityEnabled = enabled; } /** - * Resets whether reachability repositioning is allowed for letterboxed fullscreen apps in - * landscape device orientation to {@link R.bool.config_letterboxIsReachabilityEnabled}. + * Overrides whether vertical reachability repositioning is allowed for letterboxed fullscreen + * apps in portrait device orientation. */ - void resetIsReachabilityEnabled() { - mIsReachabilityEnabled = mContext.getResources().getBoolean( - R.bool.config_letterboxIsReachabilityEnabled); + void setIsVerticalReachabilityEnabled(boolean enabled) { + mIsVerticalReachabilityEnabled = enabled; } - /* - * Gets default horizontal position of the letterboxed app window when reachability is enabled. - * Specified in {@link R.integer.config_letterboxDefaultPositionForReachability} or via an ADB - * command. + /** + * Resets whether horizontal reachability repositioning is allowed for letterboxed fullscreen + * apps in landscape device orientation to + * {@link R.bool.config_letterboxIsHorizontalReachabilityEnabled}. */ - @LetterboxReachabilityPosition - int getDefaultPositionForReachability() { - return mDefaultPositionForReachability; + void resetIsHorizontalReachabilityEnabled() { + mIsHorizontalReachabilityEnabled = mContext.getResources().getBoolean( + R.bool.config_letterboxIsHorizontalReachabilityEnabled); } /** - * Overrides default horizonal position of the letterboxed app window when reachability + * Resets whether vertical reachability repositioning is allowed for letterboxed fullscreen apps + * in portrait device orientation to + * {@link R.bool.config_letterboxIsVerticalReachabilityEnabled}. + */ + void resetIsVerticalReachabilityEnabled() { + mIsVerticalReachabilityEnabled = mContext.getResources().getBoolean( + R.bool.config_letterboxIsVerticalReachabilityEnabled); + } + + /* + * Gets default horizontal position of the letterboxed app window when horizontal reachability * is enabled. + * + * <p> Specified in {@link R.integer.config_letterboxDefaultPositionForHorizontalReachability} + * or via an ADB command. */ - void setDefaultPositionForReachability(@LetterboxReachabilityPosition int position) { - mDefaultPositionForReachability = position; + @LetterboxHorizontalReachabilityPosition + int getDefaultPositionForHorizontalReachability() { + return mDefaultPositionForHorizontalReachability; + } + + /* + * Gets default vertical position of the letterboxed app window when vertical reachability is + * enabled. + * + * <p> Specified in {@link R.integer.config_letterboxDefaultPositionForVerticalReachability} or + * via an ADB command. + */ + @LetterboxVerticalReachabilityPosition + int getDefaultPositionForVerticalReachability() { + return mDefaultPositionForVerticalReachability; + } + + /** + * Overrides default horizontal position of the letterboxed app window when horizontal + * reachability is enabled. + */ + void setDefaultPositionForHorizontalReachability( + @LetterboxHorizontalReachabilityPosition int position) { + mDefaultPositionForHorizontalReachability = position; } /** - * Resets default horizontal position of the letterboxed app window when reachability is - * enabled to {@link R.integer.config_letterboxDefaultPositionForReachability}. + * Overrides default vertical position of the letterboxed app window when vertical + * reachability is enabled. */ - void resetDefaultPositionForReachability() { - mDefaultPositionForReachability = readLetterboxReachabilityPositionFromConfig(mContext); + void setDefaultPositionForVerticalReachability( + @LetterboxVerticalReachabilityPosition int position) { + mDefaultPositionForVerticalReachability = position; } - @LetterboxReachabilityPosition - private static int readLetterboxReachabilityPositionFromConfig(Context context) { + /** + * Resets default horizontal position of the letterboxed app window when horizontal reachability + * is enabled to {@link R.integer.config_letterboxDefaultPositionForHorizontalReachability}. + */ + void resetDefaultPositionForHorizontalReachability() { + mDefaultPositionForHorizontalReachability = + readLetterboxHorizontalReachabilityPositionFromConfig(mContext); + } + + /** + * Resets default vertical position of the letterboxed app window when vertical reachability + * is enabled to {@link R.integer.config_letterboxDefaultPositionForVerticalReachability}. + */ + void resetDefaultPositionForVerticalReachability() { + mDefaultPositionForVerticalReachability = + readLetterboxVerticalReachabilityPositionFromConfig(mContext); + } + + @LetterboxHorizontalReachabilityPosition + private static int readLetterboxHorizontalReachabilityPositionFromConfig(Context context) { int position = context.getResources().getInteger( - R.integer.config_letterboxDefaultPositionForReachability); - return position == LETTERBOX_REACHABILITY_POSITION_LEFT - || position == LETTERBOX_REACHABILITY_POSITION_CENTER - || position == LETTERBOX_REACHABILITY_POSITION_RIGHT - ? position : LETTERBOX_REACHABILITY_POSITION_CENTER; + R.integer.config_letterboxDefaultPositionForHorizontalReachability); + return position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT + || position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER + || position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT + ? position : LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER; + } + + @LetterboxVerticalReachabilityPosition + private static int readLetterboxVerticalReachabilityPositionFromConfig(Context context) { + int position = context.getResources().getInteger( + R.integer.config_letterboxDefaultPositionForVerticalReachability); + return position == LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP + || position == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER + || position == LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM + ? position : LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER; } /* @@ -462,48 +619,108 @@ final class LetterboxConfiguration { * <p>The position multiplier is changed after each double tap in the letterbox area. */ float getHorizontalMultiplierForReachability() { - switch (mLetterboxPositionForReachability) { - case LETTERBOX_REACHABILITY_POSITION_LEFT: + switch (mLetterboxPositionForHorizontalReachability) { + case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT: + return 0.0f; + case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER: + return 0.5f; + case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT: + return 1.0f; + default: + throw new AssertionError( + "Unexpected letterbox position type: " + + mLetterboxPositionForHorizontalReachability); + } + } + /* + * Gets vertical position of a center of the letterboxed app window when reachability + * is enabled specified. 0 corresponds to the top side of the screen and 1 to the bottom side. + * + * <p>The position multiplier is changed after each double tap in the letterbox area. + */ + float getVerticalMultiplierForReachability() { + switch (mLetterboxPositionForVerticalReachability) { + case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP: return 0.0f; - case LETTERBOX_REACHABILITY_POSITION_CENTER: + case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER: return 0.5f; - case LETTERBOX_REACHABILITY_POSITION_RIGHT: + case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM: return 1.0f; default: throw new AssertionError( - "Unexpected letterbox position type: " + mLetterboxPositionForReachability); + "Unexpected letterbox position type: " + + mLetterboxPositionForVerticalReachability); } } - /** Returns a string representing the given {@link LetterboxReachabilityPosition}. */ - static String letterboxReachabilityPositionToString( - @LetterboxReachabilityPosition int position) { + /** Returns a string representing the given {@link LetterboxHorizontalReachabilityPosition}. */ + static String letterboxHorizontalReachabilityPositionToString( + @LetterboxHorizontalReachabilityPosition int position) { switch (position) { - case LETTERBOX_REACHABILITY_POSITION_LEFT: - return "LETTERBOX_REACHABILITY_POSITION_LEFT"; - case LETTERBOX_REACHABILITY_POSITION_CENTER: - return "LETTERBOX_REACHABILITY_POSITION_CENTER"; - case LETTERBOX_REACHABILITY_POSITION_RIGHT: - return "LETTERBOX_REACHABILITY_POSITION_RIGHT"; + case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT: + return "LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT"; + case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER: + return "LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER"; + case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT: + return "LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT"; default: throw new AssertionError( "Unexpected letterbox position type: " + position); } } + /** Returns a string representing the given {@link LetterboxVerticalReachabilityPosition}. */ + static String letterboxVerticalReachabilityPositionToString( + @LetterboxVerticalReachabilityPosition int position) { + switch (position) { + case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP: + return "LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP"; + case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER: + return "LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER"; + case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM: + return "LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM"; + default: + throw new AssertionError( + "Unexpected letterbox position type: " + position); + } + } + + /** + * Changes letterbox position for horizontal reachability to the next available one on the + * right side. + */ + void movePositionForHorizontalReachabilityToNextRightStop() { + mLetterboxPositionForHorizontalReachability = Math.min( + mLetterboxPositionForHorizontalReachability + 1, + LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT); + } + + /** + * Changes letterbox position for horizontal reachability to the next available one on the left + * side. + */ + void movePositionForHorizontalReachabilityToNextLeftStop() { + mLetterboxPositionForHorizontalReachability = + Math.max(mLetterboxPositionForHorizontalReachability - 1, 0); + } + /** - * Changes letterbox position for reachability to the next available one on the right side. + * Changes letterbox position for vertical reachability to the next available one on the bottom + * side. */ - void movePositionForReachabilityToNextRightStop() { - mLetterboxPositionForReachability = Math.min( - mLetterboxPositionForReachability + 1, LETTERBOX_REACHABILITY_POSITION_RIGHT); + void movePositionForVerticalReachabilityToNextBottomStop() { + mLetterboxPositionForVerticalReachability = Math.min( + mLetterboxPositionForVerticalReachability + 1, + LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM); } /** - * Changes letterbox position for reachability to the next available one on the left side. + * Changes letterbox position for vertical reachability to the next available one on the top + * side. */ - void movePositionForReachabilityToNextLeftStop() { - mLetterboxPositionForReachability = Math.max(mLetterboxPositionForReachability - 1, 0); + void movePositionForVerticalReachabilityToNextTopStop() { + mLetterboxPositionForVerticalReachability = + Math.max(mLetterboxPositionForVerticalReachability - 1, 0); } /** diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index bb15d76c3bac..201520677b26 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -163,7 +163,8 @@ final class LetterboxUiController { this::hasWallpaperBackgroudForLetterbox, this::getLetterboxWallpaperBlurRadius, this::getLetterboxWallpaperDarkScrimAlpha, - this::handleDoubleTap); + this::handleHorizontalDoubleTap, + this::handleVerticalDoubleTap); mLetterbox.attachInput(w); } mActivityRecord.getPosition(mTmpPoint); @@ -193,17 +194,28 @@ final class LetterboxUiController { float getHorizontalPositionMultiplier(Configuration parentConfiguration) { // Don't check resolved configuration because it may not be updated yet during // configuration change. - return isReachabilityEnabled(parentConfiguration) + return isHorizontalReachabilityEnabled(parentConfiguration) // Using the last global dynamic position to avoid "jumps" when moving // between apps or activities. ? mLetterboxConfiguration.getHorizontalMultiplierForReachability() : mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier(); } + float getVerticalPositionMultiplier(Configuration parentConfiguration) { + // Don't check resolved configuration because it may not be updated yet during + // configuration change. + return isVerticalReachabilityEnabled(parentConfiguration) + // Using the last global dynamic position to avoid "jumps" when moving + // between apps or activities. + ? mLetterboxConfiguration.getVerticalMultiplierForReachability() + : mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier(); + } + float getFixedOrientationLetterboxAspectRatio(Configuration parentConfiguration) { // Don't check resolved windowing mode because it may not be updated yet during // configuration change. - if (!isReachabilityEnabled(parentConfiguration)) { + if (!isHorizontalReachabilityEnabled(parentConfiguration) + && !isVerticalReachabilityEnabled(parentConfiguration)) { return mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(); } @@ -225,8 +237,8 @@ final class LetterboxUiController { return mActivityRecord.mWmService.mContext.getResources(); } - private void handleDoubleTap(int x) { - if (!isReachabilityEnabled() || mActivityRecord.isInTransition()) { + private void handleHorizontalDoubleTap(int x) { + if (!isHorizontalReachabilityEnabled() || mActivityRecord.isInTransition()) { return; } @@ -237,10 +249,32 @@ final class LetterboxUiController { if (mLetterbox.getInnerFrame().left > x) { // Moving to the next stop on the left side of the app window: right > center > left. - mLetterboxConfiguration.movePositionForReachabilityToNextLeftStop(); + mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextLeftStop(); } else if (mLetterbox.getInnerFrame().right < x) { // Moving to the next stop on the right side of the app window: left > center > right. - mLetterboxConfiguration.movePositionForReachabilityToNextRightStop(); + mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextRightStop(); + } + + // TODO(197549949): Add animation for transition. + mActivityRecord.recomputeConfiguration(); + } + + private void handleVerticalDoubleTap(int y) { + if (!isVerticalReachabilityEnabled() || mActivityRecord.isInTransition()) { + return; + } + + if (mLetterbox.getInnerFrame().top <= y && mLetterbox.getInnerFrame().bottom >= y) { + // Only react to clicks at the top and bottom of the letterboxed app window. + return; + } + + if (mLetterbox.getInnerFrame().top > y) { + // Moving to the next stop on the top side of the app window: bottom > center > top. + mLetterboxConfiguration.movePositionForVerticalReachabilityToNextTopStop(); + } else if (mLetterbox.getInnerFrame().bottom < y) { + // Moving to the next stop on the bottom side of the app window: top > center > bottom. + mLetterboxConfiguration.movePositionForVerticalReachabilityToNextBottomStop(); } // TODO(197549949): Add animation for transition. @@ -248,25 +282,47 @@ final class LetterboxUiController { } /** - * Whether reachability is enabled for an activity in the curren configuration. + * Whether horizontal reachability is enabled for an activity in the current configuration. * * <p>Conditions that needs to be met: * <ul> * <li>Activity is portrait-only. * <li>Fullscreen window in landscape device orientation. - * <li>Reachability is enabled. + * <li>Horizontal Reachability is enabled. + * </ul> + */ + private boolean isHorizontalReachabilityEnabled(Configuration parentConfiguration) { + return mLetterboxConfiguration.getIsHorizontalReachabilityEnabled() + && parentConfiguration.windowConfiguration.getWindowingMode() + == WINDOWING_MODE_FULLSCREEN + && (parentConfiguration.orientation == ORIENTATION_LANDSCAPE + && mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_PORTRAIT); + } + + private boolean isHorizontalReachabilityEnabled() { + return isHorizontalReachabilityEnabled(mActivityRecord.getParent().getConfiguration()); + } + + /** + * Whether vertical reachability is enabled for an activity in the current configuration. + * + * <p>Conditions that needs to be met: + * <ul> + * <li>Activity is landscape-only. + * <li>Fullscreen window in portrait device orientation. + * <li>Vertical Reachability is enabled. * </ul> */ - private boolean isReachabilityEnabled(Configuration parentConfiguration) { - return mLetterboxConfiguration.getIsReachabilityEnabled() + private boolean isVerticalReachabilityEnabled(Configuration parentConfiguration) { + return mLetterboxConfiguration.getIsVerticalReachabilityEnabled() && parentConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FULLSCREEN - && parentConfiguration.orientation == ORIENTATION_LANDSCAPE - && mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_PORTRAIT; + && (parentConfiguration.orientation == ORIENTATION_PORTRAIT + && mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_LANDSCAPE); } - private boolean isReachabilityEnabled() { - return isReachabilityEnabled(mActivityRecord.getParent().getConfiguration()); + private boolean isVerticalReachabilityEnabled() { + return isVerticalReachabilityEnabled(mActivityRecord.getParent().getConfiguration()); } @VisibleForTesting @@ -474,9 +530,13 @@ final class LetterboxUiController { + getLetterboxWallpaperBlurRadius()); } - pw.println(prefix + " isReachabilityEnabled=" + isReachabilityEnabled()); + pw.println(prefix + " isHorizontalReachabilityEnabled=" + + isHorizontalReachabilityEnabled()); + pw.println(prefix + " isVerticalReachabilityEnabled=" + isVerticalReachabilityEnabled()); pw.println(prefix + " letterboxHorizontalPositionMultiplier=" + getHorizontalPositionMultiplier(mActivityRecord.getParent().getConfiguration())); + pw.println(prefix + " letterboxVerticalPositionMultiplier=" + + getVerticalPositionMultiplier(mActivityRecord.getParent().getConfiguration())); pw.println(prefix + " fixedOrientationLetterboxAspectRatio=" + getFixedOrientationLetterboxAspectRatio( mActivityRecord.getParent().getConfiguration())); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index ff18d681bee2..4e972bf8bea6 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2004,7 +2004,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final Task rootPinnedTask = taskDisplayArea.getRootPinnedTask(); if (rootPinnedTask != null) { transitionController.collect(rootPinnedTask); - rootPinnedTask.dismissPip(); + // The new ActivityRecord should replace the existing PiP, so it's more desirable + // that the old PiP disappears instead of turning to full-screen at the same time, + // as the Task#dismissPip is trying to do. + removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED); } // Set a transition to ensure that we don't immediately try and update the visibility diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index dfbeb55a9bf0..d5acf4fed330 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -27,6 +27,7 @@ import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS; @@ -45,6 +46,7 @@ import static android.view.WindowManager.TransitionType; import static android.view.WindowManager.transitTypeToString; import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; +import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD; import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD; @@ -1025,6 +1027,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe return wc.asWallpaperToken() != null; } + private static boolean isInputMethod(WindowContainer wc) { + return wc.getWindowType() == TYPE_INPUT_METHOD; + } + private static boolean occludesKeyguard(WindowContainer wc) { final ActivityRecord ar = wc.asActivityRecord(); if (ar != null) { @@ -1614,6 +1620,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe if (isWallpaper(wc)) { flags |= FLAG_IS_WALLPAPER; } + if (isInputMethod(wc)) { + flags |= FLAG_IS_INPUT_METHOD; + } if (occludesKeyguard(wc)) { flags |= FLAG_OCCLUDES_KEYGUARD; } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 42d184263722..c0d7d1362ac3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -35,7 +35,6 @@ import android.view.IInputFilter; import android.view.IRemoteAnimationFinishedCallback; import android.view.IWindow; import android.view.InputChannel; -import android.view.InputWindowHandle; import android.view.MagnificationSpec; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; @@ -862,24 +861,12 @@ public abstract class WindowManagerInternal { public abstract SurfaceControl getHandwritingSurfaceForDisplay(int displayId); /** - * Replaces the touchable region of the provided input surface with the crop of the window with - * the provided token. This method will associate the inputSurface with a copy of - * the given inputWindowHandle, where the copy is configured using - * {@link InputWindowHandle#replaceTouchableRegionWithCrop(SurfaceControl)} with the surface - * of the provided windowToken. + * Returns {@code true} if the given point is within the window bounds of the given window. * - * This is a no-op if windowToken is not valid or the window is not found. - * - * This does not change any other properties of the inputSurface. - * - * This method exists to avoid leaking the window's SurfaceControl outside WindowManagerService. - * - * @param inputSurface The surface for which the touchable region should be set. - * @param inputWindowHandle The {@link InputWindowHandle} for the input surface. - * @param windowToken The window whose bounds should be used as the touchable region for the - * inputSurface. + * @param windowToken the window whose bounds should be used for the hit test. + * @param displayX the x coordinate of the test point in the display's coordinate space. + * @param displayY the y coordinate of the test point in the display's coordinate space. */ - public abstract void replaceInputSurfaceTouchableRegionWithWindowCrop( - @NonNull SurfaceControl inputSurface, @NonNull InputWindowHandle inputWindowHandle, - @NonNull IBinder windowToken); + public abstract boolean isPointInsideWindow( + @NonNull IBinder windowToken, int displayId, float displayX, float displayY); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 414212286da7..e169da1ffee2 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3056,10 +3056,10 @@ public class WindowManagerService extends IWindowManager.Stub mRecentsAnimationController = null; controller.cleanupAnimation(reorderMode); // TODO(multi-display): currently only default display support recents animation. - // Cancel any existing app transition animation running in the legacy transition - // framework. final DisplayContent dc = getDefaultDisplayContentLocked(); - dc.mAppTransition.freeze(); + if (dc.mAppTransition.isTransitionSet()) { + dc.mSkipAppTransitionAnimation = true; + } dc.forAllWindowContainers((wc) -> { if (wc.isAnimating(TRANSITION, ANIMATION_TYPE_APP_TRANSITION)) { wc.cancelAnimation(); @@ -8246,23 +8246,15 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void replaceInputSurfaceTouchableRegionWithWindowCrop( - @NonNull SurfaceControl inputSurface, - @NonNull InputWindowHandle inputWindowHandle, - @NonNull IBinder windowToken) { + public boolean isPointInsideWindow(@NonNull IBinder windowToken, int displayId, + float displayX, float displayY) { synchronized (mGlobalLock) { final WindowState w = mWindowMap.get(windowToken); - if (w == null) { - return; + if (w == null || w.getDisplayId() != displayId) { + return false; } - // Make a copy of the InputWindowHandle to avoid leaking the window's - // SurfaceControl. - final InputWindowHandle localHandle = new InputWindowHandle(inputWindowHandle); - localHandle.replaceTouchableRegionWithCrop(w.getSurfaceControl()); - final SurfaceControl.Transaction t = mTransactionFactory.get(); - t.setInputWindowInfo(inputSurface, localHandle); - t.apply(); - t.close(); + + return w.getBounds().contains((int) displayX, (int) displayY); } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index 5a2f28f4a365..1284bb306275 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -23,9 +23,12 @@ import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_ import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR; import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_REACHABILITY_POSITION_CENTER; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_REACHABILITY_POSITION_LEFT; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_REACHABILITY_POSITION_RIGHT; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER; +import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP; import android.content.res.Resources.NotFoundException; import android.graphics.Color; @@ -47,7 +50,8 @@ import com.android.internal.protolog.ProtoLogImpl; import com.android.server.LocalServices; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType; -import com.android.server.wm.LetterboxConfiguration.LetterboxReachabilityPosition; +import com.android.server.wm.LetterboxConfiguration.LetterboxHorizontalReachabilityPosition; +import com.android.server.wm.LetterboxConfiguration.LetterboxVerticalReachabilityPosition; import java.io.IOException; import java.io.PrintWriter; @@ -773,7 +777,27 @@ public class WindowManagerShellCommand extends ShellCommand { return 0; } - private int runSetLetterboxIsReachabilityEnabled(PrintWriter pw) throws RemoteException { + private int runSetLetterboxVerticalPositionMultiplier(PrintWriter pw) throws RemoteException { + final float multiplier; + try { + String arg = getNextArgRequired(); + multiplier = Float.parseFloat(arg); + } catch (NumberFormatException e) { + getErrPrintWriter().println("Error: bad multiplier format " + e); + return -1; + } catch (IllegalArgumentException e) { + getErrPrintWriter().println( + "Error: multiplier should be provided as an argument " + e); + return -1; + } + synchronized (mInternal.mGlobalLock) { + mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(multiplier); + } + return 0; + } + + private int runSetLetterboxIsHorizontalReachabilityEnabled(PrintWriter pw) + throws RemoteException { String arg = getNextArg(); final boolean enabled; switch (arg) { @@ -791,25 +815,49 @@ public class WindowManagerShellCommand extends ShellCommand { } synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setIsReachabilityEnabled(enabled); + mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(enabled); } return 0; } - private int runSetLetterboxDefaultPositionForReachability(PrintWriter pw) + private int runSetLetterboxIsVerticalReachabilityEnabled(PrintWriter pw) throws RemoteException { - @LetterboxReachabilityPosition final int position; + String arg = getNextArg(); + final boolean enabled; + switch (arg) { + case "true": + case "1": + enabled = true; + break; + case "false": + case "0": + enabled = false; + break; + default: + getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg); + return -1; + } + + synchronized (mInternal.mGlobalLock) { + mLetterboxConfiguration.setIsVerticalReachabilityEnabled(enabled); + } + return 0; + } + + private int runSetLetterboxDefaultPositionForHorizontalReachability(PrintWriter pw) + throws RemoteException { + @LetterboxHorizontalReachabilityPosition final int position; try { String arg = getNextArgRequired(); switch (arg) { case "left": - position = LETTERBOX_REACHABILITY_POSITION_LEFT; + position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT; break; case "center": - position = LETTERBOX_REACHABILITY_POSITION_CENTER; + position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER; break; case "right": - position = LETTERBOX_REACHABILITY_POSITION_RIGHT; + position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT; break; default: getErrPrintWriter().println( @@ -822,7 +870,38 @@ public class WindowManagerShellCommand extends ShellCommand { return -1; } synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setDefaultPositionForReachability(position); + mLetterboxConfiguration.setDefaultPositionForHorizontalReachability(position); + } + return 0; + } + + private int runSetLetterboxDefaultPositionForVerticalReachability(PrintWriter pw) + throws RemoteException { + @LetterboxVerticalReachabilityPosition final int position; + try { + String arg = getNextArgRequired(); + switch (arg) { + case "top": + position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP; + break; + case "center": + position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER; + break; + case "bottom": + position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM; + break; + default: + getErrPrintWriter().println( + "Error: 'top', 'center' or 'bottom' are expected as an argument"); + return -1; + } + } catch (IllegalArgumentException e) { + getErrPrintWriter().println( + "Error: 'top', 'center' or 'bottom' are expected as an argument" + e); + return -1; + } + synchronized (mInternal.mGlobalLock) { + mLetterboxConfiguration.setDefaultPositionForVerticalReachability(position); } return 0; } @@ -881,11 +960,20 @@ public class WindowManagerShellCommand extends ShellCommand { case "--horizontalPositionMultiplier": runSetLetterboxHorizontalPositionMultiplier(pw); break; - case "--isReachabilityEnabled": - runSetLetterboxIsReachabilityEnabled(pw); + case "--verticalPositionMultiplier": + runSetLetterboxVerticalPositionMultiplier(pw); break; - case "--defaultPositionForReachability": - runSetLetterboxDefaultPositionForReachability(pw); + case "--isHorizontalReachabilityEnabled": + runSetLetterboxIsHorizontalReachabilityEnabled(pw); + break; + case "--isVerticalReachabilityEnabled": + runSetLetterboxIsVerticalReachabilityEnabled(pw); + break; + case "--defaultPositionForHorizontalReachability": + runSetLetterboxDefaultPositionForHorizontalReachability(pw); + break; + case "--defaultPositionForVerticalReachability": + runSetLetterboxDefaultPositionForVerticalReachability(pw); break; case "--isEducationEnabled": runSetLetterboxIsEducationEnabled(pw); @@ -928,11 +1016,20 @@ public class WindowManagerShellCommand extends ShellCommand { case "horizontalPositionMultiplier": mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier(); break; - case "isReachabilityEnabled": - mLetterboxConfiguration.getIsReachabilityEnabled(); + case "verticalPositionMultiplier": + mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier(); + break; + case "isHorizontalReachabilityEnabled": + mLetterboxConfiguration.getIsHorizontalReachabilityEnabled(); break; - case "defaultPositionForReachability": - mLetterboxConfiguration.getDefaultPositionForReachability(); + case "isVerticalReachabilityEnabled": + mLetterboxConfiguration.getIsVerticalReachabilityEnabled(); + break; + case "defaultPositionForHorizontalReachability": + mLetterboxConfiguration.getDefaultPositionForHorizontalReachability(); + break; + case "defaultPositionForVerticalReachability": + mLetterboxConfiguration.getDefaultPositionForVerticalReachability(); break; case "isEducationEnabled": mLetterboxConfiguration.getIsEducationEnabled(); @@ -1030,8 +1127,10 @@ public class WindowManagerShellCommand extends ShellCommand { mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius(); mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha(); mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier(); - mLetterboxConfiguration.resetIsReachabilityEnabled(); - mLetterboxConfiguration.resetDefaultPositionForReachability(); + mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled(); + mLetterboxConfiguration.resetIsVerticalReachabilityEnabled(); + mLetterboxConfiguration.resetDefaultPositionForHorizontalReachability(); + mLetterboxConfiguration.resetDefaultPositionForVerticalReachability(); mLetterboxConfiguration.resetIsEducationEnabled(); } } @@ -1044,11 +1143,16 @@ public class WindowManagerShellCommand extends ShellCommand { + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier()); pw.println("Aspect ratio: " + mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio()); - pw.println("Is reachability enabled: " - + mLetterboxConfiguration.getIsReachabilityEnabled()); - pw.println("Default position for reachability: " - + LetterboxConfiguration.letterboxReachabilityPositionToString( - mLetterboxConfiguration.getDefaultPositionForReachability())); + pw.println("Is horizontal reachability enabled: " + + mLetterboxConfiguration.getIsHorizontalReachabilityEnabled()); + pw.println("Is vertical reachability enabled: " + + mLetterboxConfiguration.getIsVerticalReachabilityEnabled()); + pw.println("Default position for horizontal reachability: " + + LetterboxConfiguration.letterboxHorizontalReachabilityPositionToString( + mLetterboxConfiguration.getDefaultPositionForHorizontalReachability())); + pw.println("Default position for vertical reachability: " + + LetterboxConfiguration.letterboxVerticalReachabilityPositionToString( + mLetterboxConfiguration.getDefaultPositionForVerticalReachability())); pw.println("Is education enabled: " + mLetterboxConfiguration.getIsEducationEnabled()); @@ -1185,18 +1289,30 @@ public class WindowManagerShellCommand extends ShellCommand { pw.println(" Horizontal position of app window center. If multiplier < 0 or > 1,"); pw.println(" both it and R.dimen.config_letterboxHorizontalPositionMultiplier"); pw.println(" are ignored and central position (0.5) is used."); - pw.println(" --isReachabilityEnabled [true|1|false|0]"); - pw.println(" Whether reachability repositioning is allowed for letterboxed"); - pw.println(" fullscreen apps in landscape device orientation."); - pw.println(" --defaultPositionForReachability [left|center|right]"); - pw.println(" Default horizontal position of app window when reachability is."); + pw.println(" --verticalPositionMultiplier multiplier"); + pw.println(" Vertical position of app window center. If multiplier < 0 or > 1,"); + pw.println(" both it and R.dimen.config_letterboxVerticalPositionMultiplier"); + pw.println(" are ignored and central position (0.5) is used."); + pw.println(" --isHorizontalReachabilityEnabled [true|1|false|0]"); + pw.println(" Whether horizontal reachability repositioning is allowed for "); + pw.println(" letterboxed fullscreen apps in landscape device orientation."); + pw.println(" --isVerticalReachabilityEnabled [true|1|false|0]"); + pw.println(" Whether vertical reachability repositioning is allowed for "); + pw.println(" letterboxed fullscreen apps in portrait device orientation."); + pw.println(" --defaultPositionForHorizontalReachability [left|center|right]"); + pw.println(" Default position of app window when horizontal reachability is."); + pw.println(" enabled."); + pw.println(" --defaultPositionForVerticalReachability [top|center|bottom]"); + pw.println(" Default position of app window when vertical reachability is."); pw.println(" enabled."); pw.println(" --isEducationEnabled [true|1|false|0]"); pw.println(" Whether education is allowed for letterboxed fullscreen apps."); pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType"); pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha"); - pw.println(" |horizontalPositionMultiplier|isReachabilityEnabled"); - pw.println(" isEducationEnabled||defaultPositionMultiplierForReachability]"); + pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier"); + pw.println(" |isHorizontalReachabilityEnabled|isVerticalReachabilityEnabled"); + pw.println(" isEducationEnabled||defaultPositionMultiplierForHorizontalReachability"); + pw.println(" ||defaultPositionMultiplierForVerticalReachability]"); pw.println(" Resets overrides to default values for specified properties separated"); pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'."); pw.println(" If no arguments provided, all values will be reset."); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index d5c07aff2a5c..3e0ed32eb3c9 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -6043,6 +6043,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mRedrawForSyncReported) { return false; } + if (mInRelayout) { + // The last sync seq id will return to the client, so there is no need to request the + // client to redraw. + return false; + } return useBLASTSync(); } diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index 93152f2ea1b7..dbc1a00ce274 100644 --- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -66,13 +66,13 @@ using android::base::unique_fd; // Defines the maximum amount of VMAs we can send per process_madvise syscall. // Currently this is set to UIO_MAXIOV which is the maximum segments allowed by // iovec implementation used by process_madvise syscall -#define MAX_VMAS_PER_COMPACTION UIO_MAXIOV +#define MAX_VMAS_PER_BATCH UIO_MAXIOV // Maximum bytes that we can send per process_madvise syscall once this limit // is reached we split the remaining VMAs into another syscall. The MAX_RW_COUNT // limit is imposed by iovec implementation. However, if you want to use a smaller -// limit, it has to be a page aligned value, otherwise, compaction would fail. -#define MAX_BYTES_PER_COMPACTION MAX_RW_COUNT +// limit, it has to be a page aligned value. +#define MAX_BYTES_PER_BATCH MAX_RW_COUNT // Selected a high enough number to avoid clashing with linux errno codes #define ERROR_COMPACTION_CANCELLED -1000 @@ -83,6 +83,180 @@ namespace android { // before starting next VMA batch static std::atomic<bool> cancelRunningCompaction; +// A VmaBatch represents a set of VMAs that can be processed +// as VMAs are processed by client code it is expected that the +// VMAs get consumed which means they are discarded as they are +// processed so that the first element always is the next element +// to be sent +struct VmaBatch { + struct iovec* vmas; + // total amount of VMAs to reach the end of iovec + size_t totalVmas; + // total amount of bytes that are remaining within iovec + uint64_t totalBytes; +}; + +// Advances the iterator by the specified amount of bytes. +// This is used to remove already processed or no longer +// needed parts of the batch. +// Returns total bytes consumed +uint64_t consumeBytes(VmaBatch& batch, uint64_t bytesToConsume) { + if (CC_UNLIKELY(bytesToConsume) < 0) { + LOG(ERROR) << "Cannot consume negative bytes for VMA batch !"; + return 0; + } + + if (CC_UNLIKELY(bytesToConsume > batch.totalBytes)) { + // Avoid consuming more bytes than available + bytesToConsume = batch.totalBytes; + } + + uint64_t bytesConsumed = 0; + while (bytesConsumed < bytesToConsume) { + if (CC_UNLIKELY(batch.totalVmas > 0)) { + // No more vmas to consume + break; + } + if (CC_UNLIKELY(bytesConsumed + batch.vmas[0].iov_len > bytesToConsume)) { + // This vma can't be fully consumed, do it partially. + uint64_t bytesLeftToConsume = bytesToConsume - bytesConsumed; + bytesConsumed += bytesLeftToConsume; + batch.vmas[0].iov_base = (void*)((uint64_t)batch.vmas[0].iov_base + bytesLeftToConsume); + batch.vmas[0].iov_len -= bytesLeftToConsume; + batch.totalBytes -= bytesLeftToConsume; + return bytesConsumed; + } + // This vma can be fully consumed + bytesConsumed += batch.vmas[0].iov_len; + batch.totalBytes -= batch.vmas[0].iov_len; + --batch.totalVmas; + ++batch.vmas; + } + + return bytesConsumed; +} + +// given a source of vmas this class will act as a factory +// of VmaBatch objects and it will allow generating batches +// until there are no more left in the source vector. +// Note: the class does not actually modify the given +// vmas vector, instead it iterates on it until the end. +class VmaBatchCreator { + const std::vector<Vma>* sourceVmas; + // This is the destination array where batched VMAs will be stored + // it gets encapsulated into a VmaBatch which is the object + // meant to be used by client code. + struct iovec* destVmas; + + // Parameters to keep track of the iterator on the source vmas + int currentIndex_; + uint64_t currentOffset_; + +public: + VmaBatchCreator(const std::vector<Vma>* vmasToBatch, struct iovec* destVmasVec) + : sourceVmas(vmasToBatch), destVmas(destVmasVec), currentIndex_(0), currentOffset_(0) {} + + int currentIndex() { return currentIndex_; } + uint64_t currentOffset() { return currentOffset_; } + + // Generates a batch and moves the iterator on the source vmas + // past the last VMA in the batch. + // Returns true on success, false on failure + bool createNextBatch(VmaBatch& batch) { + if (currentIndex_ >= MAX_VMAS_PER_BATCH && currentIndex_ >= sourceVmas->size()) { + return false; + } + + const std::vector<Vma>& vmas = *sourceVmas; + batch.vmas = destVmas; + uint64_t totalBytesInBatch = 0; + int indexInBatch = 0; + + // Add VMAs to the batch up until we consumed all the VMAs or + // reached any imposed limit of VMAs per batch. + while (indexInBatch < MAX_VMAS_PER_BATCH && currentIndex_ < vmas.size()) { + uint64_t vmaStart = vmas[currentIndex_].start + currentOffset_; + uint64_t vmaSize = vmas[currentIndex_].end - vmaStart; + uint64_t bytesAvailableInBatch = MAX_BYTES_PER_BATCH - totalBytesInBatch; + + batch.vmas[indexInBatch].iov_base = (void*)vmaStart; + + if (vmaSize > bytesAvailableInBatch) { + // VMA would exceed the max available bytes in batch + // clamp with available bytes and finish batch. + vmaSize = bytesAvailableInBatch; + currentOffset_ += bytesAvailableInBatch; + } + + batch.vmas[indexInBatch].iov_len = vmaSize; + totalBytesInBatch += vmaSize; + + ++indexInBatch; + if (totalBytesInBatch >= MAX_BYTES_PER_BATCH) { + // Reached max bytes quota so this marks + // the end of the batch + if (CC_UNLIKELY(vmaSize == (vmas[currentIndex_].end - vmaStart))) { + // we reached max bytes exactly at the end of the vma + // so advance to next one + currentOffset_ = 0; + ++currentIndex_; + } + break; + } + // Fully finished current VMA, move to next one + currentOffset_ = 0; + ++currentIndex_; + } + batch.totalVmas = indexInBatch; + batch.totalBytes = totalBytesInBatch; + if (batch.totalVmas == 0 || batch.totalBytes == 0) { + // This is an empty batch, mark as failed creating. + return false; + } + return true; + } +}; + +// Madvise a set of VMAs given in a batch for a specific process +// The total number of bytes successfully madvised will be set on +// outBytesProcessed. +// Returns 0 on success and standard linux -errno code returned by +// process_madvise on failure +int madviseVmasFromBatch(unique_fd& pidfd, VmaBatch& batch, int madviseType, + uint64_t* outBytesProcessed) { + if (batch.totalVmas == 0 || batch.totalBytes == 0) { + // No VMAs in Batch, skip. + *outBytesProcessed = 0; + return 0; + } + + ATRACE_BEGIN(StringPrintf("Madvise %d: %zu VMAs.", madviseType, batch.totalVmas).c_str()); + int64_t bytesProcessedInSend = + process_madvise(pidfd, batch.vmas, batch.totalVmas, madviseType, 0); + ATRACE_END(); + if (CC_UNLIKELY(bytesProcessedInSend == -1)) { + bytesProcessedInSend = 0; + if (errno != EINVAL) { + // Forward irrecoverable errors and bail out compaction + *outBytesProcessed = 0; + return -errno; + } + } + if (bytesProcessedInSend == 0) { + // When we find a VMA with error, fully consume it as it + // is extremely expensive to iterate on its pages one by one + bytesProcessedInSend = batch.vmas[0].iov_len; + } else if (bytesProcessedInSend < batch.totalBytes) { + // Partially processed the bytes requested + // skip last page which is where it failed. + bytesProcessedInSend += PAGE_SIZE; + } + bytesProcessedInSend = consumeBytes(batch, bytesProcessedInSend); + + *outBytesProcessed = bytesProcessedInSend; + return 0; +} + // Legacy method for compacting processes, any new code should // use compactProcess instead. static inline void compactProcessProcfs(int pid, const std::string& compactionType) { @@ -96,8 +270,6 @@ static inline void compactProcessProcfs(int pid, const std::string& compactionTy // If any VMA fails compaction due to -EINVAL it will be skipped and continue. // However, if it fails for any other reason, it will bail out and forward the error static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseType) { - static struct iovec vmasToKernel[MAX_VMAS_PER_COMPACTION]; - if (vmas.empty()) { return 0; } @@ -108,13 +280,16 @@ static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseT return -errno; } - int64_t totalBytesProcessed = 0; + struct iovec destVmas[MAX_VMAS_PER_BATCH]; + + VmaBatch batch; + VmaBatchCreator batcher(&vmas, destVmas); - int64_t vmaOffset = 0; - for (int iVma = 0; iVma < vmas.size();) { - uint64_t bytesSentToCompact = 0; - int iVec = 0; - while (iVec < MAX_VMAS_PER_COMPACTION && iVma < vmas.size()) { + int64_t totalBytesProcessed = 0; + while (batcher.createNextBatch(batch)) { + uint64_t bytesProcessedInSend; + ScopedTrace batchTrace(ATRACE_TAG, "VMA Batch"); + do { if (CC_UNLIKELY(cancelRunningCompaction.load())) { // There could be a significant delay between when a compaction // is requested and when it is handled during this time our @@ -124,50 +299,18 @@ static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseT StringPrintf("Cancelled compaction for %d", pid).c_str()); return ERROR_COMPACTION_CANCELLED; } - - uint64_t vmaStart = vmas[iVma].start + vmaOffset; - uint64_t vmaSize = vmas[iVma].end - vmaStart; - if (vmaSize == 0) { - goto next_vma; - } - vmasToKernel[iVec].iov_base = (void*)vmaStart; - if (vmaSize > MAX_BYTES_PER_COMPACTION - bytesSentToCompact) { - // Exceeded the max bytes that could be sent, so clamp - // the end to avoid exceeding limit and issue compaction - vmaSize = MAX_BYTES_PER_COMPACTION - bytesSentToCompact; + int error = madviseVmasFromBatch(pidfd, batch, madviseType, &bytesProcessedInSend); + if (error < 0) { + // Returns standard linux errno code + return error; } - - vmasToKernel[iVec].iov_len = vmaSize; - bytesSentToCompact += vmaSize; - ++iVec; - if (bytesSentToCompact >= MAX_BYTES_PER_COMPACTION) { - // Ran out of bytes within iovec, dispatch compaction. - vmaOffset += vmaSize; + if (CC_UNLIKELY(bytesProcessedInSend == 0)) { + // This means there was a problem consuming bytes, + // bail out since no forward progress can be made with this batch break; } - - next_vma: - // Finished current VMA, and have more bytes remaining - vmaOffset = 0; - ++iVma; - } - - ATRACE_BEGIN(StringPrintf("Compact %d VMAs", iVec).c_str()); - auto bytesProcessed = process_madvise(pidfd, vmasToKernel, iVec, madviseType, 0); - ATRACE_END(); - - if (CC_UNLIKELY(bytesProcessed == -1)) { - if (errno == EINVAL) { - // This error is somewhat common due to an unevictable VMA if this is - // the case silently skip the bad VMA and continue compacting the rest. - continue; - } else { - // Forward irrecoverable errors and bail out compaction - return -errno; - } - } - - totalBytesProcessed += bytesProcessed; + totalBytesProcessed += bytesProcessedInSend; + } while (batch.totalBytes > 0 && batch.totalVmas > 0); } return totalBytesProcessed; @@ -203,6 +346,7 @@ static int getAnyPageAdvice(const Vma& vma) { static int64_t compactProcess(int pid, VmaToAdviseFunc vmaToAdviseFunc) { cancelRunningCompaction.store(false); + ATRACE_BEGIN("CollectVmas"); ProcMemInfo meminfo(pid); std::vector<Vma> pageoutVmas, coldVmas; auto vmaCollectorCb = [&coldVmas,&pageoutVmas,&vmaToAdviseFunc](const Vma& vma) { @@ -217,6 +361,7 @@ static int64_t compactProcess(int pid, VmaToAdviseFunc vmaToAdviseFunc) { } }; meminfo.ForEachVmaFromMaps(vmaCollectorCb); + ATRACE_END(); int64_t pageoutBytes = compactMemory(pageoutVmas, pid, MADV_PAGEOUT); if (pageoutBytes < 0) { diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 32adac7f282b..287fb8219650 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -106,7 +106,6 @@ static struct { jmethodID interceptMotionBeforeQueueingNonInteractive; jmethodID interceptKeyBeforeDispatching; jmethodID dispatchUnhandledKey; - jmethodID checkInjectEventsPermission; jmethodID onPointerDisplayIdChanged; jmethodID onPointerDownOutsideFocus; jmethodID getVirtualKeyQuietTimeMillis; @@ -333,7 +332,6 @@ public: bool dispatchUnhandledKey(const sp<IBinder>& token, const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) override; void pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) override; - bool checkInjectEventsPermissionNonReentrant(int32_t injectorPid, int32_t injectorUid) override; void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) override; void setPointerCapture(const PointerCaptureRequest& request) override; void notifyDropWindow(const sp<IBinder>& token, float x, float y) override; @@ -1380,19 +1378,6 @@ void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType, android_server_PowerManagerService_userActivity(eventTime, eventType, displayId); } -bool NativeInputManager::checkInjectEventsPermissionNonReentrant(int32_t injectorPid, - int32_t injectorUid) { - ATRACE_CALL(); - JNIEnv* env = jniEnv(); - jboolean result = - env->CallBooleanMethod(mServiceObj, gServiceClassInfo.checkInjectEventsPermission, - injectorPid, injectorUid); - if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) { - result = false; - } - return result; -} - void NativeInputManager::onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) { ATRACE_CALL(); JNIEnv* env = jniEnv(); @@ -1709,10 +1694,11 @@ static void nativeSetBlockUntrustedTouchesMode(JNIEnv* env, jobject nativeImplOb } static jint nativeInjectInputEvent(JNIEnv* env, jobject nativeImplObj, jobject inputEventObj, - jint injectorPid, jint injectorUid, jint syncMode, + jboolean injectIntoUid, jint uid, jint syncMode, jint timeoutMillis, jint policyFlags) { NativeInputManager* im = getNativeInputManager(env, nativeImplObj); + const std::optional<int32_t> targetUid = injectIntoUid ? std::make_optional(uid) : std::nullopt; // static_cast is safe because the value was already checked at the Java layer InputEventInjectionSync mode = static_cast<InputEventInjectionSync>(syncMode); @@ -1725,8 +1711,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jobject nativeImplObj, jobject i } const InputEventInjectionResult result = - im->getInputManager()->getDispatcher().injectInputEvent(&keyEvent, injectorPid, - injectorUid, mode, + im->getInputManager()->getDispatcher().injectInputEvent(&keyEvent, targetUid, mode, std::chrono::milliseconds( timeoutMillis), uint32_t(policyFlags)); @@ -1739,8 +1724,8 @@ static jint nativeInjectInputEvent(JNIEnv* env, jobject nativeImplObj, jobject i } const InputEventInjectionResult result = - im->getInputManager()->getDispatcher().injectInputEvent(motionEvent, injectorPid, - injectorUid, mode, + im->getInputManager()->getDispatcher().injectInputEvent(motionEvent, targetUid, + mode, std::chrono::milliseconds( timeoutMillis), uint32_t(policyFlags)); @@ -2345,7 +2330,7 @@ static const JNINativeMethod gInputManagerMethods[] = { {"setMaximumObscuringOpacityForTouch", "(F)V", (void*)nativeSetMaximumObscuringOpacityForTouch}, {"setBlockUntrustedTouchesMode", "(I)V", (void*)nativeSetBlockUntrustedTouchesMode}, - {"injectInputEvent", "(Landroid/view/InputEvent;IIIII)I", (void*)nativeInjectInputEvent}, + {"injectInputEvent", "(Landroid/view/InputEvent;ZIIII)I", (void*)nativeInjectInputEvent}, {"verifyInputEvent", "(Landroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;", (void*)nativeVerifyInputEvent}, {"toggleCapsLock", "(I)V", (void*)nativeToggleCapsLock}, @@ -2492,9 +2477,6 @@ int register_android_server_InputManager(JNIEnv* env) { "dispatchUnhandledKey", "(Landroid/os/IBinder;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;"); - GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz, - "checkInjectEventsPermission", "(II)Z"); - GET_METHOD_ID(gServiceClassInfo.onPointerDisplayIdChanged, clazz, "onPointerDisplayIdChanged", "(IFF)V"); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java index 3912991a41ed..0c69067ab131 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java @@ -157,13 +157,14 @@ class ActiveAdmin { private static final String TAG_SSID_ALLOWLIST = "ssid-allowlist"; private static final String TAG_SSID_DENYLIST = "ssid-denylist"; private static final String TAG_SSID = "ssid"; - private static final String ATTR_VALUE = "value"; - private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification"; - private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications"; private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIGS = "preferential_network_service_configs"; private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG = "preferential_network_service_config"; + private static final String TAG_PROTECTED_PACKAGES = "protected_packages"; + private static final String ATTR_VALUE = "value"; + private static final String ATTR_LAST_NETWORK_LOGGING_NOTIFICATION = "last-notification"; + private static final String ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS = "num-notifications"; DeviceAdminInfo info; @@ -253,6 +254,9 @@ class ActiveAdmin { // List of package names to keep cached. List<String> keepUninstalledPackages; + // List of packages for which the user cannot invoke "clear data" or "force stop". + List<String> protectedPackages; + // Wi-Fi SSID restriction policy. WifiSsidPolicy mWifiSsidPolicy; @@ -505,6 +509,7 @@ class ActiveAdmin { permittedNotificationListeners); writePackageListToXml(out, TAG_KEEP_UNINSTALLED_PACKAGES, keepUninstalledPackages); writePackageListToXml(out, TAG_METERED_DATA_DISABLED_PACKAGES, meteredDisabledPackages); + writePackageListToXml(out, TAG_PROTECTED_PACKAGES, protectedPackages); if (hasUserRestrictions()) { UserRestrictionsUtils.writeRestrictions( out, userRestrictions, TAG_USER_RESTRICTIONS); @@ -771,6 +776,8 @@ class ActiveAdmin { keepUninstalledPackages = readPackageList(parser, tag); } else if (TAG_METERED_DATA_DISABLED_PACKAGES.equals(tag)) { meteredDisabledPackages = readPackageList(parser, tag); + } else if (TAG_PROTECTED_PACKAGES.equals(tag)) { + protectedPackages = readPackageList(parser, tag); } else if (TAG_USER_RESTRICTIONS.equals(tag)) { userRestrictions = UserRestrictionsUtils.readRestrictions(parser); } else if (TAG_DEFAULT_ENABLED_USER_RESTRICTIONS.equals(tag)) { @@ -1210,6 +1217,16 @@ class ActiveAdmin { pw.println(keepUninstalledPackages); } + if (meteredDisabledPackages != null) { + pw.print("meteredDisabledPackages="); + pw.println(meteredDisabledPackages); + } + + if (protectedPackages != null) { + pw.print("protectedPackages="); + pw.println(protectedPackages); + } + pw.print("organizationColor="); pw.println(organizationColor); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java index 48a436f15803..fd97db23f01a 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java @@ -17,6 +17,7 @@ package com.android.server.devicepolicy; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManager; @@ -129,8 +130,10 @@ class DevicePolicyData { // This is the list of component allowed to start lock task mode. List<String> mLockTaskPackages = new ArrayList<>(); - // List of packages protected by device owner - List<String> mUserControlDisabledPackages = new ArrayList<>(); + /** @deprecated moved to {@link ActiveAdmin#protectedPackages}. */ + @Deprecated + @Nullable + List<String> mUserControlDisabledPackages; // Bitfield of feature flags to be enabled during LockTask mode. // We default on the power button menu, in order to be consistent with pre-P behaviour. @@ -364,13 +367,6 @@ class DevicePolicyData { out.endTag(null, TAG_OWNER_INSTALLED_CA_CERT); } - for (int i = 0, size = policyData.mUserControlDisabledPackages.size(); i < size; i++) { - String packageName = policyData.mUserControlDisabledPackages.get(i); - out.startTag(null, TAG_PROTECTED_PACKAGES); - out.attribute(null, ATTR_NAME, packageName); - out.endTag(null, TAG_PROTECTED_PACKAGES); - } - if (policyData.mAppsSuspended) { out.startTag(null, TAG_APPS_SUSPENDED); out.attributeBoolean(null, ATTR_VALUE, policyData.mAppsSuspended); @@ -473,7 +469,7 @@ class DevicePolicyData { policy.mAdminMap.clear(); policy.mAffiliationIds.clear(); policy.mOwnerInstalledCaCerts.clear(); - policy.mUserControlDisabledPackages.clear(); + policy.mUserControlDisabledPackages = null; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { @@ -561,15 +557,19 @@ class DevicePolicyData { policy.mCurrentInputMethodSet = true; } else if (TAG_OWNER_INSTALLED_CA_CERT.equals(tag)) { policy.mOwnerInstalledCaCerts.add(parser.getAttributeValue(null, ATTR_ALIAS)); - } else if (TAG_PROTECTED_PACKAGES.equals(tag)) { - policy.mUserControlDisabledPackages.add( - parser.getAttributeValue(null, ATTR_NAME)); } else if (TAG_APPS_SUSPENDED.equals(tag)) { policy.mAppsSuspended = parser.getAttributeBoolean(null, ATTR_VALUE, false); } else if (TAG_BYPASS_ROLE_QUALIFICATIONS.equals(tag)) { policy.mBypassDevicePolicyManagementRoleQualifications = true; policy.mCurrentRoleHolder = parser.getAttributeValue(null, ATTR_VALUE); + // Deprecated tags below + } else if (TAG_PROTECTED_PACKAGES.equals(tag)) { + if (policy.mUserControlDisabledPackages == null) { + policy.mUserControlDisabledPackages = new ArrayList<>(); + } + policy.mUserControlDisabledPackages.add( + parser.getAttributeValue(null, ATTR_NAME)); } else { Slogf.w(TAG, "Unknown tag: %s", tag); XmlUtils.skipCurrentTag(parser); @@ -674,8 +674,6 @@ class DevicePolicyData { pw.increaseIndent(); pw.print("mPasswordOwner="); pw.println(mPasswordOwner); pw.print("mPasswordTokenHandle="); pw.println(Long.toHexString(mPasswordTokenHandle)); - pw.print("mUserControlDisabledPackages="); - pw.println(mUserControlDisabledPackages); pw.print("mAppsSuspended="); pw.println(mAppsSuspended); pw.print("mUserSetupComplete="); pw.println(mUserSetupComplete); pw.print("mAffiliationIds="); pw.println(mAffiliationIds); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 7f466f38e96a..1ce24173d3a2 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -536,7 +536,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // to decide whether an existing policy in the {@link #DEVICE_POLICIES_XML} needs to // be upgraded. See {@link PolicyVersionUpgrader} on instructions how to add an upgrade // step. - static final int DPMS_VERSION = 2; + static final int DPMS_VERSION = 3; static { SECURE_SETTINGS_ALLOWLIST = new ArraySet<>(); @@ -1908,39 +1908,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (userHandle == UserHandle.USER_SYSTEM) { mStateCache.setDeviceProvisioned(policy.mUserSetupComplete); } - - migrateDeviceOwnerProtectedPackagesToOwners(userHandle, policy); } return policy; } } /** - * Only used by {@link #getUserData(int)} to migrate <b>existing</b> device owner protected - * packages that were stored in {@link DevicePolicyData#mUserControlDisabledPackages} to - * {@link Owners} because the device owner protected packages are now stored on a per device - * owner basis instead of on a per user basis. - * - * Any calls to {@link #setUserControlDisabledPackages(ComponentName, List)} would now store - * the device owner protected packages in {@link Owners} instead of {@link DevicePolicyData}. - * @param userHandle The device owner user - * @param policy The policy data of the device owner user - */ - private void migrateDeviceOwnerProtectedPackagesToOwners( - int userHandle, DevicePolicyData policy) { - ComponentName deviceOwnerComponent = getOwnerComponent(userHandle); - if (isDeviceOwner(deviceOwnerComponent, userHandle) - && !policy.mUserControlDisabledPackages.isEmpty()) { - mOwners.setDeviceOwnerProtectedPackages( - deviceOwnerComponent.getPackageName(), - policy.mUserControlDisabledPackages); - - policy.mUserControlDisabledPackages = new ArrayList<>(); - saveSettingsLocked(userHandle); - } - } - - /** * Creates and loads the policy data from xml for data that is shared between * various profiles of a user. In contrast to {@link #getUserData(int)} * it allows access to data of users other than the calling user. @@ -3143,6 +3116,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { deleteTransferOwnershipBundleLocked(metadata.userId); } updateSystemUpdateFreezePeriodsRecord(/* saveIfChanged */ true); + pushUserControlDisabledPackagesLocked(metadata.userId); } private void maybeLogStart() { @@ -3182,6 +3156,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { void handleStartUser(int userId) { synchronized (getLockObject()) { pushScreenCapturePolicy(userId); + pushUserControlDisabledPackagesLocked(userId); } pushUserRestrictions(userId); // When system user is started (device boot), load cache for all users. @@ -3204,6 +3179,24 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { startOwnerService(userId, "start-user"); } + void pushUserControlDisabledPackagesLocked(int userId) { + final int targetUserId; + final ActiveAdmin owner; + if (getDeviceOwnerUserIdUncheckedLocked() == userId) { + owner = getDeviceOwnerAdminLocked(); + targetUserId = UserHandle.USER_ALL; + } else { + owner = getProfileOwnerAdminLocked(userId); + targetUserId = userId; + } + + List<String> protectedPackages = (owner == null || owner.protectedPackages == null) + ? Collections.emptyList() : owner.protectedPackages; + mInjector.binderWithCleanCallingIdentity(() -> + mInjector.getPackageManagerInternal().setOwnerProtectedPackages( + targetUserId, protectedPackages)); + } + @Override void handleUnlockUser(int userId) { startOwnerService(userId, "unlock-user"); @@ -8802,6 +8795,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { setNetworkLoggingActiveInternal(false); deleteTransferOwnershipBundleLocked(userId); toggleBackupServiceActive(UserHandle.USER_SYSTEM, true); + pushUserControlDisabledPackagesLocked(userId); } private void clearApplicationRestrictions(int userId) { @@ -8986,7 +8980,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { policy.mLockTaskPackages.clear(); updateLockTaskPackagesLocked(policy.mLockTaskPackages, userId); policy.mLockTaskFeatures = DevicePolicyManager.LOCK_TASK_FEATURE_NONE; - policy.mUserControlDisabledPackages.clear(); saveSettingsLocked(userId); try { @@ -16979,19 +16972,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); Objects.requireNonNull(packages, "packages is null"); final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization( - isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller)); + Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller) + || isFinancedDeviceOwner(caller)); checkCanExecuteOrThrowUnsafe( DevicePolicyManager.OPERATION_SET_USER_CONTROL_DISABLED_PACKAGES); synchronized (getLockObject()) { - mOwners.setDeviceOwnerProtectedPackages(who.getPackageName(), packages); - DevicePolicyEventLogger - .createEvent(DevicePolicyEnums.SET_USER_CONTROL_DISABLED_PACKAGES) - .setAdmin(who) - .setStrings(packages.toArray(new String[packages.size()])) - .write(); + ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId()); + if (!Objects.equals(owner.protectedPackages, packages)) { + owner.protectedPackages = packages.isEmpty() ? null : packages; + saveSettingsLocked(caller.getUserId()); + pushUserControlDisabledPackagesLocked(caller.getUserId()); + } } + + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.SET_USER_CONTROL_DISABLED_PACKAGES) + .setAdmin(who) + .setStrings(packages.toArray(new String[packages.size()])) + .write(); } @Override @@ -16999,11 +16998,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); final CallerIdentity caller = getCallerIdentity(who); - Preconditions.checkCallAuthorization( - isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller)); + Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller) + || isFinancedDeviceOwner(caller)); synchronized (getLockObject()) { - return mOwners.getDeviceOwnerProtectedPackages(who.getPackageName()); + ActiveAdmin deviceOwner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId()); + return deviceOwner.protectedPackages != null + ? deviceOwner.protectedPackages : Collections.emptyList(); } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java index d1c6b3411b20..08bd3e4c7c47 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java @@ -31,7 +31,6 @@ import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; -import android.util.ArrayMap; import android.util.ArraySet; import android.util.IndentingPrintWriter; import android.util.Pair; @@ -49,7 +48,6 @@ import com.android.server.wm.ActivityTaskManagerInternal; import java.io.File; import java.time.LocalDate; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; @@ -108,12 +106,6 @@ class Owners { notifyChangeLocked(); pushToActivityTaskManagerLocked(); - - for (ArrayMap.Entry<String, List<String>> entry : - mData.mDeviceOwnerProtectedPackages.entrySet()) { - mPackageManagerInternal.setDeviceOwnerProtectedPackages( - entry.getKey(), entry.getValue()); - } } } @@ -247,12 +239,6 @@ class Owners { void clearDeviceOwner() { synchronized (mData) { mData.mDeviceOwnerTypes.remove(mData.mDeviceOwner.packageName); - List<String> protectedPackages = - mData.mDeviceOwnerProtectedPackages.remove(mData.mDeviceOwner.packageName); - if (protectedPackages != null) { - mPackageManagerInternal.setDeviceOwnerProtectedPackages( - mData.mDeviceOwner.packageName, new ArrayList<>()); - } mData.mDeviceOwner = null; mData.mDeviceOwnerUserId = UserHandle.USER_NULL; @@ -296,12 +282,6 @@ class Owners { synchronized (mData) { Integer previousDeviceOwnerType = mData.mDeviceOwnerTypes.remove( mData.mDeviceOwner.packageName); - List<String> previousProtectedPackages = - mData.mDeviceOwnerProtectedPackages.remove(mData.mDeviceOwner.packageName); - if (previousProtectedPackages != null) { - mPackageManagerInternal.setDeviceOwnerProtectedPackages( - mData.mDeviceOwner.packageName, new ArrayList<>()); - } // We don't set a name because it's not used anyway. // See DevicePolicyManagerService#getDeviceOwnerName mData.mDeviceOwner = new OwnerInfo(null, target, @@ -313,10 +293,6 @@ class Owners { mData.mDeviceOwnerTypes.put( mData.mDeviceOwner.packageName, previousDeviceOwnerType); } - if (previousProtectedPackages != null) { - mData.mDeviceOwnerProtectedPackages.put( - mData.mDeviceOwner.packageName, previousProtectedPackages); - } notifyChangeLocked(); pushToActivityTaskManagerLocked(); } @@ -504,34 +480,6 @@ class Owners { } } - void setDeviceOwnerProtectedPackages(String packageName, List<String> protectedPackages) { - synchronized (mData) { - if (!hasDeviceOwner()) { - Slog.e(TAG, - "Attempting to set device owner protected packages when there is no " - + "device owner"); - return; - } else if (!mData.mDeviceOwner.packageName.equals(packageName)) { - Slog.e(TAG, "Attempting to set device owner protected packages when the provided " - + "package name " + packageName - + " does not match the device owner package name"); - return; - } - - mData.mDeviceOwnerProtectedPackages.put(packageName, protectedPackages); - mPackageManagerInternal.setDeviceOwnerProtectedPackages(packageName, protectedPackages); - writeDeviceOwner(); - } - } - - List<String> getDeviceOwnerProtectedPackages(String packageName) { - synchronized (mData) { - return mData.mDeviceOwnerProtectedPackages.containsKey(packageName) - ? mData.mDeviceOwnerProtectedPackages.get(packageName) - : Collections.emptyList(); - } - } - void writeDeviceOwner() { synchronized (mData) { pushToDevicePolicyManager(); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java index 4fe4f0d83f1a..694842034d1f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java @@ -91,8 +91,10 @@ class OwnersData { // Device owner type for a managed device. final ArrayMap<String, Integer> mDeviceOwnerTypes = new ArrayMap<>(); - final ArrayMap<String, List<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>(); - + /** @deprecated moved to {@link ActiveAdmin#protectedPackages}. */ + @Deprecated + @Nullable + ArrayMap<String, List<String>> mDeviceOwnerProtectedPackages; // Internal state for the profile owner packages. final ArrayMap<Integer, OwnerInfo> mProfileOwners = new ArrayMap<>(); @@ -366,21 +368,6 @@ class OwnersData { } } - if (!mDeviceOwnerProtectedPackages.isEmpty()) { - for (ArrayMap.Entry<String, List<String>> entry : - mDeviceOwnerProtectedPackages.entrySet()) { - List<String> protectedPackages = entry.getValue(); - - out.startTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES); - out.attribute(null, ATTR_PACKAGE, entry.getKey()); - out.attributeInt(null, ATTR_SIZE, protectedPackages.size()); - for (int i = 0, size = protectedPackages.size(); i < size; i++) { - out.attribute(null, ATTR_NAME + i, protectedPackages.get(i)); - } - out.endTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES); - } - } - if (mSystemUpdatePolicy != null) { out.startTag(null, TAG_SYSTEM_UPDATE_POLICY); mSystemUpdatePolicy.saveToXml(out); @@ -444,6 +431,7 @@ class OwnersData { null, ATTR_DEVICE_OWNER_TYPE_VALUE, DEVICE_OWNER_TYPE_DEFAULT); mDeviceOwnerTypes.put(packageName, deviceOwnerType); break; + // Deprecated fields below. case TAG_DEVICE_OWNER_PROTECTED_PACKAGES: packageName = parser.getAttributeValue(null, ATTR_PACKAGE); int protectedPackagesSize = parser.getAttributeInt(null, ATTR_SIZE, 0); @@ -451,6 +439,9 @@ class OwnersData { for (int i = 0; i < protectedPackagesSize; i++) { protectedPackages.add(parser.getAttributeValue(null, ATTR_NAME + i)); } + if (mDeviceOwnerProtectedPackages == null) { + mDeviceOwnerProtectedPackages = new ArrayMap<>(); + } mDeviceOwnerProtectedPackages.put(packageName, protectedPackages); break; default: diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java index 7556d690f6fd..253851cdbf68 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java @@ -16,6 +16,7 @@ package com.android.server.devicepolicy; +import android.annotation.Nullable; import android.content.ComponentName; import android.os.UserHandle; import android.util.Slog; @@ -28,6 +29,8 @@ import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; /** * Class for dealing with Device Policy Manager Service version upgrades. @@ -91,30 +94,82 @@ public class PolicyVersionUpgrader { if (currentVersion == 1) { Slog.i(LOG_TAG, String.format("Upgrading from version %d", currentVersion)); - // This upgrade step is for Device Owner scenario only: For devices upgrading to S, - // if there is a device owner, it retains the ability to control sensors-related - // permission grants. - for (int userId : allUsers) { - DevicePolicyData userData = allUsersData.get(userId); - if (userData == null) { - continue; - } - for (ActiveAdmin admin : userData.mAdminList) { - if (ownersData.mDeviceOwnerUserId == userId - && ownersData.mDeviceOwner != null - && ownersData.mDeviceOwner.admin.equals(admin.info.getComponent())) { - Slog.i(LOG_TAG, String.format( - "Marking Device Owner in user %d for permission grant ", userId)); - admin.mAdminCanGrantSensorsPermissions = true; - } - } - } + upgradeSensorPermissionsAccess(allUsers, ownersData, allUsersData); currentVersion = 2; } + if (currentVersion == 2) { + Slog.i(LOG_TAG, String.format("Upgrading from version %d", currentVersion)); + upgradeProtectedPackages(ownersData, allUsersData); + currentVersion = 3; + } + writePoliciesAndVersion(allUsers, allUsersData, ownersData, currentVersion); } + /** + * This upgrade step is for Device Owner scenario only: For devices upgrading to S, if there is + * a device owner, it retains the ability to control sensors-related permission grants. + */ + private void upgradeSensorPermissionsAccess( + int[] allUsers, OwnersData ownersData, SparseArray<DevicePolicyData> allUsersData) { + for (int userId : allUsers) { + DevicePolicyData userData = allUsersData.get(userId); + if (userData == null) { + continue; + } + for (ActiveAdmin admin : userData.mAdminList) { + if (ownersData.mDeviceOwnerUserId == userId + && ownersData.mDeviceOwner != null + && ownersData.mDeviceOwner.admin.equals(admin.info.getComponent())) { + Slog.i(LOG_TAG, String.format( + "Marking Device Owner in user %d for permission grant ", userId)); + admin.mAdminCanGrantSensorsPermissions = true; + } + } + } + } + + /** + * This upgrade step moves device owner protected packages to ActiveAdmin. + * Initially these packages were stored in DevicePolicyData, then moved to Owners without + * employing PolicyVersionUpgrader. Here we check both places. + */ + private void upgradeProtectedPackages( + OwnersData ownersData, SparseArray<DevicePolicyData> allUsersData) { + if (ownersData.mDeviceOwner == null) { + return; + } + List<String> protectedPackages = null; + DevicePolicyData doUserData = allUsersData.get(ownersData.mDeviceOwnerUserId); + if (doUserData == null) { + Slog.e(LOG_TAG, "No policy data for do user"); + return; + } + if (ownersData.mDeviceOwnerProtectedPackages != null) { + protectedPackages = ownersData.mDeviceOwnerProtectedPackages + .get(ownersData.mDeviceOwner.packageName); + if (protectedPackages != null) { + Slog.i(LOG_TAG, "Found protected packages in Owners"); + } + ownersData.mDeviceOwnerProtectedPackages = null; + } else if (doUserData.mUserControlDisabledPackages != null) { + Slog.i(LOG_TAG, "Found protected packages in DevicePolicyData"); + protectedPackages = doUserData.mUserControlDisabledPackages; + doUserData.mUserControlDisabledPackages = null; + } + + ActiveAdmin doAdmin = doUserData.mAdminMap.get(ownersData.mDeviceOwner.admin); + if (doAdmin == null) { + Slog.e(LOG_TAG, "DO admin not found in DO user"); + return; + } + + if (protectedPackages != null) { + doAdmin.protectedPackages = new ArrayList<>(protectedPackages); + } + } + private OwnersData loadOwners(int[] allUsers) { OwnersData ownersData = new OwnersData(mPathProvider); ownersData.load(allUsers); @@ -146,17 +201,23 @@ public class PolicyVersionUpgrader { OwnersData ownersData) { final SparseArray<DevicePolicyData> allUsersData = new SparseArray<>(); for (int user: allUsers) { - ComponentName owner = null; - if (ownersData.mDeviceOwnerUserId == user && ownersData.mDeviceOwner != null) { - owner = ownersData.mDeviceOwner.admin; - } else if (ownersData.mProfileOwners.containsKey(user)) { - owner = ownersData.mProfileOwners.get(user).admin; - } + ComponentName owner = getOwnerForUser(ownersData, user); allUsersData.append(user, loadDataForUser(user, loadVersion, owner)); } return allUsersData; } + @Nullable + private ComponentName getOwnerForUser(OwnersData ownersData, int user) { + ComponentName owner = null; + if (ownersData.mDeviceOwnerUserId == user && ownersData.mDeviceOwner != null) { + owner = ownersData.mDeviceOwner.admin; + } else if (ownersData.mProfileOwners.containsKey(user)) { + owner = ownersData.mProfileOwners.get(user).admin; + } + return owner; + } + private DevicePolicyData loadDataForUser( int userId, int loadVersion, ComponentName ownerComponent) { DevicePolicyData policy = new DevicePolicyData(userId); diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index dc2b6f8d3b64..80f0186a2528 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -338,8 +338,6 @@ public final class SystemServer implements Dumpable { "com.android.server.contentcapture.ContentCaptureManagerService"; private static final String TRANSLATION_MANAGER_SERVICE_CLASS = "com.android.server.translation.TranslationManagerService"; - private static final String SELECTION_TOOLBAR_MANAGER_SERVICE_CLASS = - "com.android.server.selectiontoolbar.SelectionToolbarManagerService"; private static final String MUSIC_RECOGNITION_MANAGER_SERVICE_CLASS = "com.android.server.musicrecognition.MusicRecognitionManagerService"; private static final String SYSTEM_CAPTIONS_MANAGER_SERVICE_CLASS = @@ -2635,11 +2633,6 @@ public final class SystemServer implements Dumpable { Slog.d(TAG, "TranslationService not defined by OEM"); } - // Selection toolbar service - t.traceBegin("StartSelectionToolbarManagerService"); - mSystemServiceManager.startService(SELECTION_TOOLBAR_MANAGER_SERVICE_CLASS); - t.traceEnd(); - // NOTE: ClipboardService depends on ContentCapture and Autofill t.traceBegin("StartClipboardService"); mSystemServiceManager.startService(ClipboardService.class); diff --git a/services/selectiontoolbar/Android.bp b/services/selectiontoolbar/Android.bp deleted file mode 100644 index cc6405f97bc3..000000000000 --- a/services/selectiontoolbar/Android.bp +++ /dev/null @@ -1,22 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -filegroup { - name: "services.selectiontoolbar-sources", - srcs: ["java/**/*.java"], - path: "java", - visibility: ["//frameworks/base/services"], -} - -java_library_static { - name: "services.selectiontoolbar", - defaults: ["platform_service_defaults"], - srcs: [":services.selectiontoolbar-sources"], - libs: ["services.core"], -} 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 8461b39f8899..17b42260948d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -3220,34 +3220,19 @@ public class AlarmManagerServiceTest { when(mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING)).thenReturn( Arrays.asList(package4)); - mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true); - mService.mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = false; - mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] { - package1, - package3, - }); - - // Deny listed packages will be false. - assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1)); - assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2)); - assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3)); - assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4)); - mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false); - mService.mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = true; mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] { package1, package3, }); - // Same as above, deny listed packages will be false. + // Deny listed packages will be false. assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1)); assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2)); assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3)); assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4)); mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true); - mService.mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = true; mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] { package1, package3, diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java index ac542935fa0a..009dae51e94b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java @@ -582,6 +582,7 @@ public final class BackgroundRestrictionTest { DeviceConfigSession<Boolean> bgCurrentDrainMonitor = null; DeviceConfigSession<Long> bgCurrentDrainWindow = null; + DeviceConfigSession<Long> bgCurrentDrainInteractionGracePeriod = null; DeviceConfigSession<Float> bgCurrentDrainRestrictedBucketThreshold = null; DeviceConfigSession<Float> bgCurrentDrainBgRestrictedThreshold = null; DeviceConfigSession<Boolean> bgPromptFgsWithNotiToBgRestricted = null; @@ -617,6 +618,14 @@ public final class BackgroundRestrictionTest { R.integer.config_bg_current_drain_window)); bgCurrentDrainWindow.set(windowMs); + bgCurrentDrainInteractionGracePeriod = new DeviceConfigSession<>( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD, + DeviceConfig::getLong, + (long) mContext.getResources().getInteger( + R.integer.config_bg_current_drain_window)); + bgCurrentDrainInteractionGracePeriod.set(windowMs); + bgCurrentDrainRestrictedBucketThreshold = new DeviceConfigSession<>( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_THRESHOLD_TO_RESTRICTED_BUCKET, @@ -768,6 +777,32 @@ public final class BackgroundRestrictionTest { clearInvocations(mInjector.getAppStandbyInternal()); + // It won't be restricted since user just interacted with it. + runTestBgCurrentDrainMonitorOnce(listener, stats, uids, + zeros, new double[]{0, restrictBucketThresholdMah - 1}, + zeros, new double[]{restrictBucketThresholdMah + 1, 0}, + () -> { + doReturn(mCurrentTimeMillis).when(stats).getStatsStartTimestamp(); + doReturn(mCurrentTimeMillis + windowMs) + .when(stats).getStatsEndTimestamp(); + mCurrentTimeMillis += windowMs + 1; + try { + listener.verify(timeout, testUid, testPkgName, + RESTRICTION_LEVEL_RESTRICTED_BUCKET); + fail("There shouldn't be any level change events"); + } catch (Exception e) { + // Expected. + } + verify(mInjector.getAppStandbyInternal(), never()).restrictApp( + eq(testPkgName), + eq(testUser), + anyInt(), anyInt()); + }); + + // Sleep a while. + Thread.sleep(windowMs); + clearInvocations(mInjector.getAppStandbyInternal()); + // Now it should have been restricted. runTestBgCurrentDrainMonitorOnce(listener, stats, uids, zeros, new double[]{0, restrictBucketThresholdMah - 1}, zeros, new double[]{restrictBucketThresholdMah + 1, 0}, @@ -1061,6 +1096,7 @@ public final class BackgroundRestrictionTest { } finally { closeIfNotNull(bgCurrentDrainMonitor); closeIfNotNull(bgCurrentDrainWindow); + closeIfNotNull(bgCurrentDrainInteractionGracePeriod); closeIfNotNull(bgCurrentDrainRestrictedBucketThreshold); closeIfNotNull(bgCurrentDrainBgRestrictedThreshold); closeIfNotNull(bgPromptFgsWithNotiToBgRestricted); @@ -1610,6 +1646,7 @@ public final class BackgroundRestrictionTest { DeviceConfigSession<Boolean> bgCurrentDrainMonitor = null; DeviceConfigSession<Long> bgCurrentDrainWindow = null; + DeviceConfigSession<Long> bgCurrentDrainInteractionGracePeriod = null; DeviceConfigSession<Float> bgCurrentDrainRestrictedBucketThreshold = null; DeviceConfigSession<Float> bgCurrentDrainBgRestrictedThreshold = null; DeviceConfigSession<Float> bgCurrentDrainRestrictedBucketHighThreshold = null; @@ -1655,6 +1692,14 @@ public final class BackgroundRestrictionTest { R.integer.config_bg_current_drain_window)); bgCurrentDrainWindow.set(windowMs); + bgCurrentDrainInteractionGracePeriod = new DeviceConfigSession<>( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD, + DeviceConfig::getLong, + (long) mContext.getResources().getInteger( + R.integer.config_bg_current_drain_window)); + bgCurrentDrainInteractionGracePeriod.set(windowMs); + bgCurrentDrainRestrictedBucketThreshold = new DeviceConfigSession<>( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_THRESHOLD_TO_RESTRICTED_BUCKET, @@ -2176,6 +2221,7 @@ public final class BackgroundRestrictionTest { } finally { closeIfNotNull(bgCurrentDrainMonitor); closeIfNotNull(bgCurrentDrainWindow); + closeIfNotNull(bgCurrentDrainInteractionGracePeriod); closeIfNotNull(bgCurrentDrainRestrictedBucketThreshold); closeIfNotNull(bgCurrentDrainBgRestrictedThreshold); closeIfNotNull(bgCurrentDrainRestrictedBucketHighThreshold); diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java index 444db9128662..da5c8f06bc86 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java @@ -16,6 +16,9 @@ package com.android.server.pm; +import static com.android.server.pm.BackgroundDexOptService.STATUS_DEX_OPT_FAILED; +import static com.android.server.pm.BackgroundDexOptService.STATUS_OK; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -23,12 +26,14 @@ import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertThrows; +import android.annotation.Nullable; import android.app.job.JobInfo; import android.app.job.JobParameters; import android.app.job.JobScheduler; @@ -38,10 +43,13 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.HandlerThread; import android.os.PowerManager; +import android.util.Log; +import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; import com.android.server.PinnerService; import com.android.server.pm.dex.DexManager; +import com.android.server.pm.dex.DexoptOptions; import org.junit.After; import org.junit.Before; @@ -52,7 +60,11 @@ import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.stream.Collectors; @@ -66,8 +78,12 @@ public final class BackgroundDexOptServiceUnitTest { private static final long TEST_WAIT_TIMEOUT_MS = 10_000; - private static final List<String> DEFAULT_PACKAGE_LIST = List.of("aaa", "bbb"); - private static final List<String> EMPTY_PACKAGE_LIST = List.of(); + private static final String PACKAGE_AAA = "aaa"; + private static final List<String> DEFAULT_PACKAGE_LIST = List.of(PACKAGE_AAA, "bbb"); + private int mDexOptResultForPackageAAA = PackageDexOptimizer.DEX_OPT_PERFORMED; + + // Store expected dexopt sequence for verification. + private ArrayList<DexOptInfo> mDexInfoSequence = new ArrayList<>(); @Mock private Context mContext; @@ -116,14 +132,23 @@ public final class BackgroundDexOptServiceUnitTest { when(mInjector.getDexOptThermalCutoff()).thenReturn(PowerManager.THERMAL_STATUS_CRITICAL); when(mInjector.getCurrentThermalStatus()).thenReturn(PowerManager.THERMAL_STATUS_NONE); when(mInjector.supportSecondaryDex()).thenReturn(true); - when(mDexOptHelper.getOptimizablePackages(any())).thenReturn(DEFAULT_PACKAGE_LIST); - when(mDexOptHelper.performDexOptWithStatus(any())).thenReturn( - PackageDexOptimizer.DEX_OPT_PERFORMED); - when(mDexOptHelper.performDexOpt(any())).thenReturn(true); + setupDexOptHelper(); mService = new BackgroundDexOptService(mInjector); } + private void setupDexOptHelper() { + when(mDexOptHelper.getOptimizablePackages(any())).thenReturn(DEFAULT_PACKAGE_LIST); + when(mDexOptHelper.performDexOptWithStatus(any())).thenAnswer(inv -> { + DexoptOptions opt = inv.getArgument(0); + if (opt.getPackageName().equals(PACKAGE_AAA)) { + return mDexOptResultForPackageAAA; + } + return PackageDexOptimizer.DEX_OPT_PERFORMED; + }); + when(mDexOptHelper.performDexOpt(any())).thenReturn(true); + } + @After public void tearDown() throws Exception { LocalServices.removeServiceForTest(BackgroundDexOptService.class); @@ -159,7 +184,7 @@ public final class BackgroundDexOptServiceUnitTest { @Test public void testNoExecutionForNoOptimizablePackages() { initUntilBootCompleted(); - when(mDexOptHelper.getOptimizablePackages(any())).thenReturn(EMPTY_PACKAGE_LIST); + when(mDexOptHelper.getOptimizablePackages(any())).thenReturn(Collections.emptyList()); assertThat(mService.onStartJob(mJobServiceForPostBoot, mJobParametersForPostBoot)).isFalse(); @@ -170,15 +195,70 @@ public final class BackgroundDexOptServiceUnitTest { public void testPostBootUpdateFullRun() { initUntilBootCompleted(); - runFullJob(mJobServiceForPostBoot, mJobParametersForPostBoot, false, 1); + runFullJob(mJobServiceForPostBoot, mJobParametersForPostBoot, + /* expectedReschedule= */ false, /* expectedStatus= */ STATUS_OK, + /* totalJobFinishedWithParams= */ 1, /* expectedSkippedPackage= */ null); + } + + @Test + public void testPostBootUpdateFullRunWithPackageFailure() { + mDexOptResultForPackageAAA = PackageDexOptimizer.DEX_OPT_FAILED; + + initUntilBootCompleted(); + + runFullJob(mJobServiceForPostBoot, mJobParametersForPostBoot, + /* expectedReschedule= */ false, /* expectedStatus= */ STATUS_DEX_OPT_FAILED, + /* totalJobFinishedWithParams= */ 1, /* expectedSkippedPackage= */ PACKAGE_AAA); + + assertThat(getFailedPackageNamesPrimary()).containsExactly(PACKAGE_AAA); + assertThat(getFailedPackageNamesSecondary()).isEmpty(); } @Test public void testIdleJobFullRun() { initUntilBootCompleted(); + runFullJob(mJobServiceForPostBoot, mJobParametersForPostBoot, + /* expectedReschedule= */ false, /* expectedStatus= */ STATUS_OK, + /* totalJobFinishedWithParams= */ 1, /* expectedSkippedPackage= */ null); + runFullJob(mJobServiceForIdle, mJobParametersForIdle, + /* expectedReschedule= */ true, /* expectedStatus= */ STATUS_OK, + /* totalJobFinishedWithParams= */ 1, /* expectedSkippedPackage= */ null); + } + + @Test + public void testIdleJobFullRunWithFailureOnceAndSuccessAfterUpdate() { + mDexOptResultForPackageAAA = PackageDexOptimizer.DEX_OPT_FAILED; + + initUntilBootCompleted(); + + runFullJob(mJobServiceForPostBoot, mJobParametersForPostBoot, + /* expectedReschedule= */ false, /* expectedStatus= */ STATUS_DEX_OPT_FAILED, + /* totalJobFinishedWithParams= */ 1, /* expectedSkippedPackage= */ PACKAGE_AAA); + + assertThat(getFailedPackageNamesPrimary()).containsExactly(PACKAGE_AAA); + assertThat(getFailedPackageNamesSecondary()).isEmpty(); + + runFullJob(mJobServiceForIdle, mJobParametersForIdle, + /* expectedReschedule= */ true, /* expectedStatus= */ STATUS_OK, + /* totalJobFinishedWithParams= */ 1, /* expectedSkippedPackage= */ PACKAGE_AAA); + + assertThat(getFailedPackageNamesPrimary()).containsExactly(PACKAGE_AAA); + assertThat(getFailedPackageNamesSecondary()).isEmpty(); + + mService.notifyPackageChanged(PACKAGE_AAA); - runFullJob(mJobServiceForPostBoot, mJobParametersForPostBoot, false, 1); - runFullJob(mJobServiceForIdle, mJobParametersForIdle, true, 2); + assertThat(getFailedPackageNamesPrimary()).isEmpty(); + assertThat(getFailedPackageNamesSecondary()).isEmpty(); + + // Succeed this time. + mDexOptResultForPackageAAA = PackageDexOptimizer.DEX_OPT_PERFORMED; + + runFullJob(mJobServiceForIdle, mJobParametersForIdle, + /* expectedReschedule= */ true, /* expectedStatus= */ STATUS_OK, + /* totalJobFinishedWithParams= */ 2, /* expectedSkippedPackage= */ null); + + assertThat(getFailedPackageNamesPrimary()).isEmpty(); + assertThat(getFailedPackageNamesSecondary()).isEmpty(); } @Test @@ -404,8 +484,10 @@ public final class BackgroundDexOptServiceUnitTest { } private void runFullJob(BackgroundDexOptJobService jobService, JobParameters params, - boolean expectedReschedule, int totalJobRuns) { + boolean expectedReschedule, int expectedStatus, int totalJobFinishedWithParams, + @Nullable String expectedSkippedPackage) { when(mInjector.createAndStartThread(any(), any())).thenReturn(Thread.currentThread()); + addFullRunSequence(expectedSkippedPackage); assertThat(mService.onStartJob(jobService, params)).isTrue(); ArgumentCaptor<Runnable> argThreadRunnable = ArgumentCaptor.forClass(Runnable.class); @@ -413,20 +495,99 @@ public final class BackgroundDexOptServiceUnitTest { argThreadRunnable.getValue().run(); - verify(jobService).jobFinished(params, expectedReschedule); + verify(jobService, times(totalJobFinishedWithParams)).jobFinished(params, + expectedReschedule); // Never block verify(mDexOptHelper, never()).controlDexOptBlocking(true); - verifyPerformDexOpt(DEFAULT_PACKAGE_LIST, totalJobRuns); + verifyPerformDexOpt(); + assertThat(getLastExecutionStatus()).isEqualTo(expectedStatus); } - private void verifyPerformDexOpt(List<String> pkgs, int expectedRuns) { + private void verifyPerformDexOpt() { InOrder inOrder = inOrder(mDexOptHelper); - for (int i = 0; i < expectedRuns; i++) { - for (String pkg : pkgs) { - inOrder.verify(mDexOptHelper, times(1)).performDexOptWithStatus(argThat((option) -> - option.getPackageName().equals(pkg) && !option.isDexoptOnlySecondaryDex())); - inOrder.verify(mDexOptHelper, times(1)).performDexOpt(argThat((option) -> - option.getPackageName().equals(pkg) && option.isDexoptOnlySecondaryDex())); + inOrder.verify(mDexOptHelper).getOptimizablePackages(any()); + for (DexOptInfo info : mDexInfoSequence) { + if (info.isPrimary) { + verify(mDexOptHelper).performDexOptWithStatus( + argThat((option) -> option.getPackageName().equals(info.packageName) + && !option.isDexoptOnlySecondaryDex())); + } else { + inOrder.verify(mDexOptHelper).performDexOpt( + argThat((option) -> option.getPackageName().equals(info.packageName) + && option.isDexoptOnlySecondaryDex())); + } + } + + // Even InOrder cannot check the order if the same call is made multiple times. + // To check the order across multiple runs, we reset the mock so that order can be checked + // in each call. + mDexInfoSequence.clear(); + reset(mDexOptHelper); + setupDexOptHelper(); + } + + private String findDumpValueForKey(String key) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + PrintWriter pw = new PrintWriter(out, true); + IndentingPrintWriter writer = new IndentingPrintWriter(pw, ""); + try { + mService.dump(writer); + writer.flush(); + Log.i(TAG, "dump output:" + out.toString()); + for (String line : out.toString().split(System.lineSeparator())) { + String[] vals = line.split(":"); + if (vals[0].equals(key)) { + if (vals.length == 2) { + return vals[1].strip(); + } else { + break; + } + } + } + return ""; + } finally { + writer.close(); + } + } + + List<String> findStringListFromDump(String key) { + String values = findDumpValueForKey(key); + if (values.isEmpty()) { + return Collections.emptyList(); + } + return Arrays.asList(values.split(",")); + } + + private List<String> getFailedPackageNamesPrimary() { + return findStringListFromDump("mFailedPackageNamesPrimary"); + } + + private List<String> getFailedPackageNamesSecondary() { + return findStringListFromDump("mFailedPackageNamesSecondary"); + } + + private int getLastExecutionStatus() { + return Integer.parseInt(findDumpValueForKey("mLastExecutionStatus")); + } + + private static class DexOptInfo { + public final String packageName; + public final boolean isPrimary; + + private DexOptInfo(String packageName, boolean isPrimary) { + this.packageName = packageName; + this.isPrimary = isPrimary; + } + } + + private void addFullRunSequence(@Nullable String expectedSkippedPackage) { + for (String packageName : DEFAULT_PACKAGE_LIST) { + if (packageName.equals(expectedSkippedPackage)) { + // only fails primary dexopt in mocking but add secodary + mDexInfoSequence.add(new DexOptInfo(packageName, /* isPrimary= */ false)); + } else { + mDexInfoSequence.add(new DexOptInfo(packageName, /* isPrimary= */ true)); + mDexInfoSequence.add(new DexOptInfo(packageName, /* isPrimary= */ false)); } } } diff --git a/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java index fa3e05a6b001..20cfd59973c3 100644 --- a/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java @@ -24,20 +24,33 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import android.app.AppOpsManager; import android.content.Context; +import android.content.res.Resources; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.hardware.lights.Light; +import android.hardware.lights.LightState; import android.hardware.lights.LightsManager; import android.hardware.lights.LightsRequest; +import android.os.Handler; +import android.os.Looper; import android.permission.PermissionManager; import android.util.ArraySet; import com.android.dx.mockito.inline.extended.ExtendedMockito; +import com.android.internal.R; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -53,26 +66,43 @@ import java.util.stream.Collectors; public class CameraPrivacyLightControllerTest { + private int mDayColor = 1; + private int mNightColor = 0; + private int mCameraPrivacyLightAlsAveragingIntervalMillis = 5000; + private int mCameraPrivacyLightAlsNightThreshold = (int) getLightSensorValue(15); + private MockitoSession mMockitoSession; @Mock private Context mContext; @Mock + private Resources mResources; + + @Mock private LightsManager mLightsManager; @Mock private AppOpsManager mAppOpsManager; @Mock + private SensorManager mSensorManager; + + @Mock private LightsManager.LightsSession mLightsSession; + @Mock + private Sensor mLightSensor; + private ArgumentCaptor<AppOpsManager.OnOpActiveChangedListener> mAppOpsListenerCaptor = ArgumentCaptor.forClass(AppOpsManager.OnOpActiveChangedListener.class); private ArgumentCaptor<LightsRequest> mLightsRequestCaptor = ArgumentCaptor.forClass(LightsRequest.class); + private ArgumentCaptor<SensorEventListener> mLightSensorListenerCaptor = + ArgumentCaptor.forClass(SensorEventListener.class); + private Set<String> mExemptedPackages = new ArraySet<>(); private List<Light> mLights = new ArrayList<>(); @@ -86,11 +116,22 @@ public class CameraPrivacyLightControllerTest { .spyStatic(PermissionManager.class) .startMocking(); + doReturn(mDayColor).when(mContext).getColor(R.color.camera_privacy_light_day); + doReturn(mNightColor).when(mContext).getColor(R.color.camera_privacy_light_night); + + doReturn(mResources).when(mContext).getResources(); + doReturn(mCameraPrivacyLightAlsAveragingIntervalMillis).when(mResources) + .getInteger(R.integer.config_cameraPrivacyLightAlsAveragingIntervalMillis); + doReturn(mCameraPrivacyLightAlsNightThreshold).when(mResources) + .getInteger(R.integer.config_cameraPrivacyLightAlsNightThreshold); + doReturn(mLightsManager).when(mContext).getSystemService(LightsManager.class); doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class); + doReturn(mSensorManager).when(mContext).getSystemService(SensorManager.class); doReturn(mLights).when(mLightsManager).getLights(); doReturn(mLightsSession).when(mLightsManager).openSession(anyInt()); + doReturn(mLightSensor).when(mSensorManager).getDefaultSensor(Sensor.TYPE_LIGHT); doReturn(mExemptedPackages) .when(() -> PermissionManager.getIndicatorExemptedPackages(any())); @@ -107,7 +148,7 @@ public class CameraPrivacyLightControllerTest { @Test public void testAppsOpsListenerNotRegisteredWithoutCameraLights() { mLights.add(getNextLight(false)); - new CameraPrivacyLightController(mContext); + createCameraPrivacyLightController(); verify(mAppOpsManager, times(0)).startWatchingActive(any(), any(), any()); } @@ -116,7 +157,7 @@ public class CameraPrivacyLightControllerTest { public void testAppsOpsListenerRegisteredWithCameraLight() { mLights.add(getNextLight(true)); - new CameraPrivacyLightController(mContext); + createCameraPrivacyLightController(); verify(mAppOpsManager, times(1)).startWatchingActive(any(), any(), any()); } @@ -128,14 +169,13 @@ public class CameraPrivacyLightControllerTest { mLights.add(getNextLight(r.nextBoolean())); } - new CameraPrivacyLightController(mContext); + createCameraPrivacyLightController(); // Verify no session has been opened at this point. verify(mLightsManager, times(0)).openSession(anyInt()); // Set camera op as active. - verify(mAppOpsManager).startWatchingActive(any(), any(), mAppOpsListenerCaptor.capture()); - mAppOpsListenerCaptor.getValue().onOpActiveChanged(OPSTR_CAMERA, 10101, "pkg1", true); + openCamera(); // Verify session has been opened exactly once verify(mLightsManager, times(1)).openSession(anyInt()); @@ -161,7 +201,7 @@ public class CameraPrivacyLightControllerTest { public void testWillOnlyOpenOnceWhenTwoPackagesStartOp() { mLights.add(getNextLight(true)); - new CameraPrivacyLightController(mContext); + createCameraPrivacyLightController(); verify(mAppOpsManager).startWatchingActive(any(), any(), mAppOpsListenerCaptor.capture()); @@ -176,7 +216,7 @@ public class CameraPrivacyLightControllerTest { public void testWillCloseOnFinishOp() { mLights.add(getNextLight(true)); - new CameraPrivacyLightController(mContext); + createCameraPrivacyLightController(); verify(mAppOpsManager).startWatchingActive(any(), any(), mAppOpsListenerCaptor.capture()); @@ -192,7 +232,7 @@ public class CameraPrivacyLightControllerTest { public void testWillCloseOnFinishOpForAllPackages() { mLights.add(getNextLight(true)); - new CameraPrivacyLightController(mContext); + createCameraPrivacyLightController(); int numUids = 100; List<Integer> uids = new ArrayList<>(numUids); @@ -226,7 +266,7 @@ public class CameraPrivacyLightControllerTest { mLights.add(getNextLight(true)); mExemptedPackages.add("pkg1"); - new CameraPrivacyLightController(mContext); + createCameraPrivacyLightController(); verify(mAppOpsManager).startWatchingActive(any(), any(), mAppOpsListenerCaptor.capture()); @@ -235,6 +275,147 @@ public class CameraPrivacyLightControllerTest { verify(mLightsManager, times(0)).openSession(anyInt()); } + @Test + public void testNoLightSensor() { + mLights.add(getNextLight(true)); + doReturn(null).when(mSensorManager).getDefaultSensor(Sensor.TYPE_LIGHT); + + createCameraPrivacyLightController(); + + openCamera(); + + verify(mLightsSession).requestLights(mLightsRequestCaptor.capture()); + LightsRequest lightsRequest = mLightsRequestCaptor.getValue(); + for (LightState lightState : lightsRequest.getLightStates()) { + assertEquals(mDayColor, lightState.getColor()); + } + } + + @Test + public void testALSListenerNotRegisteredUntilCameraIsOpened() { + mLights.add(getNextLight(true)); + Sensor sensor = mock(Sensor.class); + doReturn(sensor).when(mSensorManager).getDefaultSensor(Sensor.TYPE_LIGHT); + + CameraPrivacyLightController cplc = createCameraPrivacyLightController(); + + verify(mSensorManager, never()).registerListener(any(SensorEventListener.class), + any(Sensor.class), anyInt(), any(Handler.class)); + + openCamera(); + + verify(mSensorManager, times(1)).registerListener(mLightSensorListenerCaptor.capture(), + any(Sensor.class), anyInt(), any(Handler.class)); + + mAppOpsListenerCaptor.getValue().onOpActiveChanged(OPSTR_CAMERA, 10001, "pkg", false); + verify(mSensorManager, times(1)).unregisterListener(mLightSensorListenerCaptor.getValue()); + } + + @Ignore + @Test + public void testDayColor() { + testBrightnessToColor(20, mDayColor); + } + + @Ignore + @Test + public void testNightColor() { + testBrightnessToColor(10, mNightColor); + } + + private void testBrightnessToColor(int brightnessValue, int color) { + mLights.add(getNextLight(true)); + Sensor sensor = mock(Sensor.class); + doReturn(sensor).when(mSensorManager).getDefaultSensor(Sensor.TYPE_LIGHT); + + CameraPrivacyLightController cplc = createCameraPrivacyLightController(); + cplc.setElapsedRealTime(0); + + openCamera(); + + verify(mSensorManager).registerListener(mLightSensorListenerCaptor.capture(), + any(Sensor.class), anyInt(), any(Handler.class)); + SensorEventListener sensorListener = mLightSensorListenerCaptor.getValue(); + float[] sensorEventValues = new float[1]; + SensorEvent sensorEvent = new SensorEvent(sensor, 0, 0, sensorEventValues); + + sensorEventValues[0] = getLightSensorValue(brightnessValue); + sensorListener.onSensorChanged(sensorEvent); + + verify(mLightsSession, atLeastOnce()).requestLights(mLightsRequestCaptor.capture()); + for (LightState lightState : mLightsRequestCaptor.getValue().getLightStates()) { + assertEquals(color, lightState.getColor()); + } + } + + @Ignore + @Test + public void testDayToNightTransistion() { + mLights.add(getNextLight(true)); + Sensor sensor = mock(Sensor.class); + doReturn(sensor).when(mSensorManager).getDefaultSensor(Sensor.TYPE_LIGHT); + + CameraPrivacyLightController cplc = createCameraPrivacyLightController(); + cplc.setElapsedRealTime(0); + + openCamera(); + // There will be an initial call at brightness 0 + verify(mLightsSession, times(1)).requestLights(any(LightsRequest.class)); + + verify(mSensorManager).registerListener(mLightSensorListenerCaptor.capture(), + any(Sensor.class), anyInt(), any(Handler.class)); + SensorEventListener sensorListener = mLightSensorListenerCaptor.getValue(); + + onSensorEvent(cplc, sensorListener, sensor, 0, 20); + + // 5 sec avg = 20 + onSensorEvent(cplc, sensorListener, sensor, 5000, 30); + + verify(mLightsSession, times(2)).requestLights(mLightsRequestCaptor.capture()); + for (LightState lightState : mLightsRequestCaptor.getValue().getLightStates()) { + assertEquals(mDayColor, lightState.getColor()); + } + + // 5 sec avg = 22 + + onSensorEvent(cplc, sensorListener, sensor, 6000, 10); + + // 5 sec avg = 18 + + onSensorEvent(cplc, sensorListener, sensor, 8000, 5); + + // Should have always been day + verify(mLightsSession, times(2)).requestLights(mLightsRequestCaptor.capture()); + for (LightState lightState : mLightsRequestCaptor.getValue().getLightStates()) { + assertEquals(mDayColor, lightState.getColor()); + } + + // 5 sec avg = 12 + + onSensorEvent(cplc, sensorListener, sensor, 10000, 5); + + // Should now be night + verify(mLightsSession, times(3)).requestLights(mLightsRequestCaptor.capture()); + for (LightState lightState : mLightsRequestCaptor.getValue().getLightStates()) { + assertEquals(mNightColor, lightState.getColor()); + } + } + + private void onSensorEvent(CameraPrivacyLightController cplc, + SensorEventListener sensorListener, Sensor sensor, long timestamp, int value) { + cplc.setElapsedRealTime(timestamp); + sensorListener.onSensorChanged(new SensorEvent(sensor, 0, timestamp, + new float[] {getLightSensorValue(value)})); + } + + // Use the test thread so that the test is deterministic + private CameraPrivacyLightController createCameraPrivacyLightController() { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + return new CameraPrivacyLightController(mContext, Looper.myLooper()); + } + private Light getNextLight(boolean cameraType) { Light light = ExtendedMockito.mock(Light.class); if (cameraType) { @@ -245,4 +426,13 @@ public class CameraPrivacyLightControllerTest { doReturn(mNextLightId++).when(light).getId(); return light; } + + private float getLightSensorValue(int i) { + return (float) Math.exp(i / CameraPrivacyLightController.LIGHT_VALUE_MULTIPLIER); + } + + private void openCamera() { + verify(mAppOpsManager).startWatchingActive(any(), any(), mAppOpsListenerCaptor.capture()); + mAppOpsListenerCaptor.getValue().onOpActiveChanged(OPSTR_CAMERA, 10001, "pkg", true); + } } diff --git a/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_owner_2.xml b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_owner_2.xml new file mode 100644 index 000000000000..0725d25cdcab --- /dev/null +++ b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_owner_2.xml @@ -0,0 +1,6 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
+<root>
+ <device-owner package="com.android.frameworks.servicestests" name="" component="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1" userRestrictionsMigrated="true" isPoOrganizationOwnedDevice="true" />
+ <device-owner-context userId="0" />
+ <device-owner-protected-packages package="com.android.frameworks.servicestests" size="2" name0="com.some.app" name1="foo.bar.baz" />
+</root>
diff --git a/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_policies.xml b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_policies.xml new file mode 100644 index 000000000000..2d06ee6dca0e --- /dev/null +++ b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/protected_packages_device_policies.xml @@ -0,0 +1,13 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policies setup-complete="true" provisioning-state="3"> + <admin name="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"> + <policies flags="991" /> + <strong-auth-unlock-timeout value="0" /> + <test-only-admin value="true" /> + <cross-profile-calendar-packages /> + <cross-profile-packages /> + </admin> + <lock-task-features value="16" /> + <protected-packages name="com.some.app" /> + <protected-packages name="foo.bar.baz" /> +</policies> diff --git a/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java b/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java index 18e0f29d4166..bce99a09c6d2 100644 --- a/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java +++ b/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java @@ -416,6 +416,7 @@ public class BroadcastRecordTest { null /* resolvedType */, null /* requiredPermissions */, null /* excludedPermissions */, + null /* excludedPackages */, 0 /* appOp */, null /* options */, new ArrayList<>(receivers), // Make a copy to not affect the original list. diff --git a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java index d1390c68e130..e68a8a0f3af8 100644 --- a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java +++ b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java @@ -49,10 +49,11 @@ public class DropboxRateLimiterTest { assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); + assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); // Different processes and tags should not get rate limited either. assertFalse(mRateLimiter.shouldRateLimit("tag", "process2").shouldRateLimit()); assertFalse(mRateLimiter.shouldRateLimit("tag2", "process").shouldRateLimit()); - // The 6th entry of the same process should be rate limited. + // The 7th entry of the same process should be rate limited. assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); } @@ -64,12 +65,13 @@ public class DropboxRateLimiterTest { assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); - // The 6th entry of the same process should be rate limited. + assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); + // The 7th entry of the same process should be rate limited. assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); - // After 11 seconds there should be nothing left in the buffer and the same type of entry + // After 11 minutes there should be nothing left in the buffer and the same type of entry // should not get rate limited anymore. - mClock.setOffsetMillis(11000); + mClock.setOffsetMillis(11 * 60 * 1000); assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); } @@ -86,13 +88,15 @@ public class DropboxRateLimiterTest { mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); assertEquals(0, mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); + assertEquals(0, + mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); assertEquals(1, mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); assertEquals(2, mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); - // After 11 seconds the rate limiting buffer will be cleared and rate limiting will stop. - mClock.setOffsetMillis(11000); + // After 11 minutes the rate limiting buffer will be cleared and rate limiting will stop. + mClock.setOffsetMillis(11 * 60 * 1000); // The first call after rate limiting stops will still return the number of dropped events. assertEquals(2, diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java index 5b3a1284069e..98f0603ca633 100644 --- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java @@ -339,7 +339,7 @@ public final class AppHibernationServiceTest { ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mIActivityManager, times(2)).broadcastIntentWithFeature(any(), any(), intentArgumentCaptor.capture(), any(), any(), anyInt(), any(), any(), any(), any(), - anyInt(), any(), anyBoolean(), anyBoolean(), eq(USER_ID_1)); + any(), anyInt(), any(), anyBoolean(), anyBoolean(), eq(USER_ID_1)); List<Intent> capturedIntents = intentArgumentCaptor.getAllValues(); assertEquals(capturedIntents.get(0).getAction(), Intent.ACTION_LOCKED_BOOT_COMPLETED); assertEquals(capturedIntents.get(1).getAction(), Intent.ACTION_BOOT_COMPLETED); diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 0fc201eae3d4..ec6b67450a1a 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -6996,22 +6996,23 @@ public class DevicePolicyManagerTest extends DpmTestBase { dpm.setUserControlDisabledPackages(admin1, testPackages); verify(getServices().packageManagerInternal) - .setDeviceOwnerProtectedPackages(admin1.getPackageName(), testPackages); + .setOwnerProtectedPackages(UserHandle.USER_ALL, testPackages); assertThat(dpm.getUserControlDisabledPackages(admin1)).isEqualTo(testPackages); } @Test - public void testSetUserControlDisabledPackages_failingAsPO() { + public void testSetUserControlDisabledPackages_asPO() { final List<String> testPackages = new ArrayList<>(); testPackages.add("package_1"); testPackages.add("package_2"); mServiceContext.permissions.add(permission.MANAGE_DEVICE_ADMINS); setAsProfileOwner(admin1); - assertExpectException(SecurityException.class, /* messageRegex= */ null, - () -> dpm.setUserControlDisabledPackages(admin1, testPackages)); - assertExpectException(SecurityException.class, /* messageRegex= */ null, - () -> dpm.getUserControlDisabledPackages(admin1)); + dpm.setUserControlDisabledPackages(admin1, testPackages); + + verify(getServices().packageManagerInternal) + .setOwnerProtectedPackages(CALLER_USER_HANDLE, testPackages); + assertThat(dpm.getUserControlDisabledPackages(admin1)).isEqualTo(testPackages); } private void configureProfileOwnerOfOrgOwnedDevice(ComponentName who, int userId) { @@ -7845,7 +7846,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { dpm.setUserControlDisabledPackages(admin1, packages); verify(getServices().packageManagerInternal) - .setDeviceOwnerProtectedPackages(eq(admin1.getPackageName()), eq(packages)); + .setOwnerProtectedPackages(eq(UserHandle.USER_ALL), eq(packages)); } @Test diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java index 9efc10cb55ec..412722d68f43 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java @@ -63,8 +63,9 @@ import java.util.function.Function; public class PolicyVersionUpgraderTest extends DpmTestBase { // NOTE: Only change this value if the corresponding CL also adds a test to test the upgrade // to the new version. - private static final int LATEST_TESTED_VERSION = 2; + private static final int LATEST_TESTED_VERSION = 3; public static final String PERMISSIONS_TAG = "admin-can-grant-sensors-permissions"; + public static final String DEVICE_OWNER_XML = "device_owner_2.xml"; private ComponentName mFakeAdmin; private class FakePolicyUpgraderDataProvider implements PolicyUpgraderDataProvider { @@ -119,18 +120,18 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { mUpgrader = new PolicyVersionUpgrader(mProvider, getServices().pathProvider); mFakeAdmin = new ComponentName( "com.android.frameworks.servicestests", - "com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"); + "com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"); ActivityInfo activityInfo = createActivityInfo(mFakeAdmin); DeviceAdminInfo dai = createDeviceAdminInfo(activityInfo); mProvider.mComponentToDeviceAdminInfo.put(mFakeAdmin, dai); - mProvider.mUsers = new int[] {0}; + mProvider.mUsers = new int[]{0}; } @Test public void testSameVersionDoesNothing() throws IOException { writeVersionToXml(DevicePolicyManagerService.DPMS_VERSION); final int userId = mProvider.mUsers[0]; - preparePoliciesFile(userId); + preparePoliciesFile(userId, "device_policies.xml"); String oldContents = readPoliciesFile(userId); mUpgrader.upgradePolicy(DevicePolicyManagerService.DPMS_VERSION); @@ -142,19 +143,19 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { @Test public void testUpgrade0To1RemovesPasswordMetrics() throws IOException, XmlPullParserException { final String activePasswordTag = "active-password"; - mProvider.mUsers = new int[] {0, 10}; + mProvider.mUsers = new int[]{0, 10}; getServices().addUser(10, /* flags= */ 0, USER_TYPE_PROFILE_MANAGED); writeVersionToXml(0); for (int userId : mProvider.mUsers) { - preparePoliciesFile(userId); + preparePoliciesFile(userId, "device_policies.xml"); } // Validate test set-up. assertThat(isTagPresent(readPoliciesFileToStream(0), activePasswordTag)).isTrue(); mUpgrader.upgradePolicy(1); - assertThat(readVersionFromXml()).isGreaterThan(1); - for (int user: mProvider.mUsers) { + assertThat(readVersionFromXml()).isAtLeast(1); + for (int user : mProvider.mUsers) { assertThat(isTagPresent(readPoliciesFileToStream(user), activePasswordTag)).isFalse(); } } @@ -163,17 +164,17 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { public void testUpgrade1To2MarksDoForPermissionControl() throws IOException, XmlPullParserException { final int ownerUser = 10; - mProvider.mUsers = new int[] {0, ownerUser}; + mProvider.mUsers = new int[]{0, ownerUser}; getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); writeVersionToXml(1); for (int userId : mProvider.mUsers) { - preparePoliciesFile(userId); + preparePoliciesFile(userId, "device_policies.xml"); } - prepareDeviceOwnerFile(ownerUser); + prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml"); mUpgrader.upgradePolicy(2); - assertThat(readVersionFromXml()).isEqualTo(2); + assertThat(readVersionFromXml()).isAtLeast(2); assertThat(getBooleanValueTag(readPoliciesFileToStream(mProvider.mUsers[0]), PERMISSIONS_TAG)).isFalse(); assertThat(getBooleanValueTag(readPoliciesFileToStream(ownerUser), @@ -186,8 +187,8 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); setUpPackageManagerForAdmin(admin1, UserHandle.getUid(ownerUser, 123 /* admin app ID */)); writeVersionToXml(0); - preparePoliciesFile(ownerUser); - prepareDeviceOwnerFile(ownerUser); + preparePoliciesFile(ownerUser, "device_policies.xml"); + prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml"); DevicePolicyManagerServiceTestable dpms; final long ident = getContext().binder.clearCallingIdentity(); @@ -202,11 +203,65 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { getContext().binder.restoreCallingIdentity(ident); } + assertThat(readVersionFromXml()).isEqualTo(DevicePolicyManagerService.DPMS_VERSION); + // DO should be marked as able to grant sensors permission during upgrade and should be // reported as such via the API. assertThat(dpms.canAdminGrantSensorsPermissionsForUser(ownerUser)).isTrue(); } + /** + * Up to Android R DO protected packages were stored in DevicePolicyData, verify that they are + * moved to ActiveAdmin. + */ + @Test + public void testUserControlDisabledPackagesFromR() throws Exception { + final String oldTag = "protected-packages"; + final String newTag = "protected_packages"; + final int ownerUser = 0; + mProvider.mUsers = new int[]{0}; + getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); + writeVersionToXml(2); + preparePoliciesFile(ownerUser, "protected_packages_device_policies.xml"); + prepareDeviceOwnerFile(ownerUser, "device_owner_2.xml"); + + // Validate the setup. + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), oldTag)).isTrue(); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isFalse(); + + mUpgrader.upgradePolicy(3); + + assertThat(readVersionFromXml()).isAtLeast(3); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), oldTag)).isFalse(); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isTrue(); + } + + /** + * In Android S DO protected packages were stored in Owners, verify that they are moved to + * ActiveAdmin. + */ + @Test + public void testUserControlDisabledPackagesFromS() throws Exception { + final String oldTag = "device-owner-protected-packages"; + final String newTag = "protected_packages"; + final int ownerUser = 0; + mProvider.mUsers = new int[]{0}; + getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM); + writeVersionToXml(2); + preparePoliciesFile(ownerUser, "device_policies.xml"); + prepareDeviceOwnerFile(ownerUser, "protected_packages_device_owner_2.xml"); + + // Validate the setup. + assertThat(isTagPresent(readDoToStream(), oldTag)).isTrue(); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isFalse(); + + mUpgrader.upgradePolicy(3); + + assertThat(readVersionFromXml()).isAtLeast(3); + assertThat(isTagPresent(readDoToStream(), oldTag)).isFalse(); + assertThat(isTagPresent(readPoliciesFileToStream(ownerUser), newTag)).isTrue(); + } + @Test public void isLatestVersionTested() { assertThat(DevicePolicyManagerService.DPMS_VERSION).isEqualTo(LATEST_TESTED_VERSION); @@ -226,32 +281,27 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { return Integer.parseInt(versionString); } - private void preparePoliciesFile(int userId) throws IOException { + private void preparePoliciesFile(int userId, String assetFile) throws IOException { JournaledFile policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId); DpmTestUtils.writeToFile( policiesFile.chooseForWrite(), - DpmTestUtils.readAsset(mRealTestContext, - "PolicyVersionUpgraderTest/device_policies.xml")); + DpmTestUtils.readAsset(mRealTestContext, "PolicyVersionUpgraderTest/" + assetFile)); policiesFile.commit(); } - private void prepareDeviceOwnerFile(int userId) throws IOException { - File parentDir = getServices().pathProvider.getDataSystemDirectory(); - File doFilePath = (new File(parentDir, "device_owner_2.xml")).getAbsoluteFile(); - android.util.Log.i("YYYYYY", "DO paath: " + doFilePath); + private void prepareDeviceOwnerFile(int userId, String assetFile) throws IOException { + File doFilePath = getDoFilePath(); String doFileContent = DpmTestUtils.readAsset(mRealTestContext, - "PolicyVersionUpgraderTest/device_owner_2.xml") + "PolicyVersionUpgraderTest/" + assetFile) // Substitute the right DO userId, XML in resources has 0 .replace("userId=\"0\"", "userId=\"" + userId + "\""); DpmTestUtils.writeToFile(doFilePath, doFileContent); } - private void prepareProfileOwnerFile(int userId) throws IOException { - File parentDir = getServices().pathProvider.getUserSystemDirectory(userId); - DpmTestUtils.writeToFile( - (new File(parentDir, "profile_owner.xml")).getAbsoluteFile(), - DpmTestUtils.readAsset(mRealTestContext, - "PolicyVersionUpgraderTest/profile_owner.xml")); + private File getDoFilePath() { + File parentDir = getServices().pathProvider.getDataSystemDirectory(); + File doFilePath = (new File(parentDir, DEVICE_OWNER_XML)).getAbsoluteFile(); + return doFilePath; } private String readPoliciesFile(int userId) throws IOException { @@ -259,6 +309,10 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { return new String(Files.asByteSource(policiesFile).read(), Charset.defaultCharset()); } + private InputStream readDoToStream() throws IOException { + return new FileInputStream(getDoFilePath()); + } + private InputStream readPoliciesFileToStream(int userId) throws IOException { File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead(); return new FileInputStream(policiesFile); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java index e9515fa7fd9d..ffc0dcdca5fc 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java @@ -82,8 +82,6 @@ public class ImportanceExtractorTest extends UiServiceTestCase { ImportanceExtractor extractor = new ImportanceExtractor(); extractor.setConfig(mConfig); - when(mConfig.getImportance(anyString(), anyInt())).thenReturn( - NotificationManager.IMPORTANCE_MIN); NotificationChannel channel = new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED); @@ -101,8 +99,6 @@ public class ImportanceExtractorTest extends UiServiceTestCase { ImportanceExtractor extractor = new ImportanceExtractor(); extractor.setConfig(mConfig); - when(mConfig.getImportance(anyString(), anyInt())).thenReturn( - NotificationManager.IMPORTANCE_MIN); NotificationChannel channel = new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_HIGH); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java index f609306e44b0..6f7bacedc467 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java @@ -28,6 +28,13 @@ public class NotificationChannelLoggerFake implements NotificationChannelLogger CallRecord(NotificationChannelEvent event) { this.event = event; } + + @Override + public String toString() { + return "CallRecord{" + + "event=" + event + + '}'; + } } private List<CallRecord> mCalls = new ArrayList<>(); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index c0cd7a755e25..a7dc8518daea 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -52,6 +52,7 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_MUTABLE; import static android.app.PendingIntent.FLAG_ONE_SHOT; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; +import static android.content.pm.PackageManager.FEATURE_TELECOM; import static android.content.pm.PackageManager.FEATURE_WATCH; import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; @@ -187,6 +188,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; +import android.util.Pair; import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; import android.util.Xml; @@ -220,6 +222,7 @@ import com.android.server.wm.WindowManagerInternal; import com.google.common.collect.ImmutableList; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -272,6 +275,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private WindowManagerInternal mWindowManagerInternal; @Mock private PermissionHelper mPermissionHelper; + private NotificationChannelLoggerFake mLogger = new NotificationChannelLoggerFake(); private TestableContext mContext = spy(getContext()); private final String PKG = mContext.getPackageName(); private TestableLooper mTestableLooper; @@ -384,9 +388,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { "android.permission.WRITE_DEVICE_CONFIG", "android.permission.READ_DEVICE_CONFIG", "android.permission.READ_CONTACTS"); - Settings.Secure.putIntForUser( - getContext().getContentResolver(), - Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 0, USER_SYSTEM); MockitoAnnotations.initMocks(this); @@ -448,6 +449,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class)); when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0}); + when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(true); + ActivityManager.AppTask task = mock(ActivityManager.AppTask.class); List<ActivityManager.AppTask> taskList = new ArrayList<>(); ActivityManager.RecentTaskInfo taskInfo = new ActivityManager.RecentTaskInfo(); @@ -506,7 +509,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mAppOpsManager, mAppOpsService, mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class), - mTelecomManager); + mTelecomManager, mLogger); // Return first true for RoleObserver main-thread check when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper); @@ -582,6 +585,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertNotNull(mBinderService.getNotificationChannel( PKG, mContext.getUserId(), PKG, TEST_CHANNEL_ID)); clearInvocations(mRankingHandler); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); } @After @@ -1234,8 +1238,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testEnqueuedBlockedNotifications_blockedApp() throws Exception { when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); - - mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); final StatusBarNotification sbn = generateNotificationRecord(null).getSbn(); mBinderService.enqueueNotificationWithTag(PKG, PKG, @@ -1248,8 +1251,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testEnqueuedBlockedNotifications_blockedAppForegroundService() throws Exception { when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); - - mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); final StatusBarNotification sbn = generateNotificationRecord(null).getSbn(); sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE; @@ -1342,6 +1344,30 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testSetNotificationsEnabledForPackage_noChange() throws Exception { + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); + mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, true); + + verify(mPermissionHelper, never()).setNotificationPermission( + anyString(), anyInt(), anyBoolean(), anyBoolean()); + } + + @Test + public void testSetNotificationsEnabledForPackage() throws Exception { + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); + mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, false); + + verify(mPermissionHelper).setNotificationPermission( + mContext.getPackageName(), UserHandle.getUserId(mUid), false, true); + + verify(mAppOpsManager, never()).setMode(anyInt(), anyInt(), anyString(), anyInt()); + List<NotificationChannelLoggerFake.CallRecord> calls = mLogger.getCalls(); + Assert.assertEquals( + NotificationChannelLogger.NotificationChannelEvent.APP_NOTIFICATIONS_BLOCKED, + calls.get(calls.size() -1).event); + } + + @Test public void testBlockedNotifications_blockedByAssistant() throws Exception { when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); @@ -1368,7 +1394,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testBlockedNotifications_blockedByUser() throws Exception { - mService.setPreferencesHelper(mPreferencesHelper); when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); @@ -1377,7 +1402,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationRecord r = generateNotificationRecord(channel); mService.addEnqueuedNotification(r); - when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(IMPORTANCE_NONE); + when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false); NotificationManagerService.PostNotificationRunnable runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), @@ -1390,8 +1415,32 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testEnqueueNotificationInternal_noChannel() throws Exception { + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); + NotificationRecord nr = generateNotificationRecord( + new NotificationChannel("did not create", "", IMPORTANCE_DEFAULT)); + + mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), + nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); + waitForIdle(); + + verify(mPermissionHelper).hasPermission(mUid); + verify(mPermissionHelper, never()).hasPermission(Process.SYSTEM_UID); + + reset(mPermissionHelper); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); + + mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), + nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); + waitForIdle(); + + verify(mPermissionHelper).hasPermission(mUid); + assertThat(mService.mChannelToastsSent).contains(mUid); + } + + @Test public void testEnqueueNotification_appBlocked() throws Exception { - mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); mBinderService.enqueueNotificationWithTag(PKG, PKG, "testEnqueueNotification_appBlocked", 0, @@ -2686,6 +2735,49 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testDefaultChannelUpdatesApp_postMigrationToPermissions() throws Exception { + final NotificationChannel defaultChannel = mBinderService.getNotificationChannel( + PKG_N_MR1, ActivityManager.getCurrentUser(), PKG_N_MR1, + NotificationChannel.DEFAULT_CHANNEL_ID); + defaultChannel.setImportance(IMPORTANCE_NONE); + + mBinderService.updateNotificationChannelForPackage(PKG_N_MR1, mUid, defaultChannel); + + verify(mPermissionHelper).setNotificationPermission( + PKG_N_MR1, ActivityManager.getCurrentUser(), false, true); + } + + @Test + public void testPostNotification_appPermissionFixed() throws Exception { + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); + when(mPermissionHelper.isPermissionFixed(PKG, 0)).thenReturn(true); + + NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel); + mBinderService.enqueueNotificationWithTag(PKG, PKG, + "testPostNotification_appPermissionFixed", 0, + temp.getNotification(), 0); + waitForIdle(); + assertThat(mService.getNotificationRecordCount()).isEqualTo(1); + StatusBarNotification[] notifs = + mBinderService.getActiveNotifications(PKG); + assertThat(mService.getNotificationRecord(notifs[0].getKey()).isImportanceFixed()).isTrue(); + } + + @Test + public void testSummaryNotification_appPermissionFixed() { + NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel); + mService.addNotification(temp); + + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); + when(mPermissionHelper.isPermissionFixed(PKG, temp.getUserId())).thenReturn(true); + + NotificationRecord r = mService.createAutoGroupSummary( + temp.getUserId(), temp.getSbn().getPackageName(), temp.getKey(), false); + + assertThat(r.isImportanceFixed()).isTrue(); + } + + @Test public void testTvExtenderChannelOverride_onTv() throws Exception { mService.setIsTelevision(true); mService.setPreferencesHelper(mPreferencesHelper); @@ -2718,13 +2810,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testUpdateAppNotifyCreatorBlock() throws Exception { - mService.setPreferencesHelper(mPreferencesHelper); - when(mPreferencesHelper.getImportance(PKG, mUid)).thenReturn(IMPORTANCE_DEFAULT); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); - // should trigger a broadcast mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false); Thread.sleep(500); waitForIdle(); + ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); @@ -2736,7 +2827,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testUpdateAppNotifyCreatorBlock_notIfMatchesExistingSetting() throws Exception { - mService.setPreferencesHelper(mPreferencesHelper); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); mBinderService.setNotificationsEnabledForPackage(PKG, 0, false); verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null)); @@ -2744,15 +2835,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testUpdateAppNotifyCreatorUnblock() throws Exception { - mService.setPreferencesHelper(mPreferencesHelper); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); - // should not trigger a broadcast - when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_ALLOWED); - - // should trigger a broadcast - mBinderService.setNotificationsEnabledForPackage(PKG, 0, true); + mBinderService.setNotificationsEnabledForPackage(PKG, mUid, true); Thread.sleep(500); waitForIdle(); + ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); @@ -4344,7 +4432,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(IMPORTANCE_LOW, mService.getNotificationRecord(sbn.getKey()).getImportance()); - assertEquals(IMPORTANCE_UNSPECIFIED, mBinderService.getPackageImportance( + assertEquals(IMPORTANCE_DEFAULT, mBinderService.getPackageImportance( sbn.getPackageName())); nb = new Notification.Builder(mContext) @@ -4860,6 +4948,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testBackup() throws Exception { + mService.setPreferencesHelper(mPreferencesHelper); int systemChecks = mService.countSystemChecks; when(mListeners.queryPackageForServices(anyString(), anyInt(), anyInt())) .thenReturn(new ArraySet<>()); @@ -5963,8 +6052,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(false); // notifications from this package are blocked by the user - mService.setPreferencesHelper(mPreferencesHelper); - when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); setAppInForegroundForToasts(mUid, true); @@ -6260,8 +6348,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(false); // notifications from this package are blocked by the user - mService.setPreferencesHelper(mPreferencesHelper); - when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); setAppInForegroundForToasts(mUid, false); @@ -6347,8 +6434,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(true); // notifications from this package are NOT blocked by the user - mService.setPreferencesHelper(mPreferencesHelper); - when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_LOW); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); // enqueue toast -> no toasts enqueued ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), @@ -6369,8 +6455,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(false); // notifications from this package are blocked by the user - mService.setPreferencesHelper(mPreferencesHelper); - when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); setAppInForegroundForToasts(mUid, false); @@ -6393,8 +6478,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(true); // notifications from this package ARE blocked by the user - mService.setPreferencesHelper(mPreferencesHelper); - when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); setAppInForegroundForToasts(mUid, false); @@ -7303,6 +7387,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testAreNotificationsEnabledForPackage() throws Exception { + mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), + mUid); + + verify(mPermissionHelper).hasPermission(mUid); + } + + @Test public void testAreNotificationsEnabledForPackage_crossUser() throws Exception { try { mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), @@ -7311,21 +7403,31 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } catch (SecurityException e) { // pass } + verify(mPermissionHelper, never()).hasPermission(anyInt()); // cross user, with permission, no problem enableInteractAcrossUsers(); mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid + UserHandle.PER_USER_RANGE); - verify(mPermissionHelper, never()).hasPermission(anyInt()); + verify(mPermissionHelper).hasPermission(mUid + UserHandle.PER_USER_RANGE); } @Test - public void testAreNotificationsEnabledForPackage_viaInternalService() throws Exception { - assertEquals(mInternalService.areNotificationsEnabledForPackage( - mContext.getPackageName(), mUid), - mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid)); - verify(mPermissionHelper, never()).hasPermission(anyInt()); + public void testAreNotificationsEnabledForPackage_viaInternalService() { + mInternalService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid); + verify(mPermissionHelper).hasPermission(mUid); + } + + @Test + public void testGetPackageImportance() throws Exception { + when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); + assertThat(mBinderService.getPackageImportance(mContext.getPackageName())) + .isEqualTo(IMPORTANCE_DEFAULT); + + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); + assertThat(mBinderService.getPackageImportance(mContext.getPackageName())) + .isEqualTo(IMPORTANCE_NONE); } @Test @@ -8975,48 +9077,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test - public void testMigrationDisabledByDefault() { - assertThat(mService.mEnableAppSettingMigration).isFalse(); - } - - @Test - public void testPostNotification_channelLockedFixed() throws Exception { - mTestNotificationChannel.setImportanceLockedByOEM(true); - - NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel); - mBinderService.enqueueNotificationWithTag(PKG, PKG, - "testPostNotification_appPermissionFixed", 0, - temp.getNotification(), 0); - waitForIdle(); - assertThat(mService.getNotificationRecordCount()).isEqualTo(1); - StatusBarNotification[] notifs = - mBinderService.getActiveNotifications(PKG); - assertThat(mService.getNotificationRecord(notifs[0].getKey()).isImportanceFixed()).isTrue(); - - mBinderService.cancelAllNotifications(PKG, 0); - waitForIdle(); - - mTestNotificationChannel.setImportanceLockedByOEM(false); - mTestNotificationChannel.setImportanceLockedByCriticalDeviceFunction(true); - - temp = generateNotificationRecord(mTestNotificationChannel); - mBinderService.enqueueNotificationWithTag(PKG, PKG, - "testPostNotification_appPermissionFixed", 0, - temp.getNotification(), 0); - waitForIdle(); - assertThat(mService.getNotificationRecordCount()).isEqualTo(1); - notifs = mBinderService.getActiveNotifications(PKG); - assertThat(mService.getNotificationRecord(notifs[0].getKey()).isImportanceFixed()).isTrue(); - } - - @Test public void testGetNotificationChannelsBypassingDnd_blocked() throws RemoteException { mService.setPreferencesHelper(mPreferencesHelper); - when(mPreferencesHelper.getImportance(PKG, mUid)).thenReturn(IMPORTANCE_NONE); + + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); assertThat(mBinderService.getNotificationChannelsBypassingDnd(PKG, mUid).getList()) .isEmpty(); - verify(mPermissionHelper, never()).hasPermission(anyInt()); verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(PKG, mUid); } @@ -9110,8 +9177,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); - mBinderService.setNotificationsEnabledForPackage( - r.getSbn().getPackageName(), r.getUid(), false); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); // normal blocked notifications - blocked assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), @@ -9149,6 +9215,67 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testMediaNotificationsBypassBlock_atPost() throws Exception { + when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); + when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); + + Notification.Builder nb = new Notification.Builder( + mContext, mTestNotificationChannel.getId()) + .setContentTitle("foo") + .setSmallIcon(android.R.drawable.sym_def_app_icon) + .addAction(new Notification.Action.Builder(null, "test", null).build()); + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, + nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false); + + mService.addEnqueuedNotification(r); + NotificationManagerService.PostNotificationRunnable runnable = + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); + runnable.run(); + waitForIdle(); + + verify(mUsageStats).registerBlocked(any()); + verify(mUsageStats, never()).registerPostedByApp(any()); + + // just using the style - blocked + mService.clearNotifications(); + reset(mUsageStats); + nb.setStyle(new Notification.MediaStyle()); + sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, + nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); + r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addEnqueuedNotification(r); + runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); + runnable.run(); + waitForIdle(); + + verify(mUsageStats).registerBlocked(any()); + verify(mUsageStats, never()).registerPostedByApp(any()); + + // style + media session - bypasses block + mService.clearNotifications(); + reset(mUsageStats); + nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class))); + sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, + nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); + r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addEnqueuedNotification(r); + runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); + runnable.run(); + waitForIdle(); + + verify(mUsageStats, never()).registerBlocked(any()); + verify(mUsageStats).registerPostedByApp(any()); + } + + @Test public void testCallNotificationsBypassBlock() throws Exception { when(mAmi.getPendingIntentFlags(any(IIntentSender.class))) .thenReturn(FLAG_MUTABLE | FLAG_ONE_SHOT); @@ -9163,8 +9290,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); - mBinderService.setNotificationsEnabledForPackage( - r.getSbn().getPackageName(), r.getUid(), false); + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); // normal blocked notifications - blocked assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), @@ -9194,12 +9320,151 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { r.getSbn().getPackageName(), r.getUser())).thenReturn(true); assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue(); + + // set telecom manager to null - blocked + mService.setTelecomManager(null); + assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), + r.getSbn().getId(), r.getSbn().getTag(), r, false)) + .isFalse(); + + // set telecom feature to false - blocked + when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(false); + assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), + r.getSbn().getId(), r.getSbn().getTag(), r, false)) + .isFalse(); + } + + @Test + public void testCallNotificationsBypassBlock_atPost() throws Exception { + when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); + when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); + + Notification.Builder nb = + new Notification.Builder(mContext, mTestNotificationChannel.getId()) + .setContentTitle("foo") + .setSmallIcon(android.R.drawable.sym_def_app_icon) + .addAction(new Notification.Action.Builder(null, "test", null).build()); + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, + nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); + + // normal blocked notifications - blocked + mService.addEnqueuedNotification(r); + NotificationManagerService.PostNotificationRunnable runnable = + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); + runnable.run(); + waitForIdle(); + + verify(mUsageStats).registerBlocked(any()); + verify(mUsageStats, never()).registerPostedByApp(any()); + + // just using the style - blocked + mService.clearNotifications(); + reset(mUsageStats); + Person person = new Person.Builder().setName("caller").build(); + nb.setStyle(Notification.CallStyle.forOngoingCall(person, mock(PendingIntent.class))); + nb.setFullScreenIntent(mock(PendingIntent.class), true); + sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, nb.build(), + UserHandle.getUserHandleForUid(mUid), null, 0); + r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addEnqueuedNotification(r); + runnable = mService.new PostNotificationRunnable( + r.getKey(), r.getSbn().getPackageName(), r.getUid(), SystemClock.elapsedRealtime()); + runnable.run(); + waitForIdle(); + + verify(mUsageStats).registerBlocked(any()); + verify(mUsageStats, never()).registerPostedByApp(any()); + + // style + managed call - bypasses block + mService.clearNotifications(); + reset(mUsageStats); + when(mTelecomManager.isInManagedCall()).thenReturn(true); + + mService.addEnqueuedNotification(r); + runnable.run(); + waitForIdle(); + + verify(mUsageStats, never()).registerBlocked(any()); + verify(mUsageStats).registerPostedByApp(any()); + + // style + self managed call - bypasses block + mService.clearNotifications(); + reset(mUsageStats); + when(mTelecomManager.isInSelfManagedCall(r.getSbn().getPackageName(), r.getUser())) + .thenReturn(true); + + mService.addEnqueuedNotification(r); + runnable.run(); + waitForIdle(); + + verify(mUsageStats, never()).registerBlocked(any()); + verify(mUsageStats).registerPostedByApp(any()); + + // set telecom manager to null - notifications should be blocked + // but post notifications runnable should not crash + mService.clearNotifications(); + reset(mUsageStats); + mService.setTelecomManager(null); + + mService.addEnqueuedNotification(r); + runnable.run(); + waitForIdle(); + + verify(mUsageStats).registerBlocked(any()); + verify(mUsageStats, never()).registerPostedByApp(any()); + + // set FEATURE_TELECOM to false - notifications should be blocked + // but post notifications runnable should not crash + mService.setTelecomManager(mTelecomManager); + when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(false); + reset(mUsageStats); + mService.setTelecomManager(null); + + mService.addEnqueuedNotification(r); + runnable.run(); + waitForIdle(); + + verify(mUsageStats).registerBlocked(any()); + verify(mUsageStats, never()).registerPostedByApp(any()); } @Test - public void testGetAllUsersNotificationPermissions_migrationNotEnabled() { - // make sure we don't bother if the migration is not enabled - assertThat(mService.getAllUsersNotificationPermissions()).isNull(); + public void testGetAllUsersNotificationPermissions() { + // In this case, there are multiple users each with notification permissions (and also, + // for good measure, some without). + // make sure the collection returned contains info for all of them + final List<UserInfo> userInfos = new ArrayList<>(); + userInfos.add(new UserInfo(0, "user0", 0)); + userInfos.add(new UserInfo(1, "user1", 0)); + userInfos.add(new UserInfo(2, "user2", 0)); + when(mUm.getUsers()).thenReturn(userInfos); + + // construct the permissions for each of them + ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> permissions0 = new ArrayMap<>(), + permissions1 = new ArrayMap<>(); + permissions0.put(new Pair<>(10, "package1"), new Pair<>(true, false)); + permissions0.put(new Pair<>(20, "package2"), new Pair<>(false, true)); + permissions1.put(new Pair<>(11, "package1"), new Pair<>(false, false)); + permissions1.put(new Pair<>(21, "package2"), new Pair<>(true, true)); + when(mPermissionHelper.getNotificationPermissionValues(0)).thenReturn(permissions0); + when(mPermissionHelper.getNotificationPermissionValues(1)).thenReturn(permissions1); + when(mPermissionHelper.getNotificationPermissionValues(2)).thenReturn(new ArrayMap<>()); + + ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> combinedPermissions = + mService.getAllUsersNotificationPermissions(); + assertTrue(combinedPermissions.get(new Pair<>(10, "package1")).first); + assertFalse(combinedPermissions.get(new Pair<>(10, "package1")).second); + assertFalse(combinedPermissions.get(new Pair<>(20, "package2")).first); + assertTrue(combinedPermissions.get(new Pair<>(20, "package2")).second); + assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).first); + assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).second); + assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).first); + assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).second); } @Test @@ -9308,6 +9573,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testMaybeShowReviewPermissionsNotification_unknown() { + reset(mMockNm); + // Set up various possible states of the settings int and confirm whether or not the // notification is shown as expected @@ -9321,6 +9588,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testMaybeShowReviewPermissionsNotification_shouldShow() { + reset(mMockNm); + // If state is SHOULD_SHOW, it ... should show Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE, @@ -9333,6 +9602,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testMaybeShowReviewPermissionsNotification_alreadyShown() { + reset(mMockNm); + // If state is either USER_INTERACTED or DISMISSED, we should not show this on boot Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE, @@ -9349,6 +9620,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testMaybeShowReviewPermissionsNotification_reshown() { + reset(mMockNm); + // If we have re-shown the notification and the user did not subsequently interacted with // it, then make sure we show when trying on boot Settings.Global.putInt(mContext.getContentResolver(), @@ -9362,6 +9635,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testRescheduledReviewPermissionsNotification() { + reset(mMockNm); + // when rescheduled, the notification goes through the NotificationManagerInternal service // this call doesn't need to know anything about previously scheduled state -- if called, // it should send the notification & write the appropriate int to Settings diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java deleted file mode 100755 index b751c7fc73ea..000000000000 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java +++ /dev/null @@ -1,877 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.notification; - -import static android.app.AppOpsManager.MODE_ALLOWED; -import static android.app.AppOpsManager.MODE_IGNORED; -import static android.app.NotificationManager.EXTRA_BLOCKED_STATE; -import static android.app.NotificationManager.IMPORTANCE_DEFAULT; -import static android.app.NotificationManager.IMPORTANCE_NONE; -import static android.app.PendingIntent.FLAG_MUTABLE; -import static android.app.PendingIntent.FLAG_ONE_SHOT; -import static android.content.pm.PackageManager.FEATURE_WATCH; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.os.UserHandle.USER_SYSTEM; - -import static com.google.common.truth.Truth.assertThat; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; - -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyLong; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.clearInvocations; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.ActivityManager; -import android.app.ActivityManagerInternal; -import android.app.AlarmManager; -import android.app.AppOpsManager; -import android.app.IActivityManager; -import android.app.INotificationManager; -import android.app.IUriGrantsManager; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.StatsManager; -import android.app.admin.DevicePolicyManagerInternal; -import android.app.usage.UsageStatsManagerInternal; -import android.companion.ICompanionDeviceManager; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.IIntentSender; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageManager; -import android.content.pm.LauncherApps; -import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; -import android.content.pm.ParceledListSlice; -import android.content.pm.ShortcutInfo; -import android.content.pm.ShortcutServiceInternal; -import android.content.pm.UserInfo; -import android.content.res.Resources; -import android.media.AudioManager; -import android.media.session.MediaSession; -import android.os.Binder; -import android.os.Build; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Looper; -import android.os.Process; -import android.os.RemoteException; -import android.os.SystemClock; -import android.os.UserHandle; -import android.os.UserManager; -import android.provider.Settings; -import android.service.notification.NotificationListenerFilter; -import android.service.notification.StatusBarNotification; -import android.telecom.TelecomManager; -import android.telephony.TelephonyManager; -import android.test.suitebuilder.annotation.SmallTest; -import android.testing.AndroidTestingRunner; -import android.testing.TestableContext; -import android.testing.TestableLooper; -import android.testing.TestableLooper.RunWithLooper; -import android.testing.TestablePermissions; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.AtomicFile; -import android.util.Pair; - -import androidx.test.InstrumentationRegistry; - -import com.android.internal.app.IAppOpsService; -import com.android.internal.logging.InstanceIdSequence; -import com.android.internal.logging.InstanceIdSequenceFake; -import com.android.server.DeviceIdleInternal; -import com.android.server.LocalServices; -import com.android.server.SystemService; -import com.android.server.UiServiceTestCase; -import com.android.server.lights.LightsManager; -import com.android.server.lights.LogicalLight; -import com.android.server.notification.NotificationManagerService.NotificationAssistants; -import com.android.server.notification.NotificationManagerService.NotificationListeners; -import com.android.server.statusbar.StatusBarManagerInternal; -import com.android.server.uri.UriGrantsManagerInternal; -import com.android.server.utils.quota.MultiRateLimiter; -import com.android.server.wm.ActivityTaskManagerInternal; -import com.android.server.wm.WindowManagerInternal; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.stubbing.Answer; - -import java.io.File; -import java.io.FileOutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - - -@SmallTest -@RunWith(AndroidTestingRunner.class) -@RunWithLooper -/** - * Tests that NMS reads/writes the app notification state from Package/PermissionManager when - * migration is enabled. Because the migration field is read onStart - * TODO (b/194833441): migrate these tests to NotificationManagerServiceTest when the migration is - * permanently enabled. - */ -public class NotificationPermissionMigrationTest extends UiServiceTestCase { - private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId"; - private static final int UID_HEADLESS = 1000000; - - private final int mUid = Binder.getCallingUid(); - private TestableNotificationManagerService mService; - private INotificationManager mBinderService; - private NotificationManagerInternal mInternalService; - private ShortcutHelper mShortcutHelper; - @Mock - private IPackageManager mPackageManager; - @Mock - private PackageManager mPackageManagerClient; - @Mock - private PackageManagerInternal mPackageManagerInternal; - @Mock - private WindowManagerInternal mWindowManagerInternal; - @Mock - private PermissionHelper mPermissionHelper; - private TestableContext mContext = spy(getContext()); - private final String PKG = mContext.getPackageName(); - private TestableLooper mTestableLooper; - @Mock - private RankingHelper mRankingHelper; - @Mock private PreferencesHelper mPreferencesHelper; - AtomicFile mPolicyFile; - File mFile; - @Mock - private NotificationUsageStats mUsageStats; - @Mock - private UsageStatsManagerInternal mAppUsageStats; - @Mock - private AudioManager mAudioManager; - @Mock - private LauncherApps mLauncherApps; - @Mock - private ShortcutServiceInternal mShortcutServiceInternal; - @Mock - private UserManager mUserManager; - @Mock - ActivityManager mActivityManager; - @Mock - Resources mResources; - @Mock - RankingHandler mRankingHandler; - @Mock - ActivityManagerInternal mAmi; - @Mock - private Looper mMainLooper; - - @Mock - IIntentSender pi1; - - private static final int MAX_POST_DELAY = 1000; - - private NotificationChannel mTestNotificationChannel = new NotificationChannel( - TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); - - private static final String VALID_CONVO_SHORTCUT_ID = "shortcut"; - - @Mock - private NotificationListeners mListeners; - @Mock - private NotificationListenerFilter mNlf; - @Mock private NotificationAssistants mAssistants; - @Mock private ConditionProviders mConditionProviders; - private ManagedServices.ManagedServiceInfo mListener; - @Mock private ICompanionDeviceManager mCompanionMgr; - @Mock SnoozeHelper mSnoozeHelper; - @Mock GroupHelper mGroupHelper; - @Mock - IBinder mPermOwner; - @Mock - IActivityManager mAm; - @Mock - ActivityTaskManagerInternal mAtm; - @Mock - IUriGrantsManager mUgm; - @Mock - UriGrantsManagerInternal mUgmInternal; - @Mock - AppOpsManager mAppOpsManager; - @Mock - private TestableNotificationManagerService.NotificationAssistantAccessGrantedCallback - mNotificationAssistantAccessGrantedCallback; - @Mock - UserManager mUm; - @Mock - NotificationHistoryManager mHistoryManager; - @Mock - StatsManager mStatsManager; - @Mock - AlarmManager mAlarmManager; - @Mock - MultiRateLimiter mToastRateLimiter; - BroadcastReceiver mPackageIntentReceiver; - NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake(); - private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake( - 1 << 30); - @Mock - StatusBarManagerInternal mStatusBar; - - private NotificationManagerService.WorkerHandler mWorkerHandler; - - @Before - public void setUp() throws Exception { - // These should be the only difference in setup from NMSTest - Settings.Secure.putIntForUser( - getContext().getContentResolver(), - Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM); - Settings.Global.putInt(getContext().getContentResolver(), - Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, 1); - - // Shell permissions will override permissions of our app, so add all necessary permissions - // for this test here: - InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( - "android.permission.WRITE_DEVICE_CONFIG", - "android.permission.READ_DEVICE_CONFIG", - "android.permission.READ_CONTACTS"); - - MockitoAnnotations.initMocks(this); - - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); - - DeviceIdleInternal deviceIdleInternal = mock(DeviceIdleInternal.class); - when(deviceIdleInternal.getNotificationAllowlistDuration()).thenReturn(3000L); - - LocalServices.removeServiceForTest(UriGrantsManagerInternal.class); - LocalServices.addService(UriGrantsManagerInternal.class, mUgmInternal); - LocalServices.removeServiceForTest(WindowManagerInternal.class); - LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal); - LocalServices.removeServiceForTest(StatusBarManagerInternal.class); - LocalServices.addService(StatusBarManagerInternal.class, mStatusBar); - LocalServices.removeServiceForTest(DeviceIdleInternal.class); - LocalServices.addService(DeviceIdleInternal.class, deviceIdleInternal); - LocalServices.removeServiceForTest(ActivityManagerInternal.class); - LocalServices.addService(ActivityManagerInternal.class, mAmi); - LocalServices.removeServiceForTest(PackageManagerInternal.class); - LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal); - mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager); - when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0}); - - doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any()); - - mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, - mNotificationInstanceIdSequence); - - // Use this testable looper. - mTestableLooper = TestableLooper.get(this); - // MockPackageManager - default returns ApplicationInfo with matching calling UID - mContext.setMockPackageManager(mPackageManagerClient); - - when(mPackageManager.getApplicationInfo(anyString(), anyLong(), anyInt())) - .thenAnswer((Answer<ApplicationInfo>) invocation -> { - Object[] args = invocation.getArguments(); - return getApplicationInfo((String) args[0], mUid); - }); - when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) - .thenAnswer((Answer<ApplicationInfo>) invocation -> { - Object[] args = invocation.getArguments(); - return getApplicationInfo((String) args[0], mUid); - }); - when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid); - when(mPackageManagerInternal.isSameApp(anyString(), anyInt(), anyInt())).thenAnswer( - (Answer<Boolean>) invocation -> { - Object[] args = invocation.getArguments(); - return (int) args[1] == mUid; - }); - final LightsManager mockLightsManager = mock(LightsManager.class); - when(mockLightsManager.getLight(anyInt())).thenReturn(mock(LogicalLight.class)); - when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); - when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false); - when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner); - when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG}); - when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG}); - mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class)); - - // write to a test file; the system file isn't readable from tests - mFile = new File(mContext.getCacheDir(), "test.xml"); - mFile.createNewFile(); - final String preupgradeXml = "<notification-policy></notification-policy>"; - mPolicyFile = new AtomicFile(mFile); - FileOutputStream fos = mPolicyFile.startWrite(); - fos.write(preupgradeXml.getBytes()); - mPolicyFile.finishWrite(fos); - - // Setup managed services - when(mNlf.isTypeAllowed(anyInt())).thenReturn(true); - when(mNlf.isPackageAllowed(any())).thenReturn(true); - when(mNlf.isPackageAllowed(null)).thenReturn(true); - when(mListeners.getNotificationListenerFilter(any())).thenReturn(mNlf); - mListener = mListeners.new ManagedServiceInfo( - null, new ComponentName(PKG, "test_class"), - UserHandle.getUserId(mUid), true, null, 0, 123); - ComponentName defaultComponent = ComponentName.unflattenFromString("config/device"); - ArraySet<ComponentName> components = new ArraySet<>(); - components.add(defaultComponent); - when(mListeners.getDefaultComponents()).thenReturn(components); - when(mConditionProviders.getDefaultPackages()) - .thenReturn(new ArraySet<>(Arrays.asList("config"))); - when(mAssistants.getDefaultComponents()).thenReturn(components); - when(mAssistants.queryPackageForServices( - anyString(), anyInt(), anyInt())).thenReturn(components); - when(mListeners.checkServiceTokenLocked(null)).thenReturn(mListener); - ManagedServices.Config listenerConfig = new ManagedServices.Config(); - listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS; - when(mListeners.getConfig()).thenReturn(listenerConfig); - ManagedServices.Config assistantConfig = new ManagedServices.Config(); - assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS; - when(mAssistants.getConfig()).thenReturn(assistantConfig); - ManagedServices.Config dndConfig = new ManagedServices.Config(); - dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS; - when(mConditionProviders.getConfig()).thenReturn(dndConfig); - - when(mAssistants.isAdjustmentAllowed(anyString())).thenReturn(true); - - // apps allowed as convos - mService.setStringArrayResourceValue(PKG_O); - - mWorkerHandler = spy(mService.new WorkerHandler(mTestableLooper.getLooper())); - mService.init(mWorkerHandler, mRankingHandler, mPackageManager, mPackageManagerClient, - mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr, - mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm, - mAppUsageStats, mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal, - mAppOpsManager, mock(IAppOpsService.class), mUm, mHistoryManager, mStatsManager, - mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper, - mock(UsageStatsManagerInternal.class), mock(TelecomManager.class)); - // Return first true for RoleObserver main-thread check - when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); - mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper); - - mService.setAudioManager(mAudioManager); - - mShortcutHelper = mService.getShortcutHelper(); - mShortcutHelper.setLauncherApps(mLauncherApps); - mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal); - mShortcutHelper.setUserManager(mUserManager); - - // Capture PackageIntentReceiver - ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = - ArgumentCaptor.forClass(BroadcastReceiver.class); - ArgumentCaptor<IntentFilter> intentFilterCaptor = - ArgumentCaptor.forClass(IntentFilter.class); - - verify(mContext, atLeastOnce()).registerReceiverAsUser(broadcastReceiverCaptor.capture(), - any(), intentFilterCaptor.capture(), any(), any()); - verify(mContext, atLeastOnce()).registerReceiver(broadcastReceiverCaptor.capture(), - intentFilterCaptor.capture()); - List<BroadcastReceiver> broadcastReceivers = broadcastReceiverCaptor.getAllValues(); - List<IntentFilter> intentFilters = intentFilterCaptor.getAllValues(); - - for (int i = 0; i < intentFilters.size(); i++) { - final IntentFilter filter = intentFilters.get(i); - if (filter.hasAction(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED) - && filter.hasAction(Intent.ACTION_PACKAGES_UNSUSPENDED) - && filter.hasAction(Intent.ACTION_PACKAGES_SUSPENDED)) { - mPackageIntentReceiver = broadcastReceivers.get(i); - } - } - assertNotNull("package intent receiver should exist", mPackageIntentReceiver); - - // Pretend the shortcut exists - List<ShortcutInfo> shortcutInfos = new ArrayList<>(); - ShortcutInfo info = mock(ShortcutInfo.class); - when(info.getPackage()).thenReturn(PKG); - when(info.getId()).thenReturn(VALID_CONVO_SHORTCUT_ID); - when(info.getUserId()).thenReturn(USER_SYSTEM); - when(info.isLongLived()).thenReturn(true); - when(info.isEnabled()).thenReturn(true); - shortcutInfos.add(info); - when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos); - when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), - anyString(), anyInt(), any())).thenReturn(true); - when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true); - - // Set the testable bubble extractor - RankingHelper rankingHelper = mService.getRankingHelper(); - BubbleExtractor extractor = rankingHelper.findExtractor(BubbleExtractor.class); - extractor.setActivityManager(mActivityManager); - - // Tests call directly into the Binder. - mBinderService = mService.getBinderService(); - mInternalService = mService.getInternalService(); - - mBinderService.createNotificationChannels( - PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel))); - mBinderService.createNotificationChannels( - PKG_P, new ParceledListSlice(Arrays.asList(mTestNotificationChannel))); - mBinderService.createNotificationChannels( - PKG_O, new ParceledListSlice(Arrays.asList(mTestNotificationChannel))); - assertNotNull(mBinderService.getNotificationChannel( - PKG, mContext.getUserId(), PKG, TEST_CHANNEL_ID)); - clearInvocations(mRankingHandler); - } - - @After - public void tearDown() throws Exception { - if (mFile != null) mFile.delete(); - - try { - mService.onDestroy(); - } catch (IllegalStateException | IllegalArgumentException e) { - // can throw if a broadcast receiver was never registered - } - - InstrumentationRegistry.getInstrumentation() - .getUiAutomation().dropShellPermissionIdentity(); - // Remove scheduled messages that would be processed when the test is already done, and - // could cause issues, for example, messages that remove/cancel shown toasts (this causes - // problematic interactions with mocks when they're no longer working as expected). - mWorkerHandler.removeCallbacksAndMessages(null); - } - - private ApplicationInfo getApplicationInfo(String pkg, int uid) { - final ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.uid = uid; - switch (pkg) { - case PKG_N_MR1: - applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1; - break; - case PKG_O: - applicationInfo.targetSdkVersion = Build.VERSION_CODES.O; - break; - case PKG_P: - applicationInfo.targetSdkVersion = Build.VERSION_CODES.P; - break; - default: - applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; - break; - } - return applicationInfo; - } - - public void waitForIdle() { - mTestableLooper.processAllMessages(); - } - - private NotificationRecord generateNotificationRecord(NotificationChannel channel) { - return generateNotificationRecord(channel, null); - } - - private NotificationRecord generateNotificationRecord(NotificationChannel channel, - Notification.TvExtender extender) { - if (channel == null) { - channel = mTestNotificationChannel; - } - Notification.Builder nb = new Notification.Builder(mContext, channel.getId()) - .setContentTitle("foo") - .setSmallIcon(android.R.drawable.sym_def_app_icon) - .addAction(new Notification.Action.Builder(null, "test", null).build()); - if (extender != null) { - nb.extend(extender); - } - StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, - nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); - return new NotificationRecord(mContext, sbn, channel); - } - - private void enableInteractAcrossUsers() { - TestablePermissions perms = mContext.getTestablePermissions(); - perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); - } - - @Test - public void testAreNotificationsEnabledForPackage() throws Exception { - mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), - mUid); - - verify(mPermissionHelper).hasPermission(mUid); - } - - @Test - public void testAreNotificationsEnabledForPackage_crossUser() throws Exception { - try { - mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), - mUid + UserHandle.PER_USER_RANGE); - fail("Cannot call cross user without permission"); - } catch (SecurityException e) { - // pass - } - verify(mPermissionHelper, never()).hasPermission(anyInt()); - - // cross user, with permission, no problem - enableInteractAcrossUsers(); - mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), - mUid + UserHandle.PER_USER_RANGE); - - verify(mPermissionHelper).hasPermission(mUid + UserHandle.PER_USER_RANGE); - } - - @Test - public void testAreNotificationsEnabledForPackage_viaInternalService() { - mInternalService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid); - verify(mPermissionHelper).hasPermission(mUid); - } - - @Test - public void testGetPackageImportance() throws Exception { - when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); - assertThat(mBinderService.getPackageImportance(mContext.getPackageName())) - .isEqualTo(IMPORTANCE_DEFAULT); - - when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); - assertThat(mBinderService.getPackageImportance(mContext.getPackageName())) - .isEqualTo(IMPORTANCE_NONE); - } - - @Test - public void testEnqueueNotificationInternal_noChannel() throws Exception { - when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); - NotificationRecord nr = generateNotificationRecord( - new NotificationChannel("did not create", "", IMPORTANCE_DEFAULT)); - - mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), - nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); - waitForIdle(); - - verify(mPermissionHelper).hasPermission(mUid); - verify(mPermissionHelper, never()).hasPermission(Process.SYSTEM_UID); - - reset(mPermissionHelper); - when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); - - mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), - nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); - waitForIdle(); - - verify(mPermissionHelper).hasPermission(mUid); - assertThat(mService.mChannelToastsSent).contains(mUid); - } - - @Test - public void testSetNotificationsEnabledForPackage_noChange() throws Exception { - when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); - mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, true); - - verify(mPermissionHelper, never()).setNotificationPermission( - anyString(), anyInt(), anyBoolean(), anyBoolean()); - } - - @Test - public void testSetNotificationsEnabledForPackage() throws Exception { - when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); - mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, false); - - verify(mPermissionHelper).setNotificationPermission( - mContext.getPackageName(), UserHandle.getUserId(mUid), false, true); - - verify(mAppOpsManager, never()).setMode(anyInt(), anyInt(), anyString(), anyInt()); - } - - @Test - public void testUpdateAppNotifyCreatorBlock() throws Exception { - when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); - - mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false); - Thread.sleep(500); - waitForIdle(); - - ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); - verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); - - assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED, - captor.getValue().getAction()); - assertEquals(PKG, captor.getValue().getPackage()); - assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true)); - } - - @Test - public void testUpdateAppNotifyCreatorUnblock() throws Exception { - when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); - - mBinderService.setNotificationsEnabledForPackage(PKG, mUid, true); - Thread.sleep(500); - waitForIdle(); - - ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); - verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); - - assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED, - captor.getValue().getAction()); - assertEquals(PKG, captor.getValue().getPackage()); - assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true)); - } - - @Test - public void testGetNotificationChannelsBypassingDnd_blocked() throws RemoteException { - mService.setPreferencesHelper(mPreferencesHelper); - - when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); - - assertThat(mBinderService.getNotificationChannelsBypassingDnd(PKG, mUid).getList()) - .isEmpty(); - verify(mPreferencesHelper, never()).getImportance(anyString(), anyInt()); - verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(PKG, mUid); - } - - @Test - public void testBlockedNotifications_blockedByUser() throws Exception { - when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); - when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); - - NotificationChannel channel = new NotificationChannel("id", "name", - NotificationManager.IMPORTANCE_HIGH); - NotificationRecord r = generateNotificationRecord(channel); - mService.addEnqueuedNotification(r); - - when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false); - - NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), - r.getUid(), SystemClock.elapsedRealtime()); - runnable.run(); - waitForIdle(); - - verify(mUsageStats).registerBlocked(any()); - verify(mUsageStats, never()).registerPostedByApp(any()); - } - - @Test - public void testEnqueueNotification_appBlocked() throws Exception { - when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); - - mBinderService.enqueueNotificationWithTag(PKG, PKG, - "testEnqueueNotification_appBlocked", 0, - generateNotificationRecord(null).getNotification(), 0); - waitForIdle(); - verify(mWorkerHandler, never()).post( - any(NotificationManagerService.EnqueueNotificationRunnable.class)); - } - - @Test - public void testDefaultChannelDoesNotUpdateApp_postMigrationToPermissions() throws Exception { - final NotificationChannel defaultChannel = mBinderService.getNotificationChannel( - PKG_N_MR1, ActivityManager.getCurrentUser(), PKG_N_MR1, - NotificationChannel.DEFAULT_CHANNEL_ID); - defaultChannel.setImportance(IMPORTANCE_NONE); - - mBinderService.updateNotificationChannelForPackage(PKG_N_MR1, mUid, defaultChannel); - - verify(mPermissionHelper).setNotificationPermission( - PKG_N_MR1, ActivityManager.getCurrentUser(), false, true); - } - - @Test - public void testPostNotification_appPermissionFixed() throws Exception { - when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); - when(mPermissionHelper.isPermissionFixed(PKG, 0)).thenReturn(true); - - NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel); - mBinderService.enqueueNotificationWithTag(PKG, PKG, - "testPostNotification_appPermissionFixed", 0, - temp.getNotification(), 0); - waitForIdle(); - assertThat(mService.getNotificationRecordCount()).isEqualTo(1); - StatusBarNotification[] notifs = - mBinderService.getActiveNotifications(PKG); - assertThat(mService.getNotificationRecord(notifs[0].getKey()).isImportanceFixed()).isTrue(); - } - - @Test - public void testSummaryNotification_appPermissionFixed() { - NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel); - mService.addNotification(temp); - - when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); - when(mPermissionHelper.isPermissionFixed(PKG, temp.getUserId())).thenReturn(true); - - NotificationRecord r = mService.createAutoGroupSummary( - temp.getUserId(), temp.getSbn().getPackageName(), temp.getKey(), false); - - assertThat(r.isImportanceFixed()).isTrue(); - } - - @Test - public void testMediaNotificationsBypassBlock() throws Exception { - when(mAmi.getPendingIntentFlags(any(IIntentSender.class))) - .thenReturn(FLAG_MUTABLE | FLAG_ONE_SHOT); - when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); - - Notification.Builder nb = new Notification.Builder( - mContext, mTestNotificationChannel.getId()) - .setContentTitle("foo") - .setSmallIcon(android.R.drawable.sym_def_app_icon) - .addAction(new Notification.Action.Builder(null, "test", null).build()); - StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, - nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); - NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); - - when(mPermissionHelper.hasPermission(mUid)).thenReturn(false); - - // normal blocked notifications - blocked - assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), - r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse(); - - // just using the style - blocked - nb.setStyle(new Notification.MediaStyle()); - sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, - nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); - r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); - - assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), - r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse(); - - // using the style, but incorrect type in session - blocked - nb.setStyle(new Notification.MediaStyle()); - Bundle extras = new Bundle(); - extras.putParcelable(Notification.EXTRA_MEDIA_SESSION, new Intent()); - nb.addExtras(extras); - sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, - nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); - r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); - - assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), - r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse(); - - // style + media session - bypasses block - nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class))); - sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, - nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); - r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); - - assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), - r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue(); - } - - @Test - public void testMediaNotificationsBypassBlock_atPost() throws Exception { - when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); - when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); - - Notification.Builder nb = new Notification.Builder( - mContext, mTestNotificationChannel.getId()) - .setContentTitle("foo") - .setSmallIcon(android.R.drawable.sym_def_app_icon) - .addAction(new Notification.Action.Builder(null, "test", null).build()); - StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, - nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); - NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); - - when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false); - - mService.addEnqueuedNotification(r); - NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), - r.getUid(), SystemClock.elapsedRealtime()); - runnable.run(); - waitForIdle(); - - verify(mUsageStats).registerBlocked(any()); - verify(mUsageStats, never()).registerPostedByApp(any()); - - // just using the style - blocked - mService.clearNotifications(); - reset(mUsageStats); - nb.setStyle(new Notification.MediaStyle()); - sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, - nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); - r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); - - mService.addEnqueuedNotification(r); - runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), - r.getUid(), SystemClock.elapsedRealtime()); - runnable.run(); - waitForIdle(); - - verify(mUsageStats).registerBlocked(any()); - verify(mUsageStats, never()).registerPostedByApp(any()); - - // style + media session - bypasses block - mService.clearNotifications(); - reset(mUsageStats); - nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class))); - sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, - nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0); - r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); - - mService.addEnqueuedNotification(r); - runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), - r.getUid(), SystemClock.elapsedRealtime()); - runnable.run(); - waitForIdle(); - - verify(mUsageStats, never()).registerBlocked(any()); - verify(mUsageStats).registerPostedByApp(any()); - } - - @Test - public void testGetAllUsersNotificationPermissions() { - // In this case, there are multiple users each with notification permissions (and also, - // for good measure, some without). - // make sure the collection returned contains info for all of them - final List<UserInfo> userInfos = new ArrayList<>(); - userInfos.add(new UserInfo(0, "user0", 0)); - userInfos.add(new UserInfo(1, "user1", 0)); - userInfos.add(new UserInfo(2, "user2", 0)); - when(mUm.getUsers()).thenReturn(userInfos); - - // construct the permissions for each of them - ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> permissions0 = new ArrayMap<>(), - permissions1 = new ArrayMap<>(); - permissions0.put(new Pair<>(10, "package1"), new Pair<>(true, false)); - permissions0.put(new Pair<>(20, "package2"), new Pair<>(false, true)); - permissions1.put(new Pair<>(11, "package1"), new Pair<>(false, false)); - permissions1.put(new Pair<>(21, "package2"), new Pair<>(true, true)); - when(mPermissionHelper.getNotificationPermissionValues(0)).thenReturn(permissions0); - when(mPermissionHelper.getNotificationPermissionValues(1)).thenReturn(permissions1); - when(mPermissionHelper.getNotificationPermissionValues(2)).thenReturn(new ArrayMap<>()); - - ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> combinedPermissions = - mService.getAllUsersNotificationPermissions(); - assertTrue(combinedPermissions.get(new Pair<>(10, "package1")).first); - assertFalse(combinedPermissions.get(new Pair<>(10, "package1")).second); - assertFalse(combinedPermissions.get(new Pair<>(20, "package2")).first); - assertTrue(combinedPermissions.get(new Pair<>(20, "package2")).second); - assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).first); - assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).second); - assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).first); - assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).second); - } -} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java index d89141cc1000..5468220d9564 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java @@ -1065,9 +1065,8 @@ public class NotificationRecordTest extends UiServiceTestCase { } @Test - public void testApplyImportanceAdjustmentsForNonOemDefaultAppLockedChannels() { + public void testApplyImportanceAdjustments() { NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); - channel.setImportanceLockedByOEM(false); StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */, true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */, diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java index 46b47f4dcfdd..3a352cbe1900 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java @@ -88,51 +88,13 @@ public class PermissionHelperTest extends UiServiceTestCase { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true, false); + mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, false); PackageInfo testPkgInfo = new PackageInfo(); testPkgInfo.requestedPermissions = new String[]{ Manifest.permission.POST_NOTIFICATIONS }; when(mPackageManager.getPackageInfo(anyString(), anyLong(), anyInt())) .thenReturn(testPkgInfo); } - // TODO (b/194833441): Remove when the migration is enabled - @Test - public void testMethodsThrowIfMigrationDisabled() throws IllegalAccessException, - InvocationTargetException { - PermissionHelper permHelper = - new PermissionHelper(mPmi, mPackageManager, mPermManager, false, false); - - Method[] allMethods = PermissionHelper.class.getDeclaredMethods(); - for (Method method : allMethods) { - if (Modifier.isPublic(method.getModifiers()) && - !Objects.equals("isMigrationEnabled", method.getName())) { - Parameter[] params = method.getParameters(); - List<Object> args = Lists.newArrayListWithCapacity(params.length); - for (int i = 0; i < params.length; i++) { - Type type = params[i].getParameterizedType(); - if (type.getTypeName().equals("java.lang.String")) { - args.add(""); - } else if (type.getTypeName().equals("boolean")){ - args.add(false); - } else if (type.getTypeName().equals("int")) { - args.add(1); - } else if (type.getTypeName().equals( - "com.android.server.notification.PermissionHelper$PackagePermission")) { - args.add(null); - } - } - try { - method.invoke(permHelper, args.toArray()); - fail("Method should have thrown because migration flag is disabled"); - } catch (InvocationTargetException e) { - if (!(e.getTargetException() instanceof IllegalStateException)) { - throw e; - } - } - } - } - } - @Test public void testHasPermission() throws Exception { when(mPmi.checkPostNotificationsPermissionGrantedOrLegacyAccess(anyInt())) @@ -304,7 +266,7 @@ public class PermissionHelperTest extends UiServiceTestCase { @Test public void testSetNotificationPermission_pkgPerm_grantedByDefaultPermSet_allUserSet() throws Exception { - mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true, true); + mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true); when(mPmi.checkPermission(anyString(), anyString(), anyInt())) .thenReturn(PERMISSION_DENIED); when(mPermManager.getPermissionFlags(anyString(), diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 6d0895935877..a5cec7e01e9a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -278,6 +278,14 @@ public class PreferencesHelperTest extends UiServiceTestCase { when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), anyString(), eq(null), anyString())).thenReturn(MODE_DEFAULT); + ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); + appPermissions.put(new Pair(UID_P, PKG_P), new Pair(true, false)); + appPermissions.put(new Pair(UID_O, PKG_O), new Pair(true, false)); + appPermissions.put(new Pair(UID_N_MR1, PKG_N_MR1), new Pair(true, false)); + + when(mPermissionHelper.getNotificationPermissionValues(USER_SYSTEM)) + .thenReturn(appPermissions); + mStatsEventBuilderFactory = new WrappedSysUiStatsEvent.WrappedBuilderFactory(); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, @@ -408,6 +416,13 @@ public class PreferencesHelperTest extends UiServiceTestCase { NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH); assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false)); + ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); + appPermissions.put(new Pair(uid0, package0), new Pair(false, false)); + appPermissions.put(new Pair(uid10, package10), new Pair(true, false)); + + when(mPermissionHelper.getNotificationPermissionValues(10)) + .thenReturn(appPermissions); + ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10); // Reset state. @@ -433,6 +448,12 @@ public class PreferencesHelperTest extends UiServiceTestCase { NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH); assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false)); + ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); + appPermissions.put(new Pair(uid0, package0), new Pair(true, false)); + + when(mPermissionHelper.getNotificationPermissionValues(USER_SYSTEM)) + .thenReturn(appPermissions); + ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0); // Reset state. @@ -478,7 +499,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false)); mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true); - mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false, UserHandle.USER_ALL, channel1.getId(), channel2.getId(), @@ -489,7 +509,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { loadStreamXml(baos, false, UserHandle.USER_ALL); assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); - assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1)); assertEquals(channel1, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false)); compareChannels(channel2, @@ -550,8 +569,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.setInvalidMsgAppDemoted(PKG_P, UID_P, true); mHelper.setValidBubbleSent(PKG_P, UID_P); - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE); - ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true, USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(), NotificationChannel.DEFAULT_CHANNEL_ID); @@ -562,7 +579,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { loadStreamXml(baos, true, USER_SYSTEM); - assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O)); assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); assertTrue(mHelper.hasSentInvalidMsg(PKG_P, UID_P)); assertFalse(mHelper.hasSentInvalidMsg(PKG_N_MR1, UID_N_MR1)); @@ -601,7 +617,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testReadXml_oldXml_migrates() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -672,7 +687,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testReadXml_oldXml_backup_migratesWhenPkgInstalled() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -751,7 +765,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testReadXml_newXml_noMigration_showPermissionNotification() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -809,7 +822,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testReadXml_newXml_noMigration_noPermissionNotification() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -866,7 +878,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testReadXml_oldXml_migration_NoUid() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -900,7 +911,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testReadXml_newXml_noMigration_NoUid() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -933,7 +943,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testChannelXmlForNonBackup_postMigration() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -1014,7 +1023,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testChannelXmlForBackup_postMigration() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -1101,7 +1109,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testChannelXmlForBackup_postMigration_noExternal() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -1181,7 +1188,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testChannelXmlForBackup_postMigration_noLocalSettings() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); @@ -1303,6 +1309,12 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testBackupRestoreXml_withNullSoundUri() throws Exception { + ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); + appPermissions.put(new Pair(UID_N_MR1, PKG_N_MR1), new Pair(true, false)); + + when(mPermissionHelper.getNotificationPermissionValues(USER_SYSTEM)) + .thenReturn(appPermissions); + NotificationChannel channel = new NotificationChannel("id", "name", IMPORTANCE_LOW); channel.setSound(null, mAudioAttributes); @@ -1472,14 +1484,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testCreateChannel_blocked() throws Exception { - mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE); - - assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, - new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false)); - } - - @Test public void testCreateChannel_badImportance() throws Exception { try { mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, @@ -1543,12 +1547,10 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testUpdate_preUpgrade_updatesAppFields() throws Exception { - mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_UNSPECIFIED); assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1)); assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1)); - assertFalse(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1)); NotificationChannel defaultChannel = mHelper.getNotificationChannel( PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false); @@ -1566,8 +1568,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1)); assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1)); - assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_N_MR1, UID_N_MR1)); - assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1)); } @Test @@ -1592,9 +1592,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O)); assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, mHelper.getPackageVisibility(PKG_O, UID_O)); - assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O, - UID_O)); - assertFalse(mHelper.getIsAppImportanceLocked(PKG_O, UID_O)); } @Test @@ -1629,8 +1626,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1)); assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1)); - assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1, - UID_N_MR1)); } @Test @@ -2015,8 +2010,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testCreateAndDeleteCanChannelsBypassDnd_localSettings() throws Exception { + public void testCreateAndDeleteCanChannelsBypassDnd_localSettings() { int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; + when(mPermissionHelper.hasPermission(uid)).thenReturn(true); // create notification channel that can't bypass dnd // expected result: areChannelsBypassingDnd = false @@ -2029,7 +2025,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { // create notification channel that can bypass dnd // expected result: areChannelsBypassingDnd = true - assertTrue(mHelper.getImportance(PKG_N_MR1, uid) != IMPORTANCE_NONE); NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW); channel2.setBypassDnd(true); mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true); @@ -2052,8 +2047,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testCreateAndUpdateChannelsBypassingDnd_permissionHelper() { int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; - - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); when(mPermissionHelper.hasPermission(uid)).thenReturn(true); // create notification channel that can't bypass dnd @@ -2076,10 +2069,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testCreateAndDeleteCanChannelsBypassDnd_permissionHelper() throws Exception { + public void testCreateAndDeleteCanChannelsBypassDnd_permissionHelper() { int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; - - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); when(mPermissionHelper.hasPermission(uid)).thenReturn(true); // create notification channel that can't bypass dnd @@ -2113,8 +2104,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testBlockedGroupDoesNotBypassDnd() throws Exception { + public void testBlockedGroupDoesNotBypassDnd() { int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; + when(mPermissionHelper.hasPermission(uid)).thenReturn(true); // start in a 'allowed to bypass dnd state' mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, @@ -2140,8 +2132,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testBlockedAppsDoNotBypassDnd_localSettings() throws Exception { + public void testBlockedAppsDoNotBypassDnd_localSettings() { int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; + when(mPermissionHelper.hasPermission(uid)).thenReturn(false); // start in a 'allowed to bypass dnd state' mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, @@ -2151,7 +2144,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); - mHelper.setImportance(PKG_N_MR1, uid, IMPORTANCE_NONE); // create notification channel that can bypass dnd, but app is blocked // expected result: areChannelsBypassingDnd = false NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW); @@ -2163,10 +2155,10 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testBlockedAppsDoNotBypassDnd_permissionHelper() throws Exception { + public void testBlockedAppsDoNotBypassDnd_permissionHelper() { int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); when(mPermissionHelper.hasPermission(uid)).thenReturn(false); + // start in a 'allowed to bypass dnd state' mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0); @@ -2186,8 +2178,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testUpdateCanChannelsBypassDnd() throws Exception { + public void testUpdateCanChannelsBypassDnd() { int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; + when(mPermissionHelper.hasPermission(uid)).thenReturn(true); // create notification channel that can't bypass dnd // expected result: areChannelsBypassingDnd = false @@ -2405,8 +2398,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy); // create records with the default channel for all user 0 and user 1 uids - mHelper.getImportance(PKG_N_MR1, user0Uids[i]); - mHelper.getImportance(PKG_N_MR1, user1Uids[i]); + mHelper.canShowBadge(PKG_N_MR1, user0Uids[i]); + mHelper.canShowBadge(PKG_N_MR1, user1Uids[i]); } mHelper.onUserRemoved(1); @@ -2445,17 +2438,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testOnPackageChanged_packageRemoval_importance() throws Exception { - mHelper.setImportance(PKG_N_MR1, UID_N_MR1, NotificationManager.IMPORTANCE_HIGH); - - mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{ - UID_N_MR1}); - - assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1, - UID_N_MR1)); - } - - @Test public void testOnPackageChanged_packageRemoval_groups() throws Exception { NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1"); mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true); @@ -2496,17 +2478,14 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false); mHelper.createNotificationChannelGroup( PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true); - mHelper.lockChannelsForOEM(pkg.toArray(new String[]{})); mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair); mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1); - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE); mHelper.setBubblesAllowed(PKG_O, UID_O, DEFAULT_BUBBLE_PREFERENCE); mHelper.setShowBadge(PKG_O, UID_O, false); mHelper.setAppImportanceLocked(PKG_O, UID_O); mHelper.clearData(PKG_O, UID_O); - assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O, UID_O)); assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), DEFAULT_BUBBLE_PREFERENCE); assertTrue(mHelper.canShowBadge(PKG_O, UID_O)); assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O)); @@ -2518,13 +2497,10 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false); assertTrue(channel.isImportanceLockedByCriticalDeviceFunction()); - assertTrue(channel.isImportanceLockedByOEM()); } @Test public void testRecordDefaults() throws Exception { - assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1, - UID_N_MR1)); assertEquals(true, mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1)); assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size()); } @@ -2760,69 +2736,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testDumpJson_prePermissionMigration() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(false); - // before the migration is active, we want to verify that: - // - all notification importance info should come from package preferences - // - if there are permissions granted or denied from packages PreferencesHelper doesn't - // know about, those are ignored if migration is not enabled - - // package permissions map to be passed in - ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); - appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs - appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs - appPermissions.put(new Pair(UID_P, PKG_P), new Pair(true, false)); // in local prefs - appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs - - NotificationChannel channel1 = - new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH); - NotificationChannel channel3 = new NotificationChannel("id3", "name3", IMPORTANCE_HIGH); - - mHelper.createNotificationChannel(PKG_P, UID_P, channel1, true, false); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_LOW); - mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false); - mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE); - mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false); - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - - // in the json array, all of the individual package preferences are simply elements in the - // values array. this set is to collect expected outputs for each of our packages. - // the key/value pairs are: (userId, package name) -> expected importance - ArrayMap<Pair<Integer, String>, String> expected = new ArrayMap<>(); - expected.put(new Pair(UserHandle.getUserId(UID_P), PKG_P), "LOW"); - expected.put(new Pair(UserHandle.getUserId(UID_O), PKG_O), "HIGH"); - expected.put(new Pair(UserHandle.getUserId(UID_N_MR1), PKG_N_MR1), "NONE"); - - JSONArray actual = (JSONArray) mHelper.dumpJson( - new NotificationManagerService.DumpFilter(), appPermissions) - .get("PackagePreferencess"); - assertThat(actual.length()).isEqualTo(expected.size()); - for (int i = 0; i < actual.length(); i++) { - JSONObject pkgInfo = actual.getJSONObject(i); - Pair<Integer, String> pkgKey = - new Pair(pkgInfo.getInt("userId"), pkgInfo.getString("packageName")); - assertTrue(expected.containsKey(pkgKey)); - assertThat(pkgInfo.getString("importance")).isEqualTo(expected.get(pkgKey)); - } - - // also make sure that (more likely to actually happen) if we don't provide an array of - // app preferences (and do null instead), the same thing happens, so do the same checks - JSONArray actualWithNullInput = (JSONArray) mHelper.dumpJson( - new NotificationManagerService.DumpFilter(), null) - .get("PackagePreferencess"); - assertThat(actualWithNullInput.length()).isEqualTo(expected.size()); - for (int i = 0; i < actualWithNullInput.length(); i++) { - JSONObject pkgInfo = actualWithNullInput.getJSONObject(i); - Pair<Integer, String> pkgKey = - new Pair(pkgInfo.getInt("userId"), pkgInfo.getString("packageName")); - assertTrue(expected.containsKey(pkgKey)); - assertThat(pkgInfo.getString("importance")).isEqualTo(expected.get(pkgKey)); - } - } - - @Test public void testDumpJson_postPermissionMigration() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); // when getting a json dump, we want to verify that: // - all notification importance info should come from the permission, even if the data // isn't there yet but is present in package preferences @@ -2844,11 +2758,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.createNotificationChannel(PKG_P, UID_P, channel1, true, false); mHelper.createNotificationChannel(PKG_P, UID_P, channel2, false, false); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_LOW); mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false); - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); // in the json array, all of the individual package preferences are simply elements in the // values array. this set is to collect expected outputs for each of our packages. @@ -2887,11 +2798,10 @@ public class PreferencesHelperTest extends UiServiceTestCase { public void testDumpJson_givenNullInput_postMigration() throws Exception { // simple test just to make sure nothing dies if we pass in null input even post migration // for some reason, even though in practice this should not be how one calls this method - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); - // some packages exist, with some importance info that won't be looked at - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); + // some packages exist + mHelper.canShowBadge(PKG_O, UID_O); + mHelper.canShowBadge(PKG_P, UID_P); JSONArray actual = (JSONArray) mHelper.dumpJson( new NotificationManagerService.DumpFilter(), null) @@ -2908,44 +2818,16 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testDumpBansJson_prePermissionMigration() throws Exception { - // confirm that the package bans that are in json are only from package preferences, and - // not from the passed-in permissions map - when(mPermissionHelper.isMigrationEnabled()).thenReturn(false); - - ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); - appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs - appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs - appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs - - // package preferences: only PKG_P is banned - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); - - // make sure that's the only thing in the package ban output - JSONArray actual = mHelper.dumpBansJson( - new NotificationManagerService.DumpFilter(), appPermissions); - assertThat(actual.length()).isEqualTo(1); - - JSONObject ban = actual.getJSONObject(0); - assertThat(ban.getInt("userId")).isEqualTo(UserHandle.getUserId(UID_P)); - assertThat(ban.getString("packageName")).isEqualTo(PKG_P); - } - - @Test public void testDumpBansJson_postPermissionMigration() throws Exception { // confirm that the package bans that are in the output include all packages that // have their permission set to false, and not based on PackagePreferences importance - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs - // package preferences: PKG_O not banned based on local importance, and PKG_P is - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); + mHelper.canShowBadge(PKG_O, UID_O); // expected output ArraySet<Pair<Integer, String>> expected = new ArraySet<>(); @@ -2967,10 +2849,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testDumpBansJson_givenNullInput() throws Exception { // no one should do this, but... - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); - - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); JSONArray actual = mHelper.dumpBansJson( new NotificationManagerService.DumpFilter(), null); @@ -2978,59 +2856,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testDumpString_prePermissionMigration() { - // confirm that the string resulting from dumpImpl contains only info from package prefs - when(mPermissionHelper.isMigrationEnabled()).thenReturn(false); - - ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); - appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs - appPermissions.put(new Pair(3, "third"), new Pair(false, true)); // not in local prefs - appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs - - // local package preferences: PKG_O is not banned even though the permissions would - // indicate so - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); - - // get dump output as a string so we can inspect the contents later - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - mHelper.dump(pw, "", new NotificationManagerService.DumpFilter(), appPermissions); - pw.flush(); - String actual = sw.toString(); - - // expected (substring) output for each preference - ArrayList<String> expected = new ArrayList<>(); - expected.add(PKG_O + " (" + UID_O + ") importance=HIGH"); - expected.add(PKG_P + " (" + UID_P + ") importance=NONE"); - - // make sure the things in app permissions do NOT show up - ArrayList<String> notExpected = new ArrayList<>(); - notExpected.add("first (1) importance=DEFAULT"); - notExpected.add("third (3) importance=NONE"); - notExpected.add("userSet="); // no user-set information pre migration - - for (String exp : expected) { - assertTrue(actual.contains(exp)); - } - - for (String notExp : notExpected) { - assertFalse(actual.contains(notExp)); - } - - // also make sure it works the same if we pass in a null input - StringWriter sw2 = new StringWriter(); - PrintWriter pw2 = new PrintWriter(sw2); - mHelper.dump(pw2, "", new NotificationManagerService.DumpFilter(), null); - pw.flush(); - String actualWithNullInput = sw2.toString(); - assertThat(actualWithNullInput).isEqualTo(actual); - } - - @Test public void testDumpString_postPermissionMigration() { // confirm that the string resulting from dumpImpl contains only importances from permission - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs @@ -3038,8 +2865,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs // local package preferences - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); + mHelper.canShowBadge(PKG_O, UID_O); + mHelper.canShowBadge(PKG_P, UID_P); // get dump output as a string so we can inspect the contents later StringWriter sw = new StringWriter(); @@ -3072,11 +2899,10 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testDumpString_givenNullInput() { // test that this doesn't choke on null input - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); // local package preferences - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); + mHelper.canShowBadge(PKG_O, UID_O); + mHelper.canShowBadge(PKG_P, UID_P); // get dump output StringWriter sw = new StringWriter(); @@ -3090,48 +2916,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testDumpProto_prePermissionMigration() throws Exception { - // test that dumping to proto gets the importances from the right place - when(mPermissionHelper.isMigrationEnabled()).thenReturn(false); - - ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); - appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs - appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs - appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs - - // local package preferences - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); - - // expected output: only the local preferences - // map format: (uid, package name) -> importance (int) - ArrayMap<Pair<Integer, String>, Integer> expected = new ArrayMap<>(); - expected.put(new Pair(UID_O, PKG_O), IMPORTANCE_HIGH); - expected.put(new Pair(UID_P, PKG_P), IMPORTANCE_NONE); - - // get the proto output and inspect its contents - ProtoOutputStream proto = new ProtoOutputStream(); - mHelper.dump(proto, new NotificationManagerService.DumpFilter(), appPermissions); - - RankingHelperProto actual = RankingHelperProto.parseFrom(proto.getBytes()); - assertThat(actual.records.length).isEqualTo(expected.size()); - for (int i = 0; i < actual.records.length; i++) { - RankingHelperProto.RecordProto record = actual.records[i]; - Pair<Integer, String> pkgKey = new Pair(record.uid, record.package_); - assertTrue(expected.containsKey(pkgKey)); - assertThat(record.importance).isEqualTo(expected.get(pkgKey)); - } - - // also check that it's the same as passing in null input - ProtoOutputStream proto2 = new ProtoOutputStream(); - mHelper.dump(proto2, new NotificationManagerService.DumpFilter(), null); - assertThat(proto.getBytes()).isEqualTo(proto2.getBytes()); - } - - @Test public void testDumpProto_postPermissionMigration() throws Exception { // test that dumping to proto gets the importances from the right place - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); // permissions -- these should take precedence ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); @@ -3140,8 +2926,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs // local package preferences - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_LOW); + mHelper.canShowBadge(PKG_O, UID_O); + mHelper.canShowBadge(PKG_P, UID_P); // expected output: all the packages, but only the ones provided via appPermissions // should have importance set (aka not PKG_P) @@ -3429,14 +3215,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testAppBlockedLogging() { - mHelper.setEnabled(PKG_N_MR1, 1020, false); - assertEquals(1, mLogger.getCalls().size()); - assertEquals( - NotificationChannelLogger.NotificationChannelEvent.APP_NOTIFICATIONS_BLOCKED, - mLogger.get(0).event); - } - @Test public void testXml_statusBarIcons_default() throws Exception { String preQXml = "<ranking version=\"1\">\n" + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n" @@ -3517,7 +3295,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testIsDelegateAllowed_noDelegate() { - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED); + mHelper.canShowBadge(PKG_O, UID_O); assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "whatever", 0)); } @@ -3555,7 +3333,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testDelegateXml_noDelegate() throws Exception { - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED); + mHelper.canShowBadge(PKG_O, UID_O); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, @@ -3744,337 +3522,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testLockChannelsForOEM_emptyList() { - mHelper.lockChannelsForOEM(null); - mHelper.lockChannelsForOEM(new String[0]); - // no exception - } - - @Test - public void testLockChannelsForOEM_appWide() { - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); - NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT); - // different uids, same package - mHelper.createNotificationChannel(PKG_O, 3, a, true, false); - mHelper.createNotificationChannel(PKG_O, 3, b, false, false); - mHelper.createNotificationChannel(PKG_O, 30, c, true, true); - - mHelper.lockChannelsForOEM(new String[] {PKG_O}); - - assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false) - .isImportanceLockedByOEM()); - assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false) - .isImportanceLockedByOEM()); - assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_onlyGivenPkg() { - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); - mHelper.createNotificationChannel(PKG_O, 3, a, true, false); - mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false); - - mHelper.lockChannelsForOEM(new String[] {PKG_O}); - - assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false) - .isImportanceLockedByOEM()); - assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelSpecific() { - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); - NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT); - // different uids, same package - mHelper.createNotificationChannel(PKG_O, 3, a, true, false); - mHelper.createNotificationChannel(PKG_O, 3, b, false, false); - mHelper.createNotificationChannel(PKG_O, 30, c, true, true); - - mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"}); - - assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false) - .isImportanceLockedByOEM()); - assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false) - .isImportanceLockedByOEM()); - assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet() { - mHelper.lockChannelsForOEM(new String[] {PKG_O}); - - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); - mHelper.createNotificationChannel(PKG_O, 3, a, true, false); - mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false); - - assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false) - .isImportanceLockedByOEM()); - assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet() { - mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"}); - - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); - NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT); - // different uids, same package - mHelper.createNotificationChannel(PKG_O, 3, a, true, false); - mHelper.createNotificationChannel(PKG_O, 3, b, false, false); - mHelper.createNotificationChannel(PKG_O, 30, c, true, true); - - assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false) - .isImportanceLockedByOEM()); - assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false) - .isImportanceLockedByOEM()); - assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet_restoreData() - throws Exception { - mHelper.lockChannelsForOEM(new String[] {PKG_O}); - - final String xml = "<ranking version=\"1\">\n" - + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n" - + "<channel id=\"a\" name=\"a\" importance=\"3\"/>" - + "<channel id=\"b\" name=\"b\" importance=\"3\"/>" - + "</package>" - + "<package name=\"" + PKG_N_MR1 + "\" uid=\"" + UID_N_MR1 + "\" >\n" - + "<channel id=\"a\" name=\"a\" importance=\"3\"/>" - + "<channel id=\"b\" name=\"b\" importance=\"3\"/>" - + "</package>" - + "</ranking>"; - TypedXmlPullParser parser = Xml.newFastPullParser(); - parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), - null); - parser.nextTag(); - mHelper.readXml(parser, false, UserHandle.USER_ALL); - - assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, "a", false) - .isImportanceLockedByOEM()); - assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "b", false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet_restoreData_postMigration() - throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); - mHelper.lockChannelsForOEM(new String[] {PKG_O}); - - final String xml = "<ranking version=\"1\">\n" - + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n" - + "<channel id=\"a\" name=\"a\" importance=\"3\"/>" - + "<channel id=\"b\" name=\"b\" importance=\"3\"/>" - + "</package>" - + "</ranking>"; - TypedXmlPullParser parser = Xml.newFastPullParser(); - parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), - null); - parser.nextTag(); - mHelper.readXml(parser, false, UserHandle.USER_ALL); - - assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, "a", false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet_restoreData() - throws Exception { - mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"}); - - final String xml = "<ranking version=\"1\">\n" - + "<package name=\"" + PKG_O + "\" uid=\"" + 3 + "\" >\n" - + "<channel id=\"a\" name=\"a\" importance=\"3\"/>" - + "<channel id=\"b\" name=\"b\" importance=\"3\"/>" - + "</package>" - + "<package name=\"" + PKG_O + "\" uid=\"" + 30 + "\" >\n" - + "<channel id=\"c\" name=\"c\" importance=\"3\"/>" - + "</package>" - + "</ranking>"; - TypedXmlPullParser parser = Xml.newFastPullParser(); - parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), - null); - parser.nextTag(); - mHelper.readXml(parser, false, UserHandle.USER_ALL); - - assertFalse(mHelper.getNotificationChannel(PKG_O, 3, "a", false) - .isImportanceLockedByOEM()); - assertTrue(mHelper.getNotificationChannel(PKG_O, 3, "b", false) - .isImportanceLockedByOEM()); - assertTrue(mHelper.getNotificationChannel(PKG_O, 30, "c", false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet_restoreData_postMigration() - throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); - mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"}); - - final String xml = "<ranking version=\"1\">\n" - + "<package name=\"" + PKG_O + "\" uid=\"" + 3 + "\" >\n" - + "<channel id=\"a\" name=\"a\" importance=\"3\"/>" - + "<channel id=\"b\" name=\"b\" importance=\"3\"/>" - + "</package>" - + "<package name=\"" + PKG_O + "\" uid=\"" + 30 + "\" >\n" - + "<channel id=\"c\" name=\"c\" importance=\"3\"/>" - + "</package>" - + "</ranking>"; - TypedXmlPullParser parser = Xml.newFastPullParser(); - parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), - null); - parser.nextTag(); - mHelper.readXml(parser, false, UserHandle.USER_ALL); - - assertFalse(mHelper.getNotificationChannel(PKG_O, 3, "a", false) - .isImportanceLockedByOEM()); - assertFalse(mHelper.getNotificationChannel(PKG_O, 3, "b", false) - .isImportanceLockedByOEM()); - assertFalse(mHelper.getNotificationChannel(PKG_O, 30, "c", false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelSpecific_clearData() { - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - mHelper.getImportance(PKG_O, UID_O); - mHelper.lockChannelsForOEM(new String[] {PKG_O + ":" + a.getId()}); - mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); - assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) - .isImportanceLockedByOEM()); - - mHelper.clearData(PKG_O, UID_O); - - // it's back! - mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); - // and still locked - assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelDoesNotExistYet_appWide() { - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); - mHelper.createNotificationChannel(PKG_O, 3, a, true, false); - - mHelper.lockChannelsForOEM(new String[] {PKG_O}); - - assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false) - .isImportanceLockedByOEM()); - - mHelper.createNotificationChannel(PKG_O, 3, b, true, false); - assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific() { - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); - mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); - - mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"}); - - assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) - .isImportanceLockedByOEM()); - - mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false); - assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelSpecific_clearData_postMigration() { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - mHelper.getImportance(PKG_O, UID_O); - mHelper.lockChannelsForOEM(new String[] {PKG_O + ":" + a.getId()}); - mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); - assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) - .isImportanceLockedByOEM()); - - mHelper.clearData(PKG_O, UID_O); - - // it's back! - mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); - // and never locked - assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelDoesNotExistYet_appWide_postMigration() { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); - mHelper.createNotificationChannel(PKG_O, 3, a, true, false); - - mHelper.lockChannelsForOEM(new String[] {PKG_O}); - - assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false) - .isImportanceLockedByOEM()); - - mHelper.createNotificationChannel(PKG_O, 3, b, true, false); - assertFalse(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific_postMigration() { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); - mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); - - mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"}); - - assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) - .isImportanceLockedByOEM()); - - mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false); - assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false) - .isImportanceLockedByOEM()); - } - - @Test - public void testUpdateNotificationChannel_oemLockedImportance() { - NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); - mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); - - mHelper.lockChannelsForOEM(new String[] {PKG_O}); - - NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE); - update.setAllowBubbles(false); - - mHelper.updateNotificationChannel(PKG_O, UID_O, update, true); - - assertEquals(IMPORTANCE_HIGH, - mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance()); - assertEquals(false, - mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble()); - - mHelper.updateNotificationChannel(PKG_O, UID_O, update, true); - - assertEquals(IMPORTANCE_HIGH, - mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance()); - } - - @Test public void testUpdateNotificationChannel_fixedPermission() { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true); NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); @@ -4093,7 +3541,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testUpdateNotificationChannel_fixedPermission_butUserPreviouslyBlockedIt() { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true); NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_NONE); @@ -4112,7 +3559,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testUpdateNotificationChannel_fixedPermission_butAppAllowsIt() { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true); NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); @@ -4132,7 +3578,6 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testUpdateNotificationChannel_notFixedPermission() { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(false); NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); @@ -5312,56 +4757,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testPullPackagePreferencesStats_prePermissionMigration() { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(false); - - // build a collection of app permissions that should be passed in but ignored - ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); - appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs - appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs - appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs - - // package preferences: PKG_O not banned based on local importance, and PKG_P is - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); - - // expected output. format: uid -> importance, as only uid (and not package name) - // is in PackageNotificationPreferences - ArrayMap<Integer, Integer> expected = new ArrayMap<>(); - expected.put(UID_O, IMPORTANCE_HIGH); - expected.put(UID_P, IMPORTANCE_NONE); - - // unexpected output. these UIDs should not show up in the output at all - ArraySet<Integer> unexpected = new ArraySet<>(); - unexpected.add(1); - unexpected.add(3); - - ArrayList<StatsEvent> events = new ArrayList<>(); - mHelper.pullPackagePreferencesStats(events, appPermissions); - - for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) { - if (builder.getAtomId() == PACKAGE_NOTIFICATION_PREFERENCES) { - int uid = builder.getInt(PackageNotificationPreferences.UID_FIELD_NUMBER); - - // this shouldn't be any of the forbidden uids - assertFalse(unexpected.contains(uid)); - - // if it's one of the expected ids, then make sure the importance matches - assertTrue(expected.containsKey(uid)); - assertThat(expected.get(uid)).isEqualTo( - builder.getInt(PackageNotificationPreferences.IMPORTANCE_FIELD_NUMBER)); - - // pre-migration, the userSet field will always default to false - boolean userSet = builder.getBoolean( - PackageNotificationPreferences.USER_SET_IMPORTANCE_FIELD_NUMBER); - assertFalse(userSet); - } - } - } - - @Test public void testPullPackagePreferencesStats_postPermissionMigration() { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); // build a collection of app permissions that should be passed in but ignored ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>(); @@ -5369,9 +4765,9 @@ public class PreferencesHelperTest extends UiServiceTestCase { appPermissions.put(new Pair(3, "third"), new Pair(false, true)); // not in local prefs appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, true)); // in local prefs - // package preferences: PKG_O not banned based on local importance, and PKG_P is - mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH); - mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE); + // local preferences + mHelper.canShowBadge(PKG_O, UID_O); + mHelper.canShowBadge(PKG_P, UID_P); // expected output. format: uid -> importance, as only uid (and not package name) // is in PackageNotificationPreferences @@ -5433,27 +4829,4 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertTrue((channelB.getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0); assertTrue((channelC.getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0); } - - @Test - public void testDefaultChannelUpdatesApp_preMigrationToPermissions() throws Exception { - final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1, - UID_N_MR1, - NotificationChannel.DEFAULT_CHANNEL_ID, false); - defaultChannel.setImportance(IMPORTANCE_NONE); - mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true); - - assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_N_MR1, UID_N_MR1)); - } - - @Test - public void testDefaultChannelDoesNotUpdateApp_postMigrationToPermissions() throws Exception { - when(mPermissionHelper.isMigrationEnabled()).thenReturn(true); - final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1, - UID_N_MR1, - NotificationChannel.DEFAULT_CHANNEL_ID, false); - defaultChannel.setImportance(IMPORTANCE_NONE); - mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true); - - assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1, UID_N_MR1)); - } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java index 0bfd2020622f..98c156e6f3b5 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java @@ -168,7 +168,8 @@ public class RoleObserverTest extends UiServiceTestCase { mock(StatsManager.class), mock(TelephonyManager.class), mock(ActivityManagerInternal.class), mock(MultiRateLimiter.class), mock(PermissionHelper.class), - mock(UsageStatsManagerInternal.class), mock (TelecomManager.class)); + mock(UsageStatsManagerInternal.class), mock (TelecomManager.class), + mock(NotificationChannelLogger.class)); } catch (SecurityException e) { if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { throw e; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 533540e2568d..a34896a419ed 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -611,10 +611,9 @@ public class ActivityRecordTests extends WindowTestsBase { activity.setRequestedOrientation(activityCurOrientation == ORIENTATION_LANDSCAPE ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE); - // Asserts fixed orientation request is ignored, and the orientation is not changed - // (fill Task). - assertEquals(activityCurOrientation, activity.getConfiguration().orientation); - assertFalse(activity.isLetterboxedForFixedOrientationAndAspectRatio()); + // Asserts fixed orientation request is not ignored, and the orientation is changed. + assertNotEquals(activityCurOrientation, activity.getConfiguration().orientation); + assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio()); } @Test @@ -2854,6 +2853,11 @@ public class ActivityRecordTests extends WindowTestsBase { assertTrue(activity2.isResizeable()); activity1.reparent(taskFragment1, POSITION_TOP); + // Adds an Activity which doesn't have shared starting data, and verify if it blocks + // starting window removal. + final ActivityRecord activity3 = new ActivityBuilder(mAtm).build(); + taskFragment2.addChild(activity3, POSITION_TOP); + verify(activity1.getSyncTransaction()).reparent(eq(startingWindow.mSurfaceControl), eq(task.mSurfaceControl)); assertEquals(activity1.mStartingData, startingWindow.mStartingData); diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java index 1e86522a2307..e502f2fbd173 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java @@ -63,7 +63,7 @@ public class LetterboxTest { mLetterbox = new Letterbox(mSurfaces, StubTransaction::new, () -> mAreCornersRounded, () -> Color.valueOf(mColor), () -> mHasWallpaperBackground, () -> mBlurRadius, () -> mDarkScrimAlpha, - /* doubleTapCallback= */ x -> {}); + /* doubleTapCallbackX= */ x -> {}, /* doubleTapCallbackY= */ y -> {}); mTransaction = spy(StubTransaction.class); } diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 76fb7ff2e6f8..9dc51976d22f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -1876,6 +1876,28 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + public void testResizableFixedOrientationAppInSplitScreen_letterboxForDifferentOrientation() { + setUpDisplaySizeWithApp(1000, 2800); + final TestSplitOrganizer organizer = + new TestSplitOrganizer(mAtm, mActivity.getDisplayContent()); + + // Resizable landscape-only activity. + prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_LANDSCAPE, /* isUnresizable= */ false); + + final Rect originalBounds = new Rect(mActivity.getBounds()); + + // Move activity to split screen which takes half of the screen. + mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test"); + organizer.mPrimary.setBounds(0, 0, 1000, 1400); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode()); + assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode()); + + // Resizable activity is not in size compat mode but in the letterbox for fixed orientation. + assertFitted(); + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + } + + @Test public void testSupportsNonResizableInSplitScreen_fillTaskForSameOrientation() { // Support non resizable in multi window mAtm.mDevEnableNonResizableMultiWindow = true; @@ -1928,7 +1950,7 @@ public class SizeCompatTests extends WindowTestsBase { prepareUnresizable(mActivity, /* maxAspect */ 1.1f, SCREEN_ORIENTATION_UNSPECIFIED); // Bounds are letterboxed to respect the provided max aspect ratio. - assertEquals(mActivity.getBounds(), new Rect(0, 0, 1000, 1100)); + assertEquals(mActivity.getBounds(), new Rect(0, 850, 1000, 1950)); // Move activity to split screen which has landscape size. mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents */ false, "test"); @@ -2045,19 +2067,14 @@ public class SizeCompatTests extends WindowTestsBase { mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier( letterboxHorizontalPositionMultiplier); prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); - assertEquals(fixedOrientationLetterbox, mActivity.getBounds()); - // Rotate to put activity in size compat mode. rotateDisplay(mActivity.mDisplayContent, ROTATION_90); - assertTrue(mActivity.inSizeCompatMode()); // Activity is in size compat mode but not scaled. assertEquals(sizeCompatUnscaled, mActivity.getBounds()); - // Force activity to scaled down for size compat mode. resizeDisplay(mTask.mDisplayContent, 700, 1400); - assertTrue(mActivity.inSizeCompatMode()); assertScaled(); assertEquals(sizeCompatScaled, mActivity.getBounds()); @@ -2075,6 +2092,109 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + public void testUpdateResolvedBoundsVerticalPosition_top() { + // Display configured as (1400, 2800). + assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity( + /* letterboxVerticalPositionMultiplier */ 0.0f, + // At launch. + /* fixedOrientationLetterbox */ new Rect(0, 0, 1400, 700), + // After 90 degree rotation. + /* sizeCompatUnscaled */ new Rect(700, 0, 2100, 700), + // After the display is resized to (1400, 700). + /* sizeCompatScaled */ new Rect(0, 0, 700, 350)); + } + + @Test + public void testUpdateResolvedBoundsVerticalPosition_center() { + // Display configured as (1400, 2800). + assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity( + /* letterboxVerticalPositionMultiplier */ 0.5f, + // At launch. + /* fixedOrientationLetterbox */ new Rect(0, 1050, 1400, 1750), + // After 90 degree rotation. + /* sizeCompatUnscaled */ new Rect(700, 350, 2100, 1050), + // After the display is resized to (1400, 700). + /* sizeCompatScaled */ new Rect(0, 525, 700, 875)); + } + + @Test + public void testUpdateResolvedBoundsVerticalPosition_invalidMultiplier_defaultToCenter() { + // Display configured as (1400, 2800). + + // Below 0.0. + assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity( + /* letterboxVerticalPositionMultiplier */ -1.0f, + // At launch. + /* fixedOrientationLetterbox */ new Rect(0, 1050, 1400, 1750), + // After 90 degree rotation. + /* sizeCompatUnscaled */ new Rect(700, 350, 2100, 1050), + // After the display is resized to (1400, 700). + /* sizeCompatScaled */ new Rect(0, 525, 700, 875)); + + // Above 1.0 + assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity( + /* letterboxVerticalPositionMultiplier */ 2.0f, + // At launch. + /* fixedOrientationLetterbox */ new Rect(0, 1050, 1400, 1750), + // After 90 degree rotation. + /* sizeCompatUnscaled */ new Rect(700, 350, 2100, 1050), + // After the display is resized to (1400, 700). + /* sizeCompatScaled */ new Rect(0, 525, 700, 875)); + } + + @Test + public void testUpdateResolvedBoundsVerticalPosition_bottom() { + // Display configured as (1400, 2800). + assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity( + /* letterboxVerticalPositionMultiplier */ 1.0f, + // At launch. + /* fixedOrientationLetterbox */ new Rect(0, 2100, 1400, 2800), + // After 90 degree rotation. + /* sizeCompatUnscaled */ new Rect(700, 700, 2100, 1400), + // After the display is resized to (1400, 700). + /* sizeCompatScaled */ new Rect(0, 1050, 700, 1400)); + } + + private void assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity( + float letterboxVerticalPositionMultiplier, Rect fixedOrientationLetterbox, + Rect sizeCompatUnscaled, Rect sizeCompatScaled) { + // Set up a display in portrait and ignoring orientation request. + setUpDisplaySizeWithApp(1400, 2800); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + + mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier( + letterboxVerticalPositionMultiplier); + prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); + + assertEquals(fixedOrientationLetterbox, mActivity.getBounds()); + + // Rotate to put activity in size compat mode. + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + + assertTrue(mActivity.inSizeCompatMode()); + // Activity is in size compat mode but not scaled. + assertEquals(sizeCompatUnscaled, mActivity.getBounds()); + + // Force activity to scaled down for size compat mode. + resizeDisplay(mTask.mDisplayContent, 1400, 700); + + assertTrue(mActivity.inSizeCompatMode()); + assertScaled(); + assertEquals(sizeCompatScaled, mActivity.getBounds()); + } + + @Test + public void testUpdateResolvedBoundsVerticalPosition_activityFillParentHeight() { + // When activity height equals parent height, multiplier shouldn't have any effect. + assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity( + /* letterboxVerticalPositionMultiplier */ 0.0f); + assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity( + /* letterboxVerticalPositionMultiplier */ 0.5f); + assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity( + /* letterboxVerticalPositionMultiplier */ 1.0f); + } + + @Test public void testAreBoundsLetterboxed_letterboxedForAspectRatio_returnsTrue() { setUpDisplaySizeWithApp(1000, 2500); @@ -2367,6 +2487,23 @@ public class SizeCompatTests extends WindowTestsBase { mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier( letterboxHorizontalPositionMultiplier); prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); + assertFitted(); + // Rotate to put activity in size compat mode. + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + assertTrue(mActivity.inSizeCompatMode()); + // Activity is in size compat mode but not scaled. + assertEquals(new Rect(0, 1050, 1400, 1750), mActivity.getBounds()); + } + + private void assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity( + float letterboxVerticalPositionMultiplier) { + // Set up a display in portrait and ignoring orientation request. + setUpDisplaySizeWithApp(1400, 2800); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + + mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier( + letterboxVerticalPositionMultiplier); + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); assertFitted(); @@ -2375,7 +2512,7 @@ public class SizeCompatTests extends WindowTestsBase { assertTrue(mActivity.inSizeCompatMode()); // Activity is in size compat mode but not scaled. - assertEquals(new Rect(0, 1050, 1400, 1750), mActivity.getBounds()); + assertEquals(new Rect(1050, 0, 1750, 1400), mActivity.getBounds()); } private static WindowState addWindowToActivity(ActivityRecord activity) { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 9957d05d0a52..e138d52b8ef6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -229,14 +229,22 @@ class WindowTestsBase extends SystemServiceTestsBase { // {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set // on some device form factors. mAtm.mWindowManager.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(0); - // Ensure letterbox position multiplier is not overridden on any device target. + // Ensure letterbox horizontal position multiplier is not overridden on any device target. // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}, // may be set on some device form factors. mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f); - // Ensure letterbox reachability treatment isn't overridden on any device target. - // {@link com.android.internal.R.bool.config_letterboxIsReachabilityEnabled}, + // Ensure letterbox vertical position multiplier is not overridden on any device target. + // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}, + // may be set on some device form factors. + mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f); + // Ensure letterbox horizontal reachability treatment isn't overridden on any device target. + // {@link com.android.internal.R.bool.config_letterboxIsHorizontalReachabilityEnabled}, + // may be set on some device form factors. + mAtm.mWindowManager.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(false); + // Ensure letterbox vertical reachability treatment isn't overridden on any device target. + // {@link com.android.internal.R.bool.config_letterboxIsVerticalReachabilityEnabled}, // may be set on some device form factors. - mAtm.mWindowManager.mLetterboxConfiguration.setIsReachabilityEnabled(false); + mAtm.mWindowManager.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(false); checkDeviceSpecificOverridesNotApplied(); } @@ -246,7 +254,8 @@ class WindowTestsBase extends SystemServiceTestsBase { // Revert back to device overrides. mAtm.mWindowManager.mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio(); mAtm.mWindowManager.mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier(); - mAtm.mWindowManager.mLetterboxConfiguration.resetIsReachabilityEnabled(); + mAtm.mWindowManager.mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled(); + mAtm.mWindowManager.mLetterboxConfiguration.resetIsVerticalReachabilityEnabled(); } /** diff --git a/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java b/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java index 177e819878c7..2893f807c8a8 100644 --- a/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java +++ b/services/usb/java/com/android/server/usb/UsbDirectMidiDevice.java @@ -23,6 +23,7 @@ import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbManager; +import android.hardware.usb.UsbRequest; import android.media.midi.MidiDeviceInfo; import android.media.midi.MidiDeviceServer; import android.media.midi.MidiDeviceStatus; @@ -44,6 +45,7 @@ import libcore.io.IoUtils; import java.io.Closeable; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.ArrayList; /** @@ -73,10 +75,10 @@ public final class UsbDirectMidiDevice implements Closeable { // event schedulers for each input port of the physical device private MidiEventScheduler[] mEventSchedulers; - // Arbitrary number for timeout to not continue sending/receiving number from - // an inactive device. This number tries to balances the number of cycles and - // not being permanently stuck. - private static final int BULK_TRANSFER_TIMEOUT_MILLISECONDS = 100; + // Arbitrary number for timeout to not continue sending to + // an inactive device. This number tries to balances the number + // of cycles and not being permanently stuck. + private static final int BULK_TRANSFER_TIMEOUT_MILLISECONDS = 10; private ArrayList<UsbDeviceConnection> mUsbDeviceConnections; private ArrayList<ArrayList<UsbEndpoint>> mInputUsbEndpoints; @@ -330,48 +332,55 @@ public final class UsbDirectMidiDevice implements Closeable { new Thread("UsbDirectMidiDevice input thread " + portFinal) { @Override public void run() { - byte[] inputBuffer = new byte[endpointFinal.getMaxPacketSize()]; - Log.d(TAG, "input buffer size: " + inputBuffer.length); + final UsbRequest request = new UsbRequest(); try { + request.initialize(connectionFinal, endpointFinal); + byte[] inputBuffer = new byte[endpointFinal.getMaxPacketSize()]; while (true) { // Record time of event immediately after waking. long timestamp = System.nanoTime(); - synchronized (mLock) { - if (!mIsOpen) break; - - int nRead = connectionFinal.bulkTransfer(endpointFinal, - inputBuffer, inputBuffer.length, - BULK_TRANSFER_TIMEOUT_MILLISECONDS); - - if (nRead > 0) { - if (DEBUG) { - logByteArray("Input before conversion ", inputBuffer, - 0, nRead); - } - byte[] convertedArray; - if (mIsUniversalMidiDevice) { - // For USB, each 32 bit word of a UMP is - // sent with the least significant byte first. - convertedArray = swapEndiannessPerWord(inputBuffer, - nRead); - } else { - convertedArray = - mUsbMidiPacketConverter.usbMidiToRawMidi( - inputBuffer, nRead); - } - - if (DEBUG) { - logByteArray("Input after conversion ", convertedArray, - 0, convertedArray.length); - } - - outputReceivers[portFinal].send(convertedArray, 0, - convertedArray.length, timestamp); + if (!mIsOpen) break; + final ByteBuffer byteBuffer = ByteBuffer.wrap(inputBuffer); + if (!request.queue(byteBuffer)) { + Log.w(TAG, "Cannot queue request"); + break; + } + final UsbRequest response = connectionFinal.requestWait(); + if (response != request) { + Log.w(TAG, "Unexpected response"); + continue; + } + int bytesRead = byteBuffer.position(); + + if (bytesRead > 0) { + if (DEBUG) { + logByteArray("Input before conversion ", inputBuffer, + 0, bytesRead); + } + byte[] convertedArray; + if (mIsUniversalMidiDevice) { + // For USB, each 32 bit word of a UMP is + // sent with the least significant byte first. + convertedArray = swapEndiannessPerWord(inputBuffer, + bytesRead); + } else { + convertedArray = + mUsbMidiPacketConverter.usbMidiToRawMidi( + inputBuffer, bytesRead); } + + if (DEBUG) { + logByteArray("Input after conversion ", convertedArray, + 0, convertedArray.length); + } + outputReceivers[portFinal].send(convertedArray, 0, + convertedArray.length, timestamp); } } } catch (IOException e) { Log.d(TAG, "reader thread exiting"); + } finally { + request.close(); } Log.d(TAG, "input thread exit"); } @@ -564,6 +573,10 @@ public final class UsbDirectMidiDevice implements Closeable { Log.e(TAG, "Usb Interface is null"); return false; } + if (connection == null) { + Log.e(TAG, "UsbDeviceConnection is null"); + return false; + } if (!connection.claimInterface(usbInterface, true)) { Log.e(TAG, "Can't claim interface"); return false; diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java index 78b0b844865d..4924a82c385f 100644 --- a/telephony/common/com/android/internal/telephony/SmsApplication.java +++ b/telephony/common/com/android/internal/telephony/SmsApplication.java @@ -68,7 +68,6 @@ import java.util.stream.Collectors; public final class SmsApplication { static final String LOG_TAG = "SmsApplication"; public static final String PHONE_PACKAGE_NAME = "com.android.phone"; - public static final String BLUETOOTH_PACKAGE_NAME = "com.android.bluetooth.services"; public static final String MMS_SERVICE_PACKAGE_NAME = "com.android.mms.service"; public static final String TELEPHONY_PROVIDER_PACKAGE_NAME = "com.android.providers.telephony"; @@ -541,11 +540,13 @@ public final class SmsApplication { PackageManager packageManager = context.getPackageManager(); AppOpsManager appOps = context.getSystemService(AppOpsManager.class); + final String bluetoothPackageName = context.getResources() + .getString(com.android.internal.R.string.config_systemBluetoothStack); // Assign permission to special system apps assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, PHONE_PACKAGE_NAME, true); assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, - BLUETOOTH_PACKAGE_NAME, true); + bluetoothPackageName, false); assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, MMS_SERVICE_PACKAGE_NAME, true); assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, @@ -1128,8 +1129,11 @@ public final class SmsApplication { return false; } final String defaultSmsPackage = getDefaultSmsApplicationPackageName(context); + final String bluetoothPackageName = context.getResources() + .getString(com.android.internal.R.string.config_systemBluetoothStack); + if ((defaultSmsPackage != null && defaultSmsPackage.equals(packageName)) - || BLUETOOTH_PACKAGE_NAME.equals(packageName)) { + || bluetoothPackageName.equals(packageName)) { return true; } return false; diff --git a/telephony/java/android/telephony/AnomalyReporter.java b/telephony/java/android/telephony/AnomalyReporter.java index f47cf3384791..e7d95e4f53b3 100644 --- a/telephony/java/android/telephony/AnomalyReporter.java +++ b/telephony/java/android/telephony/AnomalyReporter.java @@ -16,6 +16,8 @@ package android.telephony; +import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID; + import static com.android.internal.telephony.TelephonyStatsLog.TELEPHONY_ANOMALY_DETECTED; import android.annotation.NonNull; @@ -73,6 +75,7 @@ public final class AnomalyReporter { * * This method sends the {@link TelephonyManager#ACTION_ANOMALY_REPORTED} broadcast, which is * system protected. Invoking this method unless you are the system will result in an error. + * Carrier Id will be set as UNKNOWN_CARRIER_ID. * * @param eventId a fixed event ID that will be sent for each instance of the same event. This * ID should be generated randomly. @@ -81,6 +84,23 @@ public final class AnomalyReporter { * static and must not contain any sensitive information (especially PII). */ public static void reportAnomaly(@NonNull UUID eventId, String description) { + reportAnomaly(eventId, description, UNKNOWN_CARRIER_ID); + } + + /** + * If enabled, build and send an intent to a Debug Service for logging. + * + * This method sends the {@link TelephonyManager#ACTION_ANOMALY_REPORTED} broadcast, which is + * system protected. Invoking this method unless you are the system will result in an error. + * + * @param eventId a fixed event ID that will be sent for each instance of the same event. This + * ID should be generated randomly. + * @param description an optional description, that if included will be used as the subject for + * identification and discussion of this event. This description should ideally be + * static and must not contain any sensitive information (especially PII). + * @param carrierId the carrier of the id associated with this event. + */ + public static void reportAnomaly(@NonNull UUID eventId, String description, int carrierId) { if (sContext == null) { Rlog.w(TAG, "AnomalyReporter not yet initialized, dropping event=" + eventId); return; @@ -88,7 +108,7 @@ public final class AnomalyReporter { TelephonyStatsLog.write( TELEPHONY_ANOMALY_DETECTED, - 0, // TODO: carrier id needs to be populated + carrierId, eventId.getLeastSignificantBits(), eventId.getMostSignificantBits()); diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index d07d8097bce4..2337a5aae467 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -3426,10 +3426,21 @@ 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 will either have {@link android.Manifest.permission#READ_PHONE_STATE} - * permission or had carrier privilege permission on the subscription. + * Caller must have {@link android.Manifest.permission#READ_PHONE_STATE} + * or 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. diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java index 843827befb65..186241217588 100644 --- a/telephony/java/android/telephony/ims/feature/RcsFeature.java +++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java @@ -118,8 +118,10 @@ public class RcsFeature extends ImsFeature { @Override public void setCapabilityExchangeEventListener( @Nullable ICapabilityExchangeEventListener listener) throws RemoteException { - CapabilityExchangeEventListener listenerWrapper = - new CapabilityExchangeAidlWrapper(listener); + // Set the listener wrapper to null if the listener passed in is null. This will notify + // the RcsFeature to trigger the destruction of active capability exchange interface. + CapabilityExchangeEventListener listenerWrapper = listener != null + ? new CapabilityExchangeAidlWrapper(listener) : null; executeMethodAsync(() -> mReference.setCapabilityExchangeEventListener(listenerWrapper), "setCapabilityExchangeEventListener"); } diff --git a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java index 7ee19fb37244..052ce3a902c1 100644 --- a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java +++ b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java @@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNotNull; import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.ArgumentMatchers.matches; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; @@ -214,7 +215,7 @@ public class SmsApplicationTest { ApplicationInfo bluetoothApplicationInfo = new ApplicationInfo(); bluetoothApplicationInfo.uid = FAKE_BT_UID; bluetoothPackageInfo.applicationInfo = bluetoothApplicationInfo; - when(mPackageManager.getPackageInfo(eq(SmsApplication.BLUETOOTH_PACKAGE_NAME), anyInt())) + when(mPackageManager.getPackageInfo(matches(".*android.bluetooth.services"), anyInt())) .thenReturn(bluetoothPackageInfo); PackageInfo telephonyProviderPackageInfo = new PackageInfo(); |